Skip to content

Instantly share code, notes, and snippets.

@heycarsten
Last active February 8, 2017 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heycarsten/7136a752d42aee13c1072c96480494f4 to your computer and use it in GitHub Desktop.
Save heycarsten/7136a752d42aee13c1072c96480494f4 to your computer and use it in GitHub Desktop.
ember-fsm
import Ember from 'ember';
import FSM from 'ember-fsm';
const WAIT_TIMES = {
'red': 5000,
'amber': 3500,
'green': 6500
};
export default Ember.Controller.extend(FSM.Stateful, {
fsmStates: {
initialState: 'off',
off: {
didEnter: ['didPowerOff', 'notifyPowerDown'],
willExit: 'notifyPowerUp'
}
},
fsmEvents: {
cycle: {
after: 'colorChanged',
transitions: [
{ off: 'red' },
{ red: 'green' },
{ green: 'amber' },
{ amber: 'red' }
]
},
powerDown: {
transition: {
from: ['red', 'green', 'amber'], to: 'off'
}
}
},
actions: {
powerUp() {
this.sendStateEvent('cycle');
},
powerDown() {
if (this.get('isInOff')) {
return;
}
this.set('doPowerDown', true);
}
},
didPowerOff() {
this.set('doPowerDown', false);
},
notifyPowerUp() {
this.log('info', 'Requesting to take traffic signal online.');
return this.sleep(3000).then(() => {
this.log('info', 'Notified central office of power up.');
});
},
notifyPowerDown() {
this.log('info', 'Notified central office of power down.');
},
colorChanged(transition) {
let ms = WAIT_TIMES[this.get('fsmCurrentState')];
this.log('change', `${transition.fromState} -> ${transition.toState}`);
return this.sleep(ms).then(() => {
if (this.get('doPowerDown')) {
this.sendStateEvent('powerDown');
} else {
this.sendStateEvent('cycle');
}
});
},
sleep(ms) {
return new Ember.RSVP.Promise((resolve) => {
Ember.run.later(this, () => {
resolve();
}, ms);
});
},
log(level, message) {
this.get('model.messages').pushObject({
level: level,
message: message
});
}
});
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return { messages: Ember.A([]) };
}
});
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.signal {
text-align: center
}
.signal ol {
display: inline-block;
font-family: "wingdings";
background: #ec2;
line-height: 0.85;
border-radius: 4px;
margin: 0;
padding: 0;
padding: 14px 42px;
list-style: none;
font-size: 110px;
color: #aaa;
}
.signal li {
margin: 0;
padding: 0;
}
.red {
color: #f22;
}
.green {
color: #1e2;
}
.amber {
color: #ed3;
}
.log ol {
list-style: none;
margin: 22px 0;
padding: 0;
}
{{outlet}}
<section class="signal">
<ol>
<li class="{{if isInRed "red"}}">l</li>
<li class="{{if isInAmber "amber"}}">l</li>
<li class="{{if isInGreen "green"}}">l</li>
</ol>
</section>
<fieldset>
<legend>Control Panel</legend>
{{#unless isInOff}}
{{#if doPowerDown}}
<em>Please wait.</em>
{{else}}
<button {{action "powerDown"}}>Turn Off</button>
{{/if}}
{{else}}
<button {{action "powerUp"}} disabled={{isLoading}}>Turn On</button>
{{/unless}}
</fieldset>
<section class="log">
<ol>
{{#each model.messages as |item|}}
<li class="{{item.level}}">
<span class="level">[{{item.level}}]</span>
<span class="message">{{item.message}}</span>
</li>
{{/each}}
</ol>
</section>
{
"version": "0.11.0",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": true,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.10.2",
"ember-data": "2.11.0",
"ember-template-compiler": "2.10.2",
"ember-testing": "2.10.2"
},
"addons": {
"ember-fsm": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment