nap()
to loop thru all sprites after each render to see if any sprites had no height set (since i was letting the browser do the heights previously, and only settings widths) -- if there was no height, that would mean it was a freshly added sprite and i needed to wait for its image to load and then read its height and set it on the sprite. so waiting for assets to load and then parsing/reading/whatever from them seems like a good "automatic action"
caculateSpriteHeight
action in the state function, but also using jquery to wait for the sprite's image to load and in the callback kicking off another doneCalculatingHeight
action. but then i realized probably i only needed the former action in there, and all that other jquery stuff could be moved out into the calculateSpriteHeight
action itself. wasn't sure if that was a bad idea -- presenting to the model, but also kicking off another action after some async occurred
mousedown
into appropriate actions -- so now in mousedown
i figure out which sprite's grip i'm clicking on, inspect the DOM to find the sprite's image's current height, and then fire both a setSpriteHeight
action with that height, as well as the beginSizingSprite
action. a sort of JIT setting of the height i guess, heh
I would not say "centralized", it's more like "deliberate", the step during which you mutate state must be delineated. You can't arbitrarily/liberally assign property values. That is (IMHO) what's wrong with the way we write code.
@chuckrector why is it that the model has to know about the sprite until it's loaded? Can't you write an action where the proposal will include the new sprite, including it's action?
addSprite( url ) {
request(url, function(data) {
let height = h(data);
let width = w(data);
present( { newSprite: { data, height, width}}) ;
});
}
I really don't see the need for nap() to be involved. That's kind of the big value add of SAM, you need to inform the application state of what's happening (unless it logically requires that you do so)
model[property] = "newValue";
anywhere instead of only in the model.
addSprite
sort of action
height
for each sprite would make my current initial model data invalid
app.ts
via imports and wire up various events with it and it's great. but if i wish to use jquery as part of my onClick
events that are generated in the view, i must also include jquery in my index.html
via script tag
any
everywhere. probably also due to not designing a lot up front
webpack is appealing to learn
never though I would see a sentence containing these words
V = f(S(M))
"on paper ng2 would be everything I dislike"
then I understand, how perhaps "sometimes you just can't explain it"
and you were able to make the best of it with ng2 and avoid the bad parts.
@jdubray
Computables in MobX would be a good paradigm for the State function
That was the first thing I thought when looking at sam
class State {
@observable _counter = COUNTER_MAX;
@observable _aborted = false;
@observable _started = false;
@observable _launched = false;
public actions: Actions
constructor( a: Actions) {
this.actions = a ;
}
getActions() {
return actions ;
}
representation (model) {
console.log(model) ;
this._counter = model.counter;
this._started = model.started;
this._aborted = model.aborted;
this._launched = model.launched;
}
// Derive the current state of the system
@computed get ready() {
return ((this._counter === COUNTER_MAX) && !this._started && !this._launched && !this._aborted);
}
@computed get counting() {
return ((this._counter <= COUNTER_MAX) && (this._counter >= 0) && this._started && !this._launched && !this._aborted) ;
}
@computed get launched() {
return ((this._counter == 0) && this._started && this._launched && !this._aborted) ;
}
@computed get aborted() {
return ( ( this._counter <= COUNTER_MAX) && (this._counter >= 0)
&& this._started && !this._launched && this._aborted ) ;
}
// Next action predicate, derives whether
// the system is in a (control) state where
// an action needs to be invoked
nextAction() {
if (this.counting) {
if (this._counter>0) {
actions.decrement({counter: this._counter}) ;
}
if (this._counter === 0) {
actions.launch({}) ;
}
}
}
render(model) {
this.representation(model)
this.nextAction() ;
}
}
TOP_LEVEL_RANDOM_GIF_UPDATED
and FIRST_RANDOM_GIF_UPDATED
? Why can't RandomGif just be a single, reusable component and you can just put as many instances on the page as you want?
"In fractal architectures, the whole can be naively packaged as a component to be used in some larger application.
In non-fractal architectures, the non-repeatable parts are said to be orchestrators over the parts that have hierarchical composition."
state()
is synchronous
await
, which is in a future spec of JS). when you pass a callback, that's usually when async stuff can occur.
V = S(vm(M.present(A(M))), nap(M, A))
V= nap(S(present(A(M)))
V=S(present(A(M))
nap must happen outside
state
and nap
function
state
function imo
V=render(S(present(A(M)))
mySAMAction(event) {
let proposal = my_functional_action(event) ;
present(proposal)
}
V=represent(state(present(action(model))))