| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556 |
- var MAKE_STORE_FUNCTION_NAME = MAKE_STORE_FUNCTION_NAME || 'makeNeuronStore'
- var DBG = DBG || false;
- var DBG1 = true;
- // var STRATEGY_OVERCHARGE = [
- // "REMOVE_CHARGE",
- // "LEAVE_HALF_CHARGE",
- // "LEAVE_ALMOST_MAX",
- // ]
- var DEFAULT_CONFIG = {
- ui_output_width: 800,
- ui_max_receptor_r: 12,
- ui_space_y: 50,
- config_anim_speed: 300,
- config_read_speed_multiplier: 4,
- config_charge_receptor_at_input: 1,
- config_max_receptor_charge: 1,
- config_max_neuron_charge: 1.5,
- config_discharge_per_tick: 0.1,
- config_discharge_max_in_new_neuron_from_one: 0.7,
- }
- var DEFAULT_NEURON = {
- value: '',
- charge: 0,
- maxCharge: DEFAULT_CONFIG.config_max_neuron_charge,
- uiShape: "circle",
- ui: { cx: 0, cy: 0 },
- source: [],
- next: [],
- }
- function makeDefaultNeuronsStoreState() {
- return {
- receptor: [],
- mapReceptorChar: {},
- neuron: [],
- connection: [],
- doubleConn: [], // connections between two nodes
- charge: [], // TODO: list of [ { charge: number, nodeType: (receptor|neuron), nodeIdx: int }, ... ] groupd by node (type/idx)
- inputReadPos: 0,
- animPos: 0,
- doAnim: true,
- uiOutputHeight: 300,
- }
- }
- function makeNeuronStore() {
- DBG && console.log("DBG:NeuronStore:makeNeuronStore");
- var _state = makeDefaultNeuronsStoreState()
- var _config = {}
- var _inputText = ''
- var _animIntervalID = null
- var _callback = null
- function readCharFromInput() {
- if (_state.inputReadPos >= _inputText.length) return null;
- var char = _inputText.charAt(_state.inputReadPos)
- _state.inputReadPos += 1
- return char;
- }
- function forwardAnim() {
- DBG1 && console.log("DBG:NeuronStore:forwardAnim:doAnim = '" + (_state.doAnim ? 1 : 0) + "'");
- if (!_state.doAnim) return;
- // 1. read from input if its time
- // 2. check overcharged nodes
- // 2.1 check overcharged Receptor
- // 2.2 check overcharged Neuron
- // 3. move all charges (Receptor -> Connection, Connection -> Neuron, Neuron -> Connection)
- // 4. discharge all
- // ad.2. TODO: what to do with Charge when create new Neuron?
- // - idea 1: use Charge to create new Neuron: rm Charge, add Neuron, add Connection
- // 1. read from input if its time
- if (0 === _state.animPos % _config.config_read_speed_multiplier) {
- // read from input = add charge to receptor with given letter
- var char = readCharFromInput()
- if (null === char) {
- DBG1 && console.log("DBG:NeuronStore:forwardAnim:1(readInput): STOP - end of input", { inputLength: _inputText.length, animPos: _state.animPos })
- _state.doAnim = false
- _notifySubscribers()
- return;
- }
- var foundReceptorIdx = getReceptorIdx(char)
- DBG1 && console.log("DBG:NeuronStore:forwardAnim:1(readInput): char('" + char + "', [" + char.charCodeAt(0) + "])", { animPos: _state.animPos, char, len: _inputText.length, doAnim: _state.doAnim, foundReceptorIdx })
- if (-1 === foundReceptorIdx) {
- DBG1 && console.warn("BUG: receptor '" + char + "' not found (NeuronStore:forwardAnim:readInput)")
- _state.doAnim = false
- _notifySubscribers()
- return;
- }
- chargeAdd(_config.config_charge_receptor_at_input, { type: 'receptor', idx: foundReceptorIdx })
- _state.animPos += 1
- _notifySubscribers()
- return;
- }
- // 2. check overcharged nodes
- // 2.1 check overcharged Receptor
- // 2.2 check overcharged Neuron
- { // check overcharged nodes
- var overchargedNeuronIdx = _state.neuron.reduce(function (ret, neuron, idx) {
- var charge = getNeuronCharge(idx)
- if (charge < neuron.maxCharge) return ret;
- ret.push({ idx: idx, charge: charge })
- return ret;
- }, [])
- var overchargedReceptorIdx = _state.receptor.reduce(function (ret, receptor, idx) {
- var charge = getReceptorCharge(idx)
- if (charge < _config.config_max_receptor_charge) return ret;
- ret.push({ idx: idx, charge: charge })
- return ret;
- }, [])
- if (overchargedNeuronIdx.length > 0) {
- var overcharged = overchargedNeuronIdx[0]
- var firstNeuron = _state.neuron[overcharged.idx]
- var secondNeuronWithCharge = _state.neuron.reduce(function (ret, neuron, idx) { // find neuron with max charge
- if (idx === overcharged.idx) return ret; // skip firstNeuron
- var charge = getNeuronCharge(idx)
- if (!charge) return ret; // skip Neuron without charge
- if (null === ret) return { idx: idx, charge: charge }
- return (charge > ret.charge) ? { idx: idx, charge: charge } : ret;
- }, null)
- DBG1 && console.log("TODO:NeuronStore:forwardAnim:2(check overcharged)/neuron.1", { overcharged, firstNeuron, secondNeuronWithCharge })
- if (null !== secondNeuronWithCharge) {
- // is already exists - check doubleConn: { from: [ neuronIdx, neuronIdx ], to: neuronIdx }
- var existingConn = _state.doubleConn.reduce(function (ret, dblConn) {
- if (ret) return ret;
- if (dblConn.from[0] === overcharged.idx && dblConn.from[1] === secondNeuronWithCharge.idx) return dblConn;
- // if (dblConn.from[1] === overcharged.idx && dblConn.from[0] === secondNeuronWithCharge.idx) return dblConn;
- return ret;
- }, null)
- var TODO__value = [firstNeuron.value, _state.neuron[secondNeuronWithCharge.idx].value].join('')
- var TODO__toNodeIdx = _state.neuron.reduce(function (ret, node, idx) {
- if (node.value === TODO__value) return idx;
- return ret;
- }, null)
- var TODO__toNode = (null !== TODO__toNodeIdx) ? _state.neuron[TODO__toNodeIdx] : null
- if (null !== TODO__toNode && null !== existingConn && TODO__toNodeIdx !== existingConn.toNode) {
- // existingConn = null // Froce create new connection if not the same order
- }
- var toNode = _state.neuron[secondNeuronWithCharge.idx]
- DBG1 && console.log("TODO:NeuronStore:forwardAnim:2(check overcharged)/neuron.2(secondNeuronWithCharge)", { from: firstNeuron.value, to: toNode.value, existingConn, TODO__value, TODO__toNode })
- if (existingConn) { // charge Neuron existingConn.to
- var idxNewNeuron = existingConn.to
- chargeRemove({ type: 'neuron', idx: overcharged.idx })
- chargeRemove({ type: 'neuron', idx: secondNeuronWithCharge.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'neuron', idx: overcharged.idx })
- chargeAdd(secondNeuronWithCharge.charge / 2, { type: 'neuron', idx: secondNeuronWithCharge.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getNeuronAlmostMaxCharge(overcharged.idx), { type: 'neuron', idx: overcharged.idx })
- chargeAdd(getNeuronAlmostMaxCharge(secondNeuronWithCharge.idx), { type: 'neuron', idx: secondNeuronWithCharge.idx })
- } break;
- }
- chargeAdd(overcharged.charge + secondNeuronWithCharge.charge, { type: 'neuron', idx: existingConn.to })
- } else { // create new
- var newNeuron = makeNeuronFromTwoNeurons(overcharged.idx, overcharged.charge, secondNeuronWithCharge.idx, secondNeuronWithCharge.charge)
- _state.neuron.push(newNeuron)
- updateOuputHeight(newNeuron)
- var idxNewNeuron = _state.neuron.length - 1
- _state.connection.push({ fromType: 'neuron', fromIdx: overcharged.idx, toIdx: idxNewNeuron, timesCreated: 1 })
- _state.connection.push({ fromType: 'neuron', fromIdx: secondNeuronWithCharge.idx, toIdx: idxNewNeuron, timesCreated: 1 })
- _state.doubleConn.push({ from: [overcharged.idx, secondNeuronWithCharge.idx], to: idxNewNeuron })
- chargeRemove({ type: 'neuron', idx: overcharged.idx })
- chargeRemove({ type: 'neuron', idx: secondNeuronWithCharge.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'neuron', idx: overcharged.idx })
- chargeAdd(secondNeuronWithCharge.charge / 2, { type: 'neuron', idx: secondNeuronWithCharge.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getNeuronAlmostMaxCharge(overcharged.idx), { type: 'neuron', idx: overcharged.idx })
- chargeAdd(getNeuronAlmostMaxCharge(secondNeuronWithCharge.idx), { type: 'neuron', idx: secondNeuronWithCharge.idx })
- } break;
- }
- }
- // _state.animPos += 1
- _notifySubscribers()
- return;
- } else { // !secondNeuronWithCharge
- // TODO: check if already exists! if yes then charge else create new
- var idxFoundConnection = _state.connection.reduce(function (ret, conn, idx) {
- if (ret > -1) return ret;
- if (conn.fromType === 'neuron' && conn.fromIdx === overcharged.idx) return idx;
- return ret;
- }, -1)
- DBG1 && console.log("TODO:NeuronStore:forwardAnim:2(check overcharged)/neuron.2(!secondNeuronWithCharge)", { idxFoundConnection })
- if (-1 === idxFoundConnection) {
- var newNeuron = makeNeuronFromOneNeuron(overcharged.idx, overcharged.charge)
- _state.neuron.push(newNeuron)
- updateOuputHeight(newNeuron)
- var idxNewNeuron = _state.neuron.length - 1
- _state.connection.push({ fromType: 'neuron', fromIdx: overcharged.idx, toIdx: idxNewNeuron, timesCreated: 1 })
- chargeRemove({ type: 'neuron', idx: overcharged.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'neuron', idx: overcharged.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getNeuronAlmostMaxCharge(overcharged.idx), { type: 'neuron', idx: overcharged.idx })
- } break;
- }
- } else {
- _state.connection[idxFoundConnection].timesCreated += 1
- // chargeMove(overcharged.charge, { type: 'receptor', idx: overcharged.idx }, { type: 'connection', idx: idxFoundConnection })
- chargeRemove({ type: 'neuron', idx: overcharged.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'neuron', idx: overcharged.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getNeuronAlmostMaxCharge(overcharged.idx), { type: 'neuron', idx: overcharged.idx })
- } break;
- }
- chargeAdd(overcharged.charge, { type: 'connection', idx: idxFoundConnection })
- }
- }
- }
- if (overchargedReceptorIdx.length > 0) { // TODO: while ?
- if (1 === overchargedReceptorIdx.length) {
- var overcharged = overchargedReceptorIdx.shift()
- // Restriction: only one connection between nodes
- {
- var idxFoundConnection = _state.connection.reduce(function (ret, conn, idx) {
- if (ret > -1) return ret;
- if (conn.fromType === 'receptor' && conn.fromIdx === overcharged.idx) return idx;
- return ret;
- }, -1)
- DBG1 && console.log("DBG:NeuronStore:forwardAnim:2(check overcharged)/receptor", { idxFoundConnection, from: { type: 'receptor', idx: overcharged.idx }, conn: [].concat(_state.connection) })
- if (-1 === idxFoundConnection) {
- var newNeuron = makeNeuronFromOneReceptor(overcharged.idx, overcharged.charge)
- _state.neuron.push(newNeuron)
- var idxNewNeuron = _state.neuron.length - 1
- _state.connection.push({ fromType: 'receptor', fromIdx: overcharged.idx, toIdx: idxNewNeuron, timesCreated: 1 })
- idxFoundConnection = _state.connection.length - 1
- chargeRemove({ type: 'receptor', idx: overcharged.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'receptor', idx: overcharged.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getReceptorAlmostMaxCharge(overcharged.idx), { type: 'receptor', idx: overcharged.idx })
- } break;
- }
- chargeAdd(overcharged.charge, { type: 'connection', idx: idxFoundConnection })
- } else {
- _state.connection[idxFoundConnection].timesCreated += 1
- // chargeMove(overcharged.charge, { type: 'receptor', idx: overcharged.idx }, { type: 'connection', idx: idxFoundConnection })
- chargeRemove({ type: 'receptor', idx: overcharged.idx })
- switch (_config.config_strategy_overcharge) {
- case "REMOVE_CHARGE": break;
- case "LEAVE_HALF_CHARGE": {
- chargeAdd(overcharged.charge / 2, { type: 'receptor', idx: overcharged.idx })
- } break;
- case "LEAVE_ALMOST_MAX": {
- chargeAdd(getReceptorAlmostMaxCharge(overcharged.idx), { type: 'receptor', idx: overcharged.idx })
- } break;
- }
- chargeAdd(overcharged.charge, { type: 'connection', idx: idxFoundConnection })
- }
- }
- // _state.animPos += 1
- _notifySubscribers()
- return;
- } else {
- DBG1 && console.log("TODO:NeuronStore:forwardAnim:2(check overcharged)/receptor", { TODO: "more then 1 receptor overcharged!" })
- }
- }
- // DBG1 && console.log("DBG:NeuronStore:forwardAnim:2(check overcharged)", { overchargedNeuronIdx, overchargedReceptorIdx })
- }
- { // 3. move all charges (Receptor -> Connection, Connection -> Neuron, Neuron -> Connection)
- DBG1 && console.log("TODO:NeuronStore:forwardAnim:3(move all charges)", { charge: [].concat(_state.charge) })
- var toAddChargeNeuronIdxList = _state.charge.filter(function (charge) { return ("connection" === charge.nodeType); }).map(function (charge) {
- return { charge: charge.charge, connIdx: charge.nodeIdx };
- })
- _state.charge = _state.charge.filter(function (charge) { return !("connection" === charge.nodeType); })
- toAddChargeNeuronIdxList.forEach(function (toAddCharge) {
- var conn = _state.connection[toAddCharge.connIdx]
- chargeAdd(toAddCharge.charge, { type: 'neuron', idx: conn.toIdx })
- })
- }
- { // 4. discharge all
- _state.charge = _state.charge.map(function (charge) {
- return Object.assign({}, charge, {
- charge: Math.max(0, charge.charge - _config.config_discharge_per_tick),
- })
- }).filter(function (charge) {
- return charge.charge > 0;
- })
- }
- _state.animPos += 1
- _notifySubscribers();
- }
- function makeNeuronFromTwoNeurons(fromNeuronIdx, fromNeuronCharge, toNeuronIdx, toNeuronCharge) {
- var fromNode = _state.neuron[fromNeuronIdx]
- var toNode = _state.neuron[toNeuronIdx]
- DBG1 && console.log("DBG:NeuronStore:makeNeuronFromTwoNeurons", { fromNode, toNode })
- var uiNewNodePos = { cx: 0, cy: 0 }
- { // closer to node with more charge (first)
- var xDiff = Math.abs(fromNode.ui.cx - toNode.ui.cx)
- var isFirstOnRight = (fromNode.ui.cx > toNode.ui.cx)
- // fromNeuronCharge + toNeuronCharge -- xDiff
- // toNeuronCharge -- x ==> x = toNeuronCharge * xDiff / (fromNeuronCharge + toNeuronCharge)
- var xToFirst = (toNeuronCharge * xDiff) / (fromNeuronCharge + toNeuronCharge)
- uiNewNodePos.cx = fromNode.ui.cx + (isFirstOnRight ? -1 : 1) * xToFirst
- }
- uiNewNodePos.cy = _state.neuron.reduce(function (ret, neuron) {
- if (uiNewNodePos.cx < neuron.ui.cx - 10) return ret;
- if (uiNewNodePos.cx > neuron.ui.cx + 10) return ret;
- if (ret < neuron.ui.cy - 10) return ret;
- if (ret > neuron.ui.cy + 10) return ret;
- return ret + 10 + _config.ui_space_y;
- }, fromNode.ui.cy + 10 + _config.ui_space_y)
- DBG1 && console.log("DBG:NeuronStore:makeNeuronFromTwoNeurons", { uiNewNodePos, fromNode, toNode })
- // var value = '' + (_state.neuron.length + 1);
- var value = [fromNode.value, toNode.value].join('')
- return Object.assign({}, DEFAULT_NEURON, {
- value: value,
- charge: 0,
- maxCharge: fromNode.maxCharge * _config.config_discharge_max_in_new_neuron_from_one,
- uiShape: "ellipse",
- ui: Object.assign({}, uiNewNodePos, {
- rx: 10,
- ry: 10,
- }),
- });
- }
- function makeNeuronFromOneReceptor(fromReceptorIdx, charge) {
- var sourceNode = _state.receptor[fromReceptorIdx]
- // var value = '' + (_state.neuron.length + 1);
- var value = [sourceNode.value, ""].join('') // TODO: same name what Receptor
- DBG1 && console.log("DBG:NeuronStore:makeNeuronFromOneReceptor", { sourceNode, confMaxCharge: _config.config_discharge_max_in_new_neuron_from_one })
- return Object.assign({}, DEFAULT_NEURON, {
- value: value,
- charge: 0,
- maxCharge: sourceNode.maxCharge * _config.config_discharge_max_in_new_neuron_from_one,
- uiShape: "ellipse",
- ui: {
- cx: sourceNode.ui.cx,
- cy: sourceNode.ui.cy + 10 + _config.ui_space_y,
- rx: 10,
- ry: 10,
- },
- });
- }
- function makeNeuronFromOneNeuron(fromNeuronIdx, charge) {
- var sourceNode = _state.neuron[fromNeuronIdx]
- // var value = '' + (_state.neuron.length + 1);
- var value = [sourceNode.value, "^"].join('')
- DBG1 && console.log("DBG:NeuronStore:makeNeuronFromOneNeuron", { sourceNode, confMaxCharge: _config.config_discharge_max_in_new_neuron_from_one })
- return Object.assign({}, DEFAULT_NEURON, {
- value: value,
- charge: 0,
- maxCharge: sourceNode.maxCharge * _config.config_discharge_max_in_new_neuron_from_one,
- uiShape: "ellipse",
- ui: {
- cx: sourceNode.ui.cx,
- cy: sourceNode.ui.cy + 10 + _config.ui_space_y,
- rx: 10,
- ry: 10,
- },
- });
- }
- function chargeAdd(charge, to) {
- var foundChargeIdx = _state.charge.reduce(function (ret, charge, idx) {
- if (charge.nodeType === to.type && charge.nodeIdx === to.idx) return idx;
- return ret;
- }, -1)
- DBG1 && console.log("DBG:NeuronStore:chargeAdd", { charge, to, foundChargeIdx })
- if (-1 === foundChargeIdx) {
- _state.charge.push({ charge: charge, nodeType: to.type, nodeIdx: to.idx })
- foundChargeIdx = _state.charge.length - 1
- } else {
- _state.charge[foundChargeIdx].charge += charge
- }
- DBG1 && console.log("DBG:NeuronStore:chargeAdd.2", { state_charge: [].concat(_state.charge) })
- return foundChargeIdx;
- }
- function chargeRemove(from) {
- _state.charge = _state.charge.filter(function (item) {
- return !(from.type === item.nodeType && from.idx === item.nodeIdx);
- })
- }
- function updateOuputHeight(newNeuron) {
- if (newNeuron.ui.cy + 30 > _state.uiOutputHeight) {
- _state.uiOutputHeight = newNeuron.ui.cy + 30
- }
- }
- function dispatch(payload) {
- DBG1 && console.log("DBG:NeuronStore:dispatch('" + payload.type + "')", payload);
- switch (payload.type) {
- case 'INIT': stateReset(payload.inputText, payload.config); startAnimation(); break;
- case 'PAUSE': _state.doAnim = false; _notifySubscribers(); break;
- case 'PLAY': _state.doAnim = true; break;
- default: {
- DBG1 && console.warn("Not implemented dispatch action type '" + payload.type + "'")
- }
- }
- }
- function subscribe(callback) {
- _callback = callback; // TODO: array
- return unsubscribe;
- }
- function unsubscribe() {
- _callback = null
- }
- function _notifySubscribers() {
- if (_callback) _callback()
- }
- function makeReceptor(value, idx, arr) { // usage: [].map(makeReceptor)
- var totalReceptors = arr.length;
- var cx = Math.ceil(_config.ui_output_width / (totalReceptors + 1));
- var r = Math.min(Math.ceil(_config.ui_output_width / (totalReceptors + 10) / 2), _config.ui_max_receptor_r);
- var xCenter = cx + cx * idx - r;
- return Object.assign({}, DEFAULT_NEURON, {
- value: value,
- maxCharge: _config.config_max_receptor_charge,
- uiShape: "circle",
- ui: {
- cx: xCenter,
- cy: 40,
- r: r,
- },
- next: [],
- })
- }
- function stateReset(inputText, config) {
- _inputText = inputText
- _config = config
- _state = makeDefaultNeuronsStoreState()
- var distinct = function (value, idx, self) {
- return (idx === self.indexOf(value));
- };
- var foundLetters = inputText.split("").filter(distinct);
- _state.receptor = foundLetters.map(makeReceptor);
- _state.mapReceptorChar = _state.receptor.map(function (node) { return node.value; });
- if (_animIntervalID) clearInterval(_animIntervalID)
- _notifySubscribers();
- }
- function getReceptorIdx(char) {
- return _state.mapReceptorChar.indexOf(char)
- }
- function startAnimation() {
- _state.doAnim = true
- if (_animIntervalID) clearInterval(_animIntervalID)
- _animIntervalID = setInterval(forwardAnim, _config.config_anim_speed)
- }
- function getReceptorCharge(idx) {
- return _state.charge.filter(function (charge) {
- return ('receptor' === charge.nodeType && idx === charge.nodeIdx);
- }).reduce(function (ret, charge) {
- return ret + charge.charge;
- }, 0)
- }
- function getNeuronCharge(idx) {
- return _state.charge.filter(function (charge) {
- return ('neuron' === charge.nodeType && idx === charge.nodeIdx);
- }).reduce(function (ret, charge) {
- return ret + charge.charge;
- }, 0)
- }
- function getReceptorAlmostMaxCharge(idx) {
- return _state.receptor[idx].maxCharge - _config.config_discharge_per_tick;
- }
- function getNeuronAlmostMaxCharge(idx) {
- DBG1 && console.log("DBG:getNeuronAlmostMaxCharge(" + idx + ")", { charge: _state.neuron[idx].maxCharge - _config.config_discharge_per_tick })
- return _state.neuron[idx].maxCharge - _config.config_discharge_per_tick;
- }
- function getNodesChargeState() {
- var receptor = [].concat(_state.receptor);
- var neuron = [].concat(_state.neuron);
- _state.charge.forEach(function (charge) {
- // _state.charge: [ { charge: number, nodeType: (receptor|neuron), nodeIdx: int }, ... ] groupd by node (type/idx)
- switch (charge.nodeType) {
- case 'receptor': receptor[charge.nodeIdx].charge = charge.charge; break;
- case 'neuron': neuron[charge.nodeIdx].charge = charge.charge; break;
- }
- })
- function getNodeInfoFunction(type) {
- return function _getNodeInfo(node) {
- return {
- type: type,
- value: node.value,
- charge: node.charge,
- }
- }
- }
- return receptor.map(getNodeInfoFunction('receptor'))
- .concat(
- neuron.map(getNodeInfoFunction('neuron'))
- )
- ;
- }
- return {
- subscribe: subscribe,
- dispatch: dispatch,
- getState: function () { return _state; },
- getNodesChargeState: getNodesChargeState,
- getListReceptor: function () { return _state.receptor; },
- getListNeuron: function () { return _state.neuron; },
- getReceptor: function (idx) { return _state.receptor[idx]; },
- getNeuron: function (idx) { return _state.neuron[idx]; },
- getConnection: function (idx) { return _state.connection[idx]; },
- getListConnection: function () { return _state.connection; },
- getListCharge: function () { return _state.charge; },
- getReceptorCharge: getReceptorCharge,
- getNeuronCharge: getNeuronCharge,
- }
- }
- global[MAKE_STORE_FUNCTION_NAME] = makeNeuronStore
- // export default makeNeuronStore
|