I'm not sure anybody out there will be able to help with this, but here goes. I'm currently refactoring a game I'm writing with CraftyJS (an excellent component based game engine) to use RequireJS. Everything's been going pretty well, but suddenly I've hit a snag. I've built a module, in which I define a small Crafty component which is basically just a bottleneck for event listening. In one of the callbacks, I call several functions which are defined in the local module. I've used this pattern in RequireJS in many contexts, and it's always worked for me. For some reason, in this case some of the functions are undefined. Not all of them. Just some. Here's some code:
The component:
Crafty.c("TurnStateMachineObserver", {
startListening: function() {
...
this.bind(POST+PHASE_CHANGE, function(e) {
// this is called after the phase change has already been
// applied. now, switch to the next phase, if appropriate.
var curPhase = currentPhase();
var nextPhase = nextPhase();
if (nextPhase === PHASE_TURN_START)
_triggerPlayerChange(nextPlayer());
else if (curPhase !== PHASE_MAIN)
_triggerPhaseChange(nextPhase());
})
.bind(POST+RESET, function(e) {
reset();
});
},
...
});
For those of you unfamiliar with Crafty, Crafty.c
creates a component which can later be instantiated. The object literal passed as the second argument will be appended (extended?) to any object which includes TurnStateMachineObserver
as one of its components (i.e. using Crafty.e("TurnStateMachineObserver")
).
The functions used inside the component are defined later in the same file (the whole file is wrapped in a define()
call):
// Function: currentPhase
// The current <Turn Phase>.
function currentPhase() {
if (_currentPhaseIndex < 0) _currentPhaseIndex = 0;
return PHASES[_currentPhaseIndex];
}
// Function: nextPhase
// The phase following the <currentPhase>. Order follows the
// <PHASES> list.
function nextPhase() {
var phaseIndex = _currentPhaseIndex + 1;
phaseIndex %= PHASES.length;
return PHASES[phaseIndex];
}
Now, when the POST+PHASE_CHANGE
event is fired, an exception is thrown at the call to nextPhase()
, but NOT at the call to currentPhase()
! After some debugging, I've determined that, in fact, while all of the functions defined in the module are properly defined when the define()
body is first entered, most of them are undefined inside the component's callbacks. In fact, when the component is instantiated thusly
if (!_observer)
_observer = Crafty.e("TurnStateMachineObserver");
_observer.startListening();
in the init
function (which the module returns), nextPhase()
is defined, but if I step into _observer.startListening()
, it's not, though currentPhase()
is. Argh! I'm pulling what's left of my hair out over this one. The thing that's got me really confused is that these functions are siblings. How can some functions from a higher scope be defined while others are not?!