First, thanks for this interesting answer
Second, you don't really answer my question, even if I think I understand why you did that.
Third, I read your code, and while it's undoubtedly cleaner (and would I be coding on anything else than a MD, I suppose I'd use it) I don't see why it would be more efficient.
What I do for now :
- the call to a state_function is, from the asm side, I suppose it'll be a :
- At each iteration, the current state function takes care of modifying the value at state_fun
In your method :
- the call to the state_function should be something like :
Code: Select all
move.w (cur_state), d0
move.l (state), a0
jsr (a0, d0)
Difference with former code is not signifiant (likely a little slower).
- at each iteration, you'll have to find in the table the dst_state from the pair (src_state, ret_code).
I bet it can be done in constant time if each src_state has exactly (number of ret_codes) entries (I'm assuming you forgot one line in state_transitions[] which would be {entry, repeat, entry}) but there would be a multiplication involved and it's slow (it could be optimized of course, but if you decide to add a new ret_code, you'll have to change the optimization, and then to change the whole state_transition).
Another drawback is that there are in my program maybe 15 different events that could trigger a transition, but for a given state, only 3 of them actually triggers it. So I'd need to make a huge array where most lines would be {state, ret, state} (if you prefer, the transition matrix is sparse). If I decide that ignored transitions don't have to appear in the state_transitions array, then I can't determine the dst_state in constant time.
So, I'm not really convinced it's faster. And I'm not sure the compromise between clarity and speed is favourable.
Concerning my initial question, I suppose I can do something like (not really sure about where to put the ##) :
Code: Select all
#define MUSASHI_WALK_(dir, DIR) \
void musashi_walk_##dir(Object *self) {\
set_physics(DIR##_DX, 0, 0, 0);\
set_anim(MUSASHI_WALK_##DIR);\
self->update_function = (state_function*) musashi_walk_##dir##_update;\
}
MUSASHI_WALK(left, LEFT)
MUSASHI_WALK(right, RIGHT)
Could be a little more polished if there's a mean to make a token UPPERCASE.