Skip to content

Commit 06f9e42

Browse files
committed
Adding Examples from Repo
1 parent 99013f2 commit 06f9e42

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3190
-11
lines changed

example/atm/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ATM Example
2+
3+
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.
4+
5+
There are two sets of credentials that will work with this sample app:
6+
7+
* acct 123456789, pin 8675
8+
* acct 987654321, pin 3090
9+
10+
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.
11+
12+
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.

example/atm/index.html

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE HTML>
2+
<html lang="en-US">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>ATM State Machine Example</title>
6+
<link rel="stylesheet" type="text/css" href="style.css">
7+
<script type="text/javascript" src="../../bower/lodash/dist/lodash.js"></script>
8+
<script type="text/javascript" src="../../bower/jquery/jquery.min.js"></script>
9+
<script type="text/javascript" src="../../bower/backbone/backbone-min.js"></script>
10+
<script type="text/javascript" src="/ext/infuser_all.js"></script>
11+
<script type="text/javascript" src="../../bower/amplify/lib/amplify.js"></script>
12+
<script type="text/javascript" src="js/amplify.diagnostics.js"></script>
13+
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/machina.js/1.1.0/machina.js"></script>
14+
<script type="text/javascript" src="../../bower/accounting/accounting.js"></script>
15+
<script type="text/javascript" src="js/appConfig.js"></script>
16+
<script type="text/javascript" src="js/Repository.js"></script>
17+
<script type="text/javascript" src="js/router.js"></script>
18+
<script type="text/javascript" src="js/AtmFsm.js"></script>
19+
<script type="text/javascript" src="js/NavFsm.js"></script>
20+
<script type="text/javascript" src="js/models/AppModel.js"></script>
21+
<script type="text/javascript" src="js/models/AccountInfo.js"></script>
22+
<script type="text/javascript" src="js/models/LoginModel.js"></script>
23+
<script type="text/javascript" src="js/models/DepositModel.js"></script>
24+
<script type="text/javascript" src="js/models/WithdrawalModel.js"></script>
25+
<script type="text/javascript" src="js/models/ResultModel.js"></script>
26+
<script type="text/javascript" src="js/views/AccountView.js"></script>
27+
<script type="text/javascript" src="js/views/ResultView.js"></script>
28+
<script type="text/javascript" src="js/views/DepositView.js"></script>
29+
<script type="text/javascript" src="js/views/WithdrawalView.js"></script>
30+
<script type="text/javascript" src="js/views/LoginView.js"></script>
31+
<script type="text/javascript" src="js/views/NavView.js"></script>
32+
<script type="text/javascript" src="js/views/AppView.js"></script>
33+
<script type="text/javascript" src="js/main.js"></script>
34+
</head>
35+
<body>
36+
<div id="container">
37+
<div id="content"></div>
38+
</div>
39+
</body>
40+
</html>

example/atm/js/AtmFsm.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
This FSM generates the following custom events:
3+
"Initialized",
4+
"Authorized",
5+
"UnAuthorized",
6+
"Deposit",
7+
"Withdrawal",
8+
"OverLimit",
9+
"Result"
10+
*/
11+
var Atm = function() {
12+
var fsm;
13+
fsm = new machina.Fsm( {
14+
initialState: "uninitialized",
15+
states: {
16+
"uninitialized": {
17+
"initialize": function() {
18+
// TODO: any other init work here...
19+
this.emit( "Initialized" );
20+
this.transition( "unauthorized" );
21+
}
22+
},
23+
"unauthorized": {
24+
_onEnter: function() {
25+
this.emit( "UnAuthorized", { msg: "Please enter your account and PIN." } );
26+
},
27+
"*": function() {
28+
this.emit( "UnAuthorized", { msg: "You must authenticate first." } );
29+
},
30+
authorize: function( credentials ) {
31+
if ( authRepository.authorize( credentials.acct, credentials.pin ) ) {
32+
this.acct = credentials.acct;
33+
this.transition( "authorized" );
34+
return;
35+
}
36+
this.emit( "UnAuthorized", { msg: "Invalid Account and/or PIN." } );
37+
}
38+
},
39+
"authorized": {
40+
_onEnter: function() {
41+
this.emit( "Authorized", { acct: this.acct } );
42+
},
43+
deposit: function( amount ) {
44+
var result = clientRepository.deposit( this.acct, amount );
45+
this.emit( "Result", result );
46+
},
47+
withdrawal: function( amount ) {
48+
var result = clientRepository.withdrawal( this.acct, amount );
49+
this.emit( "Result", result );
50+
},
51+
deauthorize: function() {
52+
authRepository.deauthorize( this.acct );
53+
delete this.acct;
54+
this.transition( "unauthorized" );
55+
}
56+
}
57+
}
58+
} );
59+
return fsm;
60+
};

example/atm/js/NavFsm.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
var NavFsm = function( appFsm, navView ) {
2+
var fsm = new machina.Fsm( {
3+
initialState: "unauthorized",
4+
states: {
5+
"unauthorized": {
6+
_onEnter: function() {
7+
navView.unAuthLayout();
8+
},
9+
"*": function() {
10+
navView.unAuthLayout();
11+
}
12+
},
13+
"authorized": {
14+
"*": function() {
15+
navView.authLayout();
16+
},
17+
"deposit": function() {
18+
navView.depositLayout();
19+
},
20+
"withdrawal": function() {
21+
navView.withdrawalLayout();
22+
}
23+
}
24+
}
25+
} );
26+
appFsm.on( "Authorized", function() {
27+
fsm.transition( "authorized" );
28+
} );
29+
appFsm.on( "UnAuthorized", function() {
30+
fsm.transition( "unauthorized" );
31+
} );
32+
return fsm;
33+
};

example/atm/js/Repository.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
var clientRepository, authRepository, resources, accounts, currentAcct;
2+
( function( _ ) {
3+
var results = { };
4+
accounts = {
5+
"123456789": {
6+
pin: "8675",
7+
name: "Elwin Ransom",
8+
limit: 20000,
9+
balance: 100000
10+
},
11+
"987654321": {
12+
pin: "3090",
13+
name: "Edward Weston",
14+
limit: 400,
15+
balance: 300
16+
}
17+
};
18+
authRepository = {
19+
authorize: function( acct, pin ) {
20+
var authed = accounts[acct] && accounts[acct].pin === pin;
21+
if ( authed ) {
22+
currentAcct = acct;
23+
return true;
24+
}
25+
return false;
26+
},
27+
28+
deauthorize: function( acct ) {
29+
if ( currentAcct === acct ) {
30+
currentAcct = undefined;
31+
return true;
32+
}
33+
return false;
34+
}
35+
};
36+
clientRepository = {
37+
withdrawal: function( acct, amount ) {
38+
var current = accounts[currentAcct],
39+
newBal = current.balance - amount,
40+
result = {
41+
status: ( amount > current.limit ) ? "OverLimit" : ( newBal < 0 ) ? "InsufficientFunds" : "Successful",
42+
transactionAmount: amount
43+
};
44+
if ( result.status === "Successful" )
45+
current.balance = newBal;
46+
if ( !results[acct] ) {
47+
results[acct] = [];
48+
}
49+
results[acct].push( $.extend( true, { transactionType: "Withdrawal" }, accounts[ currentAcct ], result ) );
50+
return { acct: acct, resultId: results[acct].length - 1 };
51+
},
52+
deposit: function( acct, amount ) {
53+
accounts[ currentAcct ].balance += amount;
54+
if ( !results[acct] ) {
55+
results[acct] = [];
56+
}
57+
results[acct].push( $.extend( true, { transactionType: "Deposit" }, accounts[ currentAcct ], { status: "Successful", transactionAmount: amount } ) );
58+
return { acct: acct, resultId: results[acct].length - 1 };
59+
}
60+
};
61+
resources = {
62+
result: {
63+
read: function( model, options ) {
64+
options.success( results[model.acct][model.id] );
65+
}
66+
},
67+
accountInfo: {
68+
read: function( model, options ) {
69+
options.success( accounts[model.id] );
70+
}
71+
}
72+
};
73+
74+
Backbone.sync = function( method, model, options ) {
75+
var modelType = model.get( "modelType" );
76+
resources[modelType][method]( model.toJSON(), options );
77+
};
78+
} )( _ );

example/atm/js/amplify.diagnostics.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var orig = amplify.publish;
2+
3+
amplify.publish = function( topic, message ) {
4+
try {
5+
console.log( topic + " " + JSON.stringify( message ) );
6+
}
7+
catch ( exception ) {
8+
console.log( topic + " (unable to serialize payload)" );
9+
}
10+
orig.call( this, topic, message );
11+
}

example/atm/js/appConfig.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
( function( $, _, infuser, undefined ) {
2+
var infuserDefault = infuser.defaults;
3+
4+
infuser.defaults = $.extend( true, infuserDefault, {
5+
templateUrl: "/example/atm/templates",
6+
bindingInstruction: function( template, model ) {
7+
return template( model );
8+
},
9+
render: function( target, template ) {
10+
$( target ).html( template );
11+
},
12+
useLoadingTemplate: false,
13+
templatePreProcessor: function( template ) {
14+
return _.template( template );
15+
}
16+
} );
17+
} )( jQuery, _, infuser );

example/atm/js/main.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
var AtmApplication = function( target ) {
2+
//----------------------------------------------------------------------------
3+
//
4+
// The top level application object
5+
//
6+
//----------------------------------------------------------------------------
7+
var app = {
8+
atm: new Atm(),
9+
models: {
10+
accountInfo: undefined
11+
},
12+
views: {
13+
main: new AppView( { target: target } ),
14+
nav: new NavView(),
15+
login: new LoginView( { target: "#screen" } ),
16+
account: new AccountView( { target: "#screen" } ),
17+
deposit: new DepositView( { target: "#screen" } ),
18+
result: new ResultView( { target: "#screen" } ),
19+
withdrawal: new WithdrawalView( { target: "#screen" } )
20+
},
21+
start: function() {
22+
this.atm.handle( "initialize" );
23+
}
24+
};
25+
26+
app.navFsm = new NavFsm( app.atm, app.views.nav );
27+
28+
//----------------------------------------------------------------------------
29+
//
30+
// Handlers for View Events
31+
//
32+
//----------------------------------------------------------------------------
33+
app.views.main.on( "AppRendered", function() {
34+
app.views.nav.render( app.views.nav.unAuthLayout );
35+
} );
36+
37+
app.views.login.on( "Authenticate", function( model ) {
38+
app.atm.handle( "authorize", model );
39+
} );
40+
41+
app.views.deposit.on( "Deposit", function( amount ) {
42+
app.atm.handle( "deposit", amount );
43+
} );
44+
45+
app.views.withdrawal.on( "Withdrawal", function( amount ) {
46+
app.atm.handle( "withdrawal", amount );
47+
} );
48+
49+
//----------------------------------------------------------------------------
50+
//
51+
// Handlers for App FSM Events
52+
//
53+
//----------------------------------------------------------------------------
54+
app.atm.on( "Initialized", function() {
55+
app.views.main.render();
56+
app.router = new Router( app.atm, app.navFsm, app.views, app.models );
57+
Backbone.history.start( { root: "/example/atm/" } );
58+
} );
59+
60+
app.atm.on( "Authorized", function( data ) {
61+
app.models.accountInfo = new AccountInfo( { id: data.acct } );
62+
app.views.main.model.set( "currentAccount", data.acct ); //TODO = needed?
63+
window.location.hash = "account";
64+
} );
65+
66+
app.atm.on( "UnAuthorized", function() {
67+
window.location.hash = "unauthorized";
68+
} );
69+
app.atm.on( "Result", function( data ) {
70+
app.models.accountInfo.fetch();
71+
window.location.hash = "result/" + data.resultId;
72+
} );
73+
74+
return app;
75+
};
76+
77+
$( function() {
78+
window.atmApp = new AtmApplication( '#content' );
79+
window.atmApp.start();
80+
} );

example/atm/js/models/AccountInfo.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
var AccountInfo = Backbone.Model.extend( {
2+
defaults : {
3+
modelType : "accountInfo",
4+
name : "",
5+
balance : 0,
6+
limit : 0
7+
},
8+
9+
initialize : function () {
10+
this.fetch();
11+
}
12+
} );

example/atm/js/models/AccountModel.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
var AccountModel = Backbone.Model.extend( {
2+
defaults : {
3+
modelType : "account",
4+
name : "",
5+
balance : 0,
6+
limit : 0
7+
},
8+
initialize : function () {
9+
10+
}
11+
} );

0 commit comments

Comments
 (0)