-
Notifications
You must be signed in to change notification settings - Fork 147
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
65 changed files
with
3,190 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# ATM Example | ||
|
||
An example application where one FSM acts as the "brains" for an ATM machine (AtmFsm.js), and another controls how the nav bar is displayed (NavFsm.js), depending on the state of the application. | ||
|
||
There are two sets of credentials that will work with this sample app: | ||
|
||
* acct 123456789, pin 8675 | ||
* acct 987654321, pin 3090 | ||
|
||
This example application was intentionally written without message-bus interaction in order to demonstrate direct API usage. For a message-bus-integrated example, please see the "load" sample app. | ||
|
||
Even though messaging is not actively used in this example, it *does* demonstrate the auto-wireup to amplify.js's pub/sub. The auto-wireup to amplify provides a wiretap, which causes any FSM events to be printed to the console. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE HTML> | ||
<html lang="en-US"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>ATM State Machine Example</title> | ||
<link rel="stylesheet" type="text/css" href="style.css"> | ||
<script type="text/javascript" src="../../bower/lodash/dist/lodash.js"></script> | ||
<script type="text/javascript" src="../../bower/jquery/jquery.min.js"></script> | ||
<script type="text/javascript" src="../../bower/backbone/backbone-min.js"></script> | ||
<script type="text/javascript" src="/ext/infuser_all.js"></script> | ||
<script type="text/javascript" src="../../bower/amplify/lib/amplify.js"></script> | ||
<script type="text/javascript" src="js/amplify.diagnostics.js"></script> | ||
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/machina.js/1.1.0/machina.js"></script> | ||
<script type="text/javascript" src="../../bower/accounting/accounting.js"></script> | ||
<script type="text/javascript" src="js/appConfig.js"></script> | ||
<script type="text/javascript" src="js/Repository.js"></script> | ||
<script type="text/javascript" src="js/router.js"></script> | ||
<script type="text/javascript" src="js/AtmFsm.js"></script> | ||
<script type="text/javascript" src="js/NavFsm.js"></script> | ||
<script type="text/javascript" src="js/models/AppModel.js"></script> | ||
<script type="text/javascript" src="js/models/AccountInfo.js"></script> | ||
<script type="text/javascript" src="js/models/LoginModel.js"></script> | ||
<script type="text/javascript" src="js/models/DepositModel.js"></script> | ||
<script type="text/javascript" src="js/models/WithdrawalModel.js"></script> | ||
<script type="text/javascript" src="js/models/ResultModel.js"></script> | ||
<script type="text/javascript" src="js/views/AccountView.js"></script> | ||
<script type="text/javascript" src="js/views/ResultView.js"></script> | ||
<script type="text/javascript" src="js/views/DepositView.js"></script> | ||
<script type="text/javascript" src="js/views/WithdrawalView.js"></script> | ||
<script type="text/javascript" src="js/views/LoginView.js"></script> | ||
<script type="text/javascript" src="js/views/NavView.js"></script> | ||
<script type="text/javascript" src="js/views/AppView.js"></script> | ||
<script type="text/javascript" src="js/main.js"></script> | ||
</head> | ||
<body> | ||
<div id="container"> | ||
<div id="content"></div> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
This FSM generates the following custom events: | ||
"Initialized", | ||
"Authorized", | ||
"UnAuthorized", | ||
"Deposit", | ||
"Withdrawal", | ||
"OverLimit", | ||
"Result" | ||
*/ | ||
var Atm = function() { | ||
var fsm; | ||
fsm = new machina.Fsm( { | ||
initialState: "uninitialized", | ||
states: { | ||
"uninitialized": { | ||
"initialize": function() { | ||
// TODO: any other init work here... | ||
this.emit( "Initialized" ); | ||
this.transition( "unauthorized" ); | ||
} | ||
}, | ||
"unauthorized": { | ||
_onEnter: function() { | ||
this.emit( "UnAuthorized", { msg: "Please enter your account and PIN." } ); | ||
}, | ||
"*": function() { | ||
this.emit( "UnAuthorized", { msg: "You must authenticate first." } ); | ||
}, | ||
authorize: function( credentials ) { | ||
if ( authRepository.authorize( credentials.acct, credentials.pin ) ) { | ||
this.acct = credentials.acct; | ||
this.transition( "authorized" ); | ||
return; | ||
} | ||
this.emit( "UnAuthorized", { msg: "Invalid Account and/or PIN." } ); | ||
} | ||
}, | ||
"authorized": { | ||
_onEnter: function() { | ||
this.emit( "Authorized", { acct: this.acct } ); | ||
}, | ||
deposit: function( amount ) { | ||
var result = clientRepository.deposit( this.acct, amount ); | ||
this.emit( "Result", result ); | ||
}, | ||
withdrawal: function( amount ) { | ||
var result = clientRepository.withdrawal( this.acct, amount ); | ||
this.emit( "Result", result ); | ||
}, | ||
deauthorize: function() { | ||
authRepository.deauthorize( this.acct ); | ||
delete this.acct; | ||
this.transition( "unauthorized" ); | ||
} | ||
} | ||
} | ||
} ); | ||
return fsm; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
var NavFsm = function( appFsm, navView ) { | ||
var fsm = new machina.Fsm( { | ||
initialState: "unauthorized", | ||
states: { | ||
"unauthorized": { | ||
_onEnter: function() { | ||
navView.unAuthLayout(); | ||
}, | ||
"*": function() { | ||
navView.unAuthLayout(); | ||
} | ||
}, | ||
"authorized": { | ||
"*": function() { | ||
navView.authLayout(); | ||
}, | ||
"deposit": function() { | ||
navView.depositLayout(); | ||
}, | ||
"withdrawal": function() { | ||
navView.withdrawalLayout(); | ||
} | ||
} | ||
} | ||
} ); | ||
appFsm.on( "Authorized", function() { | ||
fsm.transition( "authorized" ); | ||
} ); | ||
appFsm.on( "UnAuthorized", function() { | ||
fsm.transition( "unauthorized" ); | ||
} ); | ||
return fsm; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
var clientRepository, authRepository, resources, accounts, currentAcct; | ||
( function( _ ) { | ||
var results = { }; | ||
accounts = { | ||
"123456789": { | ||
pin: "8675", | ||
name: "Elwin Ransom", | ||
limit: 20000, | ||
balance: 100000 | ||
}, | ||
"987654321": { | ||
pin: "3090", | ||
name: "Edward Weston", | ||
limit: 400, | ||
balance: 300 | ||
} | ||
}; | ||
authRepository = { | ||
authorize: function( acct, pin ) { | ||
var authed = accounts[acct] && accounts[acct].pin === pin; | ||
if ( authed ) { | ||
currentAcct = acct; | ||
return true; | ||
} | ||
return false; | ||
}, | ||
|
||
deauthorize: function( acct ) { | ||
if ( currentAcct === acct ) { | ||
currentAcct = undefined; | ||
return true; | ||
} | ||
return false; | ||
} | ||
}; | ||
clientRepository = { | ||
withdrawal: function( acct, amount ) { | ||
var current = accounts[currentAcct], | ||
newBal = current.balance - amount, | ||
result = { | ||
status: ( amount > current.limit ) ? "OverLimit" : ( newBal < 0 ) ? "InsufficientFunds" : "Successful", | ||
transactionAmount: amount | ||
}; | ||
if ( result.status === "Successful" ) | ||
current.balance = newBal; | ||
if ( !results[acct] ) { | ||
results[acct] = []; | ||
} | ||
results[acct].push( $.extend( true, { transactionType: "Withdrawal" }, accounts[ currentAcct ], result ) ); | ||
return { acct: acct, resultId: results[acct].length - 1 }; | ||
}, | ||
deposit: function( acct, amount ) { | ||
accounts[ currentAcct ].balance += amount; | ||
if ( !results[acct] ) { | ||
results[acct] = []; | ||
} | ||
results[acct].push( $.extend( true, { transactionType: "Deposit" }, accounts[ currentAcct ], { status: "Successful", transactionAmount: amount } ) ); | ||
return { acct: acct, resultId: results[acct].length - 1 }; | ||
} | ||
}; | ||
resources = { | ||
result: { | ||
read: function( model, options ) { | ||
options.success( results[model.acct][model.id] ); | ||
} | ||
}, | ||
accountInfo: { | ||
read: function( model, options ) { | ||
options.success( accounts[model.id] ); | ||
} | ||
} | ||
}; | ||
|
||
Backbone.sync = function( method, model, options ) { | ||
var modelType = model.get( "modelType" ); | ||
resources[modelType][method]( model.toJSON(), options ); | ||
}; | ||
} )( _ ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var orig = amplify.publish; | ||
|
||
amplify.publish = function( topic, message ) { | ||
try { | ||
console.log( topic + " " + JSON.stringify( message ) ); | ||
} | ||
catch ( exception ) { | ||
console.log( topic + " (unable to serialize payload)" ); | ||
} | ||
orig.call( this, topic, message ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
( function( $, _, infuser, undefined ) { | ||
var infuserDefault = infuser.defaults; | ||
|
||
infuser.defaults = $.extend( true, infuserDefault, { | ||
templateUrl: "/example/atm/templates", | ||
bindingInstruction: function( template, model ) { | ||
return template( model ); | ||
}, | ||
render: function( target, template ) { | ||
$( target ).html( template ); | ||
}, | ||
useLoadingTemplate: false, | ||
templatePreProcessor: function( template ) { | ||
return _.template( template ); | ||
} | ||
} ); | ||
} )( jQuery, _, infuser ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
var AtmApplication = function( target ) { | ||
//---------------------------------------------------------------------------- | ||
// | ||
// The top level application object | ||
// | ||
//---------------------------------------------------------------------------- | ||
var app = { | ||
atm: new Atm(), | ||
models: { | ||
accountInfo: undefined | ||
}, | ||
views: { | ||
main: new AppView( { target: target } ), | ||
nav: new NavView(), | ||
login: new LoginView( { target: "#screen" } ), | ||
account: new AccountView( { target: "#screen" } ), | ||
deposit: new DepositView( { target: "#screen" } ), | ||
result: new ResultView( { target: "#screen" } ), | ||
withdrawal: new WithdrawalView( { target: "#screen" } ) | ||
}, | ||
start: function() { | ||
this.atm.handle( "initialize" ); | ||
} | ||
}; | ||
|
||
app.navFsm = new NavFsm( app.atm, app.views.nav ); | ||
|
||
//---------------------------------------------------------------------------- | ||
// | ||
// Handlers for View Events | ||
// | ||
//---------------------------------------------------------------------------- | ||
app.views.main.on( "AppRendered", function() { | ||
app.views.nav.render( app.views.nav.unAuthLayout ); | ||
} ); | ||
|
||
app.views.login.on( "Authenticate", function( model ) { | ||
app.atm.handle( "authorize", model ); | ||
} ); | ||
|
||
app.views.deposit.on( "Deposit", function( amount ) { | ||
app.atm.handle( "deposit", amount ); | ||
} ); | ||
|
||
app.views.withdrawal.on( "Withdrawal", function( amount ) { | ||
app.atm.handle( "withdrawal", amount ); | ||
} ); | ||
|
||
//---------------------------------------------------------------------------- | ||
// | ||
// Handlers for App FSM Events | ||
// | ||
//---------------------------------------------------------------------------- | ||
app.atm.on( "Initialized", function() { | ||
app.views.main.render(); | ||
app.router = new Router( app.atm, app.navFsm, app.views, app.models ); | ||
Backbone.history.start( { root: "/example/atm/" } ); | ||
} ); | ||
|
||
app.atm.on( "Authorized", function( data ) { | ||
app.models.accountInfo = new AccountInfo( { id: data.acct } ); | ||
app.views.main.model.set( "currentAccount", data.acct ); //TODO = needed? | ||
window.location.hash = "account"; | ||
} ); | ||
|
||
app.atm.on( "UnAuthorized", function() { | ||
window.location.hash = "unauthorized"; | ||
} ); | ||
app.atm.on( "Result", function( data ) { | ||
app.models.accountInfo.fetch(); | ||
window.location.hash = "result/" + data.resultId; | ||
} ); | ||
|
||
return app; | ||
}; | ||
|
||
$( function() { | ||
window.atmApp = new AtmApplication( '#content' ); | ||
window.atmApp.start(); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
var AccountInfo = Backbone.Model.extend( { | ||
defaults : { | ||
modelType : "accountInfo", | ||
name : "", | ||
balance : 0, | ||
limit : 0 | ||
}, | ||
|
||
initialize : function () { | ||
this.fetch(); | ||
} | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var AccountModel = Backbone.Model.extend( { | ||
defaults : { | ||
modelType : "account", | ||
name : "", | ||
balance : 0, | ||
limit : 0 | ||
}, | ||
initialize : function () { | ||
|
||
} | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
var AppModel = Backbone.Model.extend( { | ||
title : "Contrived ATM Example" | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
var DepositModel = Backbone.Model.extend( { | ||
defaults : { | ||
amount : 0, | ||
error : "" | ||
} | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var LoginModel = Backbone.Model.extend( { | ||
defaults : { | ||
acct : "", | ||
pin : "", | ||
error : "" | ||
} | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
var ResultModel = Backbone.Model.extend( { | ||
defaults : { | ||
modelType : "result" | ||
} | ||
} ); |
Oops, something went wrong.