Let the thread to be managed outside the binding.
[apps/agl-service-can-low-level.git] / CAN-binder / low-can-demo / app / Frontend / js / AFB.js
1 AFB = function(base, initialtoken){
2
3 var urlws = "ws://"+window.location.host+"/"+base;
4 var urlhttp = "http://"+window.location.host+"/"+base;
5
6 /*********************************************/
7 /****                                     ****/
8 /****             AFB_context             ****/
9 /****                                     ****/
10 /*********************************************/
11 var AFB_context = (function() {
12         var UUID;
13         var TOKEN = initialtoken;
14
15         var context = function(token, uuid) {
16                 this.token = token;
17                 this.uuid = uuid;
18         };
19
20         context.prototype = {
21                 get token() {return TOKEN;},
22                 set token(tok) {if(tok) TOKEN=tok;},
23                 get uuid() {return UUID;},
24                 set uuid(id) {if(id) UUID=id;}
25         };
26
27         return new context();
28 })();
29 /*********************************************/
30 /****                                     ****/
31 /****             AFB_websocket           ****/
32 /****                                     ****/
33 /*********************************************/
34 var AFB_websocket = (function() {
35         var CALL = 2;
36         var RETOK = 3;
37         var RETERR = 4;
38         var EVENT = 5;
39
40         var PROTO1 = "x-afb-ws-json1";
41
42         var result = function(onopen, onabort) {
43                 var u = urlws;
44                 if (AFB_context.token) {
45                         u = u + '?x-afb-token=' + AFB_context.token;
46                         if (AFB_context.uuid)
47                                 u = u + '&x-afb-uuid=' + AFB_context.uuid;
48                 }
49                 this.ws = new WebSocket(u, [ PROTO1 ]);
50                 this.pendings = {};
51                 this.awaitens = {};
52                 this.counter = 0;
53                 this.ws.onopen = onopen.bind(this);
54                 this.ws.onerror = onerror.bind(this);
55                 this.ws.onclose = onclose.bind(this);
56                 this.ws.onmessage = onmessage.bind(this);
57                 this.onopen = onopen;
58                 this.onabort = onabort;
59         };
60
61         function onerror(event) {
62                 var f = this.onabort;
63                 if (f) {
64                         delete this.onopen;
65                         delete this.onabort;
66                         f && f(this);
67                 }
68                 this.onerror && this.onerror(this);
69         }
70
71         function onopen(event) {
72                 var f = this.onopen;
73                 delete this.onopen;
74                 delete this.onabort;
75                 f && f(this);
76         }
77
78         function onclose(event) {
79                 for (var id in this.pendings) {
80                         var ferr = this.pendings[id].onerror;
81                         ferr && ferr(null, this);
82                 }
83                 this.pendings = {};
84                 this.onclose && this.onclose();
85         }
86
87         function fire(awaitens, name, data) {
88                 var a = awaitens[name];
89                 if (a)
90                         a.forEach(function(handler){handler(data);});
91                 var i = name.indexOf("/");
92                 if (i >= 0) {
93                         a = awaitens[name.substring(0,i)];
94                         if (a)
95                                 a.forEach(function(handler){handler(data);});
96                 }
97                 a = awaitens["*"];
98                 if (a)
99                         a.forEach(function(handler){handler(data);});
100         }
101
102         function reply(pendings, id, ans, offset) {
103                 if (id in pendings) {
104                         var p = pendings[id];
105                         delete pendings[id];
106                         var f = p[offset];
107                         f && f(ans);
108                 }
109         }
110
111         function onmessage(event) {
112                 var obj = JSON.parse(event.data);
113                 var code = obj[0];
114                 var id = obj[1];
115                 var ans = obj[2];
116                 AFB_context.token = obj[3];
117                 switch (code) {
118                 case RETOK:
119                         reply(this.pendings, id, ans, 0);
120                         break; 
121                 case RETERR:
122                         reply(this.pendings, id, ans, 1);
123                         break; 
124                 case EVENT:
125                 default:
126                         fire(this.awaitens, id, ans);
127                         break; 
128                 }
129         }
130
131         function close() {
132                 this.ws.close();
133         }
134
135         function call(method, request, onsuccess, onfailure) {
136                 var id, arr;
137                 do {
138                         id = String(this.counter = 4095 & (this.counter + 1));
139                 } while (id in this.pendings);
140                 this.pendings[id] = [ onsuccess, onfailure ];
141                 arr = [CALL, id, method, request ];
142                 if (AFB_context.token) arr.push(AFB_context.token);
143                 this.ws.send(JSON.stringify(arr));
144         }
145
146         function onevent(name, handler) {
147                 var id = name;
148                 var list = this.awaitens[id] || (this.awaitens[id] = []);
149                 list.push(handler);
150         }
151
152         result.prototype = {
153                 close: close,
154                 call: call,
155                 onevent: onevent
156         };
157
158         return result;
159 })();
160 /*********************************************/
161 /****                                     ****/
162 /****                                     ****/
163 /****                                     ****/
164 /*********************************************/
165 return {
166         context: AFB_context,
167         ws: AFB_websocket
168 };
169 };
170