(function(){
var Events = {
bind: function(){
if(!this.o) this.o = $({});
this.o.bind.apply(this.o, arguments);
},
trigger: function(){
if(!this.o) this.o = $({});
this.o.trigger.apply(this.o, arguments);
}
};
var StateMachine = function(){};
StateMachine.fn = StateMachine.prototype;
$.extend(StateMachine.fn, Events);
StateMachine.fn.add = function(controller){
// this.o > events > changeに
// コールバックがスタックされていく
this.bind('change', function(e, current){
// currentにはアクティブ化されたコントローラーが返って来る
if(controller === current)
// アクティブ化されたコントローラならアクティブに
controller.activate();
else
// アクティブ化されたコントローラ以外ならディアクティブに
controller.deactivate();
});
// それぞれのコントローラにイベントを紐付け、
// 発火時には自身(コントローラ)を引数として渡す
controller.active = $.proxy(function(){
this.trigger('change', controller);
}, this);
};
var con1 = {
activate: function(){
console.log('controller 1 activated');
},
deactivate: function(){
console.log('controller 1 deactivated');
}
};
var con2 = {
activate: function(){
console.log('controller 2 activated');
},
deactivate: function(){
console.log('controller 2 deactivated');
}
};
var sm = new StateMachine;
sm.add(con1);
sm.add(con2);
con1.active();
//con2.active();
}());
External resources loaded into this fiddle: