I'am using Mobx to build a webgl game engine. I am not using it with react. I am using it to enhance an entity component system. I have entity classes like
import {observable, observe, computed, autorun} from 'mobx';
class Entity {
@observable position = [0,0,0]
@observable rotation = [0,0,0]
@computed get modelMat(){
return position * rotation;
}
}
I use this entity like :
var ent = new Entity();
entity.position = [0,10,0];
if(entity.modelMat == 6){
// do something
}
My understanding is that reading modelMat directly like that is not a best practice. It causes the computed to be recalculated. It is not cached. This is detrimental in my game engine as I might be accessing these computed values at a high velocity like 60fps.
This seems unintuitive to me because you define the computed using the get helper and then are not supposed to use it as a getter? The debug computedRequiresReaction setting is available to prevent this pattern of direct computed reading.
configure({
computedRequiresReaction: true
});
My question then is how to cache or memoize these computed values that will be accessed at frequent intervals? To avoid this I have started using a pattern that uses autoruns, to update local variables when the computed changes. It looks like:
class Entity {
@observable position = [0,0,0]
@observable rotation = [0,0,0]
modelMat = []
constructor(){
autorun(() => {
this.modelMat = this.computedModelMat()
})
}
@computed get computedModelMat(){
return position * rotation;
}
}
This enables an interface for the class so that ent.modelMat can still be accessed rapidly but its not re-computed each time. Is there a better suggested pattern for this? It seems redundant to have an autorun for each computed. some of my classes end up having many autorun handlers to cache these values.