kharandziuk - 1 year ago 88
Javascript Question

# Circular Dependencies with RxJS. Modeling spores

I try to model some game with RxJS. but I found some troubles with circular dependencies. So, I simplified my game to a simple simulation(I left only 'move' action). You can find code below(I omitted some parts, you can find the repo here)

``````const rx = require('rx')
const math = require('mathjs')
const _ = require('underscore')

const FIELD_SIZE = 10

const ctx = require('axel');

let getInitialState = () => {
return {
size: FIELD_SIZE,
people: [
{ x: 0, y: 0 },
{ x: 9, y: 9 },
{ x: 5, y: 5 }
]
}
}

var drawWorld = ({size, people}) => {
// draw world logic
}

let getMove = (index)=> {
let [xOffset, yOffset] = [[0,1], [1,0]][math.pickRandom([0, 1])]
let direction = math.pickRandom([-1, 1])
return (state) => {
let {people} = state
let p = people[index]
people[index] = {
x: math.max(
0,
math.min(p.x + xOffset * direction, FIELD_SIZE-1)),
y: math.max(
0,
math.min(p.y + yOffset * direction, FIELD_SIZE-1))
}
return _.extend({}, state, {people})
}
}

var POOL = []

var produceActions = (state) => {
_.range(state.people.length).forEach((i) => {
POOL.push(getMove(i))
})
}

var stateObservable = rx.Observable
.interval(100)
.timeInterval()
.map(()=> {
var x = POOL.slice()
POOL.splice(0, POOL.length)
return x
})
.scan(
(state, ops) => ops.reduce(
(st, o) => o(st),
state
),
getInitialState()
)

stateObservable.subscribe(drawWorld)
stateObservable.tap(produceActions).subscribe()
``````

Is there a way to rewrite this ugly `produceActions' part which relies on global variable?
Like proposed in the @user3743222 answer

Answer Source

Following your updated question and request for an example, this is untested but here is my try, based on the provided link on the subject technique. Check if it works, I'll post some explanations after that if it does. Also, please check the syntax, I don't know so much about ES6.

Using a proxy subject for `POOL`:

``````var POOL_proxyS = new Rx.BehaviorSubject([]); // instead of var POOL = []

var stateObservable = rx.Observable
.interval(100)
.timeInterval()
.combineLatest(POOL_proxyS, (_, POOL) => POOL.slice() )
.scan(
(state, ops) => ops.reduce(
(st, o) => o(st),
state
),
getInitialState()
);

var produceActions = (state) => _.range(state.people.length).map((i) => getMove(i));

stateObservable
.do(drawWorld)
.map(produceActions)
.subscribe(POOL_proxyS);
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download