debugging_environment.js 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858
  1. /**
  2. * Statechart compiler by Glenn De Jonghe
  3. * Javascript generator by Joeri Exelmans
  4. *
  5. * Date: Fri Apr 08 11:44:57 2016
  6. *
  7. * Model author: Simon Van Mierlo
  8. * Model name: DebuggingEnvironment
  9. * Model description:
  10. Debugging environment for Dynamic Structure DEVS in HTML + JS (d3/w2ui).
  11. */
  12. // put everything in an object (serves as "namespace")
  13. DebuggingEnvironment = {};
  14. // closure scope
  15. (function() {
  16. // The actual constructor
  17. var MainApp = function(controller) {
  18. MainApp.prototype.commonConstructor.call(this,controller);
  19. // constructor body (user-defined)
  20. };
  21. MainApp.prototype = new RuntimeClassBase();
  22. // Unique IDs for all statechart nodes
  23. MainApp.prototype.Root = 0;
  24. MainApp.prototype.Root_creating_toolbar = 1;
  25. MainApp.prototype.Root_creating_visualizer = 2;
  26. MainApp.prototype.Root_running = 3;
  27. // Statechart enter/exit action method(s) :
  28. MainApp.prototype.enter_Root_creating_toolbar = function() {
  29. this.object_manager.addEvent(new Event("create_instance", null, [this, 'toolbar','DebuggingToolbar']));
  30. this.current_state[this.Root].push(this.Root_creating_toolbar);
  31. };
  32. MainApp.prototype.exit_Root_creating_toolbar = function() {
  33. this.current_state[this.Root] = new Array();
  34. };
  35. MainApp.prototype.enter_Root_creating_visualizer = function() {
  36. this.object_manager.addEvent(new Event("create_instance", null, [this, 'visualizer','Visualizer']));
  37. this.current_state[this.Root].push(this.Root_creating_visualizer);
  38. };
  39. MainApp.prototype.exit_Root_creating_visualizer = function() {
  40. this.current_state[this.Root] = new Array();
  41. };
  42. MainApp.prototype.enter_Root_running = function() {
  43. this.current_state[this.Root].push(this.Root_running);
  44. };
  45. MainApp.prototype.exit_Root_running = function() {
  46. this.current_state[this.Root] = new Array();
  47. };
  48. // Statechart transitions :
  49. MainApp.prototype.transition_Root = function(event) {
  50. var catched = false;
  51. if (!catched) {
  52. if (this.current_state[this.Root][0] === this.Root_creating_toolbar) {
  53. catched = this.transition_Root_creating_toolbar(event);
  54. }
  55. else if (this.current_state[this.Root][0] === this.Root_creating_visualizer) {
  56. catched = this.transition_Root_creating_visualizer(event);
  57. }
  58. else if (this.current_state[this.Root][0] === this.Root_running) {
  59. catched = this.transition_Root_running(event);
  60. }
  61. }
  62. return catched;
  63. };
  64. MainApp.prototype.transition_Root_creating_toolbar = function(event) {
  65. var catched = false;
  66. var enableds = new Array();
  67. if (event.name === "instance_created") {
  68. enableds.push(1);
  69. }
  70. if (enableds.length > 1) {
  71. console.log("Runtime warning : indeterminism detected in a transition from node Root_creating_toolbar. Only the first in document order enabled transition is executed.")
  72. }
  73. if (enableds.length > 0) {
  74. var enabled = enableds[0];
  75. if (enabled === 1) {
  76. var parameters = event.parameters;
  77. var association_name = parameters[0];
  78. this.exit_Root_creating_toolbar();
  79. this.object_manager.addEvent(new Event("start_instance", null, [this, association_name]));
  80. this.enter_Root_creating_visualizer();
  81. }
  82. catched = true;
  83. }
  84. return catched;
  85. };
  86. MainApp.prototype.transition_Root_creating_visualizer = function(event) {
  87. var catched = false;
  88. var enableds = new Array();
  89. if (event.name === "instance_created") {
  90. enableds.push(1);
  91. }
  92. if (enableds.length > 1) {
  93. console.log("Runtime warning : indeterminism detected in a transition from node Root_creating_visualizer. Only the first in document order enabled transition is executed.")
  94. }
  95. if (enableds.length > 0) {
  96. var enabled = enableds[0];
  97. if (enabled === 1) {
  98. var parameters = event.parameters;
  99. var association_name = parameters[0];
  100. this.exit_Root_creating_visualizer();
  101. this.object_manager.addEvent(new Event("start_instance", null, [this, association_name]));
  102. this.enter_Root_running();
  103. }
  104. catched = true;
  105. }
  106. return catched;
  107. };
  108. MainApp.prototype.transition_Root_running = function(event) {
  109. var catched = false;
  110. return catched;
  111. };
  112. // Execute transitions
  113. MainApp.prototype.transition = function(event) {
  114. if (!event) event = new Event();
  115. this.state_changed = this.transition_Root(event);
  116. };
  117. // inState method for statechart
  118. MainApp.prototype.inState = function(nodes) {
  119. for (var c in this.current_state) {
  120. if (!this.current_state.hasOwnProperty(c)) continue;
  121. var new_nodes = new Array();
  122. for (var n in nodes) {
  123. if (!nodes.hasOwnProperty(n)) continue;
  124. if (this.current_state[c].indexOf(nodes[n]) === -1) {
  125. new_nodes.push(nodes[n]);
  126. }
  127. }
  128. nodes = new_nodes;
  129. if (nodes.length === 0) {
  130. return true;
  131. }
  132. }
  133. return false;
  134. };
  135. MainApp.prototype.commonConstructor = function(controller) {
  136. if (!controller) controller = null;
  137. // Constructor part that is common for all constructors.
  138. RuntimeClassBase.call(this);
  139. // User defined input ports
  140. this.inports = new Object();
  141. this.controller = controller;
  142. this.object_manager = (controller == null ? null : controller.object_manager);
  143. this.current_state = new Object();
  144. this.history_state = new Object();
  145. // Initialize statechart
  146. this.current_state[this.Root] = new Array();
  147. };
  148. MainApp.prototype.start = function() {
  149. RuntimeClassBase.prototype.start.call(this);
  150. this.enter_Root_creating_toolbar();
  151. };
  152. // put class in global diagram object
  153. DebuggingEnvironment.MainApp = MainApp;
  154. // The actual constructor
  155. var DebuggingToolbar = function(controller) {
  156. DebuggingToolbar.prototype.commonConstructor.call(this,controller);
  157. // constructor body (user-defined)
  158. this.parameters = {};
  159. this.buttons = {};
  160. this.curr_parameter = null;
  161. this.button_counter = 0;
  162. this.buttons_to_create = [{parent: this, description: 'Simulate', icon: 'simulate', command: 'simulate'},
  163. {parent: this, description: 'Realtime Simulate', icon: 'simulatert', command: 'realtime', parameter_needed: 'realtime_scale'},
  164. {parent: this, description: 'Realtime Scale', html: 'input size="1" value="1.0" style="border: 1px solid silver"', default: 1.0, parameter: 'realtime_scale'},
  165. {parent: this, description: 'Pause', icon: 'pause', command: 'pause'},
  166. {parent: this, description: 'Big Step', icon: 'bigstep', command: 'big_step'},
  167. {parent: this, description: 'Small Step', icon: 'smallstep', command: 'small_step'},
  168. {parent: this, description: 'Reset', icon: 'reset', command: 'reset'},
  169. {parent: this, description: 'Add Breakpoint', icon: 'breakpoint', action: function() {breakpoint_dialog.dialog( "open" );}}];
  170. this.tb = ui.create_toolbar('DebuggingToolbar');
  171. };
  172. DebuggingToolbar.prototype = new RuntimeClassBase();
  173. // Unique IDs for all statechart nodes
  174. DebuggingToolbar.prototype.Root = 0;
  175. DebuggingToolbar.prototype.Root_initializing = 1;
  176. DebuggingToolbar.prototype.Root_initializing_check = 2;
  177. DebuggingToolbar.prototype.Root_initializing_creating_button = 3;
  178. DebuggingToolbar.prototype.Root_initializing_running = 4;
  179. DebuggingToolbar.prototype.Root_initializing_getting_parameter = 5;
  180. // Statechart enter/exit action method(s) :
  181. DebuggingToolbar.prototype.enter_Root_initializing = function() {
  182. this.current_state[this.Root].push(this.Root_initializing);
  183. };
  184. DebuggingToolbar.prototype.exit_Root_initializing = function() {
  185. if (this.current_state[this.Root_initializing].indexOf(this.Root_initializing_check) !== -1) {
  186. this.exit_Root_initializing_check();
  187. }
  188. if (this.current_state[this.Root_initializing].indexOf(this.Root_initializing_creating_button) !== -1) {
  189. this.exit_Root_initializing_creating_button();
  190. }
  191. if (this.current_state[this.Root_initializing].indexOf(this.Root_initializing_running) !== -1) {
  192. this.exit_Root_initializing_running();
  193. }
  194. if (this.current_state[this.Root_initializing].indexOf(this.Root_initializing_getting_parameter) !== -1) {
  195. this.exit_Root_initializing_getting_parameter();
  196. }
  197. this.current_state[this.Root] = new Array();
  198. };
  199. DebuggingToolbar.prototype.enter_Root_initializing_check = function() {
  200. this.current_state[this.Root_initializing].push(this.Root_initializing_check);
  201. };
  202. DebuggingToolbar.prototype.exit_Root_initializing_check = function() {
  203. this.current_state[this.Root_initializing] = new Array();
  204. };
  205. DebuggingToolbar.prototype.enter_Root_initializing_creating_button = function() {
  206. this.current_state[this.Root_initializing].push(this.Root_initializing_creating_button);
  207. };
  208. DebuggingToolbar.prototype.exit_Root_initializing_creating_button = function() {
  209. this.current_state[this.Root_initializing] = new Array();
  210. };
  211. DebuggingToolbar.prototype.enter_Root_initializing_running = function() {
  212. this.current_state[this.Root_initializing].push(this.Root_initializing_running);
  213. };
  214. DebuggingToolbar.prototype.exit_Root_initializing_running = function() {
  215. this.current_state[this.Root_initializing] = new Array();
  216. };
  217. DebuggingToolbar.prototype.enter_Root_initializing_getting_parameter = function() {
  218. this.current_state[this.Root_initializing].push(this.Root_initializing_getting_parameter);
  219. };
  220. DebuggingToolbar.prototype.exit_Root_initializing_getting_parameter = function() {
  221. this.current_state[this.Root_initializing] = new Array();
  222. };
  223. // Statechart enter/exit default method(s) :
  224. DebuggingToolbar.prototype.enterDefault_Root_initializing = function() {
  225. this.enter_Root_initializing();
  226. this.enter_Root_initializing_check();
  227. };
  228. // Statechart transitions :
  229. DebuggingToolbar.prototype.transition_Root = function(event) {
  230. var catched = false;
  231. if (!catched) {
  232. if (this.current_state[this.Root][0] === this.Root_initializing) {
  233. catched = this.transition_Root_initializing(event);
  234. }
  235. }
  236. return catched;
  237. };
  238. DebuggingToolbar.prototype.transition_Root_initializing = function(event) {
  239. var catched = false;
  240. if (!catched) {
  241. if (this.current_state[this.Root_initializing][0] === this.Root_initializing_check) {
  242. catched = this.transition_Root_initializing_check(event);
  243. }
  244. else if (this.current_state[this.Root_initializing][0] === this.Root_initializing_creating_button) {
  245. catched = this.transition_Root_initializing_creating_button(event);
  246. }
  247. else if (this.current_state[this.Root_initializing][0] === this.Root_initializing_running) {
  248. catched = this.transition_Root_initializing_running(event);
  249. }
  250. else if (this.current_state[this.Root_initializing][0] === this.Root_initializing_getting_parameter) {
  251. catched = this.transition_Root_initializing_getting_parameter(event);
  252. }
  253. }
  254. return catched;
  255. };
  256. DebuggingToolbar.prototype.transition_Root_initializing_check = function(event) {
  257. var catched = false;
  258. var enableds = new Array();
  259. if (this.buttons_to_create.length > 0) {
  260. enableds.push(1);
  261. }
  262. if (this.buttons_to_create.length == 0) {
  263. enableds.push(2);
  264. }
  265. if (enableds.length > 1) {
  266. console.log("Runtime warning : indeterminism detected in a transition from node Root_initializing_check. Only the first in document order enabled transition is executed.")
  267. }
  268. if (enableds.length > 0) {
  269. var enabled = enableds[0];
  270. if (enabled === 1) {
  271. this.exit_Root_initializing_check();
  272. if ('parameter' in this.buttons_to_create[0]) {
  273. this.curr_parameter = this.buttons_to_create[0]['parameter']
  274. }
  275. this.object_manager.addEvent(new Event("create_instance", null, [this, 'buttons','Button','button' + this.button_counter,this.tb,this.buttons_to_create.shift()]));
  276. this.enter_Root_initializing_creating_button();
  277. }
  278. else if (enabled === 2) {
  279. this.exit_Root_initializing_check();
  280. this.enter_Root_initializing_running();
  281. }
  282. catched = true;
  283. }
  284. return catched;
  285. };
  286. DebuggingToolbar.prototype.transition_Root_initializing_creating_button = function(event) {
  287. var catched = false;
  288. var enableds = new Array();
  289. if (event.name === "instance_created") {
  290. enableds.push(1);
  291. }
  292. if (enableds.length > 1) {
  293. console.log("Runtime warning : indeterminism detected in a transition from node Root_initializing_creating_button. Only the first in document order enabled transition is executed.")
  294. }
  295. if (enableds.length > 0) {
  296. var enabled = enableds[0];
  297. if (enabled === 1) {
  298. var parameters = event.parameters;
  299. var association_name = parameters[0];
  300. this.exit_Root_initializing_creating_button();
  301. this.object_manager.addEvent(new Event("start_instance", null, [this, association_name]));
  302. if (this.curr_parameter) {
  303. this.parameters[this.curr_parameter] = association_name;
  304. this.curr_parameter = null;
  305. }
  306. this.buttons['button' + this.button_counter] = association_name;
  307. this.button_counter += 1;
  308. this.enter_Root_initializing_check();
  309. }
  310. catched = true;
  311. }
  312. return catched;
  313. };
  314. DebuggingToolbar.prototype.transition_Root_initializing_running = function(event) {
  315. var catched = false;
  316. var enableds = new Array();
  317. if (event.name === "get_parameter") {
  318. enableds.push(1);
  319. }
  320. if (enableds.length > 1) {
  321. console.log("Runtime warning : indeterminism detected in a transition from node Root_initializing_running. Only the first in document order enabled transition is executed.")
  322. }
  323. if (enableds.length > 0) {
  324. var enabled = enableds[0];
  325. if (enabled === 1) {
  326. var parameters = event.parameters;
  327. var the_parameter = parameters[0];
  328. var respond_id = parameters[1];
  329. this.exit_Root_initializing_running();
  330. var send_event = new Event("get_parameter", null, []);
  331. this.object_manager.addEvent(new Event("narrow_cast", null, [this, this.parameters[the_parameter] , send_event]));
  332. this.respond_id = respond_id;
  333. this.enter_Root_initializing_getting_parameter();
  334. }
  335. catched = true;
  336. }
  337. return catched;
  338. };
  339. DebuggingToolbar.prototype.transition_Root_initializing_getting_parameter = function(event) {
  340. var catched = false;
  341. var enableds = new Array();
  342. if (event.name === "parameter_reply") {
  343. enableds.push(1);
  344. }
  345. if (enableds.length > 1) {
  346. console.log("Runtime warning : indeterminism detected in a transition from node Root_initializing_getting_parameter. Only the first in document order enabled transition is executed.")
  347. }
  348. if (enableds.length > 0) {
  349. var enabled = enableds[0];
  350. if (enabled === 1) {
  351. var parameters = event.parameters;
  352. var parameter_value = parameters[0];
  353. this.exit_Root_initializing_getting_parameter();
  354. var send_event = new Event("parameter_reply", null, [parameter_value]);
  355. this.object_manager.addEvent(new Event("narrow_cast", null, [this, this.buttons[this.respond_id] , send_event]));
  356. this.enter_Root_initializing_running();
  357. }
  358. catched = true;
  359. }
  360. return catched;
  361. };
  362. // Execute transitions
  363. DebuggingToolbar.prototype.transition = function(event) {
  364. if (!event) event = new Event();
  365. this.state_changed = this.transition_Root(event);
  366. };
  367. // inState method for statechart
  368. DebuggingToolbar.prototype.inState = function(nodes) {
  369. for (var c in this.current_state) {
  370. if (!this.current_state.hasOwnProperty(c)) continue;
  371. var new_nodes = new Array();
  372. for (var n in nodes) {
  373. if (!nodes.hasOwnProperty(n)) continue;
  374. if (this.current_state[c].indexOf(nodes[n]) === -1) {
  375. new_nodes.push(nodes[n]);
  376. }
  377. }
  378. nodes = new_nodes;
  379. if (nodes.length === 0) {
  380. return true;
  381. }
  382. }
  383. return false;
  384. };
  385. DebuggingToolbar.prototype.commonConstructor = function(controller) {
  386. if (!controller) controller = null;
  387. // Constructor part that is common for all constructors.
  388. RuntimeClassBase.call(this);
  389. // User defined input ports
  390. this.inports = new Object();
  391. this.controller = controller;
  392. this.object_manager = (controller == null ? null : controller.object_manager);
  393. this.current_state = new Object();
  394. this.history_state = new Object();
  395. // Initialize statechart
  396. this.current_state[this.Root] = new Array();
  397. this.current_state[this.Root_initializing] = new Array();
  398. };
  399. DebuggingToolbar.prototype.start = function() {
  400. RuntimeClassBase.prototype.start.call(this);
  401. this.enterDefault_Root_initializing();
  402. };
  403. // put class in global diagram object
  404. DebuggingEnvironment.DebuggingToolbar = DebuggingToolbar;
  405. // The actual constructor
  406. var Button = function(controller, button_id, toolbar, parameters) {
  407. Button.prototype.commonConstructor.call(this,controller);
  408. // constructor body (user-defined)
  409. this.button_id = button_id;
  410. this.toolbar = toolbar;
  411. this.action = null;
  412. this.command = null;
  413. if ('parameter_needed' in parameters) {
  414. this.parameter_needed = parameters['parameter_needed'];
  415. } else {
  416. this.parameter_needed = null;
  417. }
  418. if ('html' in parameters) {
  419. var the_html = parameters['html']
  420. the_html += ' id="' + this.button_id + '_input" onchange="ui.parameter_changed(\'' + button_id + '\');"'
  421. this.btn = ui.create_tb_element(this.button_id, '<' + the_html + ' />', parameters['default'], this.toolbar, this.controller, this.inports['button_ui_input']);
  422. } else if ('action' in parameters) {
  423. this.action = parameters['action'];
  424. this.btn = ui.create_button(this.button_id, parameters['description'], parameters['icon'], this.toolbar, this.controller, this.inports['button_ui_input']);
  425. } else {
  426. this.command = parameters['command'];
  427. this.btn = ui.create_button(this.button_id, parameters['description'], parameters['icon'], this.toolbar, this.controller, this.inports['button_ui_input']);
  428. }
  429. };
  430. Button.prototype = new RuntimeClassBase();
  431. // Unique IDs for all statechart nodes
  432. Button.prototype.Root = 0;
  433. Button.prototype.Root_listening = 1;
  434. Button.prototype.Root_getting_parameter = 2;
  435. // Statechart enter/exit action method(s) :
  436. Button.prototype.enter_Root_listening = function() {
  437. this.current_state[this.Root].push(this.Root_listening);
  438. };
  439. Button.prototype.exit_Root_listening = function() {
  440. this.current_state[this.Root] = new Array();
  441. };
  442. Button.prototype.enter_Root_getting_parameter = function() {
  443. this.current_state[this.Root].push(this.Root_getting_parameter);
  444. };
  445. Button.prototype.exit_Root_getting_parameter = function() {
  446. this.current_state[this.Root] = new Array();
  447. };
  448. // Statechart transitions :
  449. Button.prototype.transition_Root = function(event) {
  450. var catched = false;
  451. if (!catched) {
  452. if (this.current_state[this.Root][0] === this.Root_listening) {
  453. catched = this.transition_Root_listening(event);
  454. }
  455. else if (this.current_state[this.Root][0] === this.Root_getting_parameter) {
  456. catched = this.transition_Root_getting_parameter(event);
  457. }
  458. }
  459. return catched;
  460. };
  461. Button.prototype.transition_Root_listening = function(event) {
  462. var catched = false;
  463. var enableds = new Array();
  464. if (event.name === "mouse_press" && event.port === "button_ui_input") {
  465. if (this.action) {
  466. enableds.push(1);
  467. }
  468. }
  469. if (event.name === "mouse_press" && event.port === "button_ui_input") {
  470. if (this.parameter_needed == null && this.command) {
  471. enableds.push(2);
  472. }
  473. }
  474. if (event.name === "mouse_press" && event.port === "button_ui_input") {
  475. if (this.parameter_needed != null && this.command) {
  476. enableds.push(3);
  477. }
  478. }
  479. if (event.name === "get_parameter") {
  480. enableds.push(4);
  481. }
  482. if (enableds.length > 1) {
  483. console.log("Runtime warning : indeterminism detected in a transition from node Root_listening. Only the first in document order enabled transition is executed.")
  484. }
  485. if (enableds.length > 0) {
  486. var enabled = enableds[0];
  487. if (enabled === 1) {
  488. this.exit_Root_listening();
  489. this.action();
  490. this.enter_Root_listening();
  491. }
  492. else if (enabled === 2) {
  493. this.exit_Root_listening();
  494. this.controller.outputEvent(new Event("debugging_command", "output", [this.command]));
  495. this.enter_Root_listening();
  496. }
  497. else if (enabled === 3) {
  498. this.exit_Root_listening();
  499. var send_event = new Event("get_parameter", null, [this.parameter_needed,this.button_id]);
  500. this.object_manager.addEvent(new Event("narrow_cast", null, [this, 'parent' , send_event]));
  501. this.enter_Root_getting_parameter();
  502. }
  503. else if (enabled === 4) {
  504. this.exit_Root_listening();
  505. var send_event = new Event("parameter_reply", null, [this.btn.value]);
  506. this.object_manager.addEvent(new Event("narrow_cast", null, [this, 'parent' , send_event]));
  507. this.enter_Root_listening();
  508. }
  509. catched = true;
  510. }
  511. return catched;
  512. };
  513. Button.prototype.transition_Root_getting_parameter = function(event) {
  514. var catched = false;
  515. var enableds = new Array();
  516. if (event.name === "parameter_reply") {
  517. enableds.push(1);
  518. }
  519. if (enableds.length > 1) {
  520. console.log("Runtime warning : indeterminism detected in a transition from node Root_getting_parameter. Only the first in document order enabled transition is executed.")
  521. }
  522. if (enableds.length > 0) {
  523. var enabled = enableds[0];
  524. if (enabled === 1) {
  525. var parameters = event.parameters;
  526. var the_parameter = parameters[0];
  527. this.exit_Root_getting_parameter();
  528. var the_parameters = {};
  529. the_parameters[this.parameter_needed] = the_parameter;
  530. this.controller.outputEvent(new Event("debugging_command", "output", [this.command,the_parameters]));
  531. this.enter_Root_listening();
  532. }
  533. catched = true;
  534. }
  535. return catched;
  536. };
  537. // Execute transitions
  538. Button.prototype.transition = function(event) {
  539. if (!event) event = new Event();
  540. this.state_changed = this.transition_Root(event);
  541. };
  542. // inState method for statechart
  543. Button.prototype.inState = function(nodes) {
  544. for (var c in this.current_state) {
  545. if (!this.current_state.hasOwnProperty(c)) continue;
  546. var new_nodes = new Array();
  547. for (var n in nodes) {
  548. if (!nodes.hasOwnProperty(n)) continue;
  549. if (this.current_state[c].indexOf(nodes[n]) === -1) {
  550. new_nodes.push(nodes[n]);
  551. }
  552. }
  553. nodes = new_nodes;
  554. if (nodes.length === 0) {
  555. return true;
  556. }
  557. }
  558. return false;
  559. };
  560. Button.prototype.commonConstructor = function(controller) {
  561. if (!controller) controller = null;
  562. // Constructor part that is common for all constructors.
  563. RuntimeClassBase.call(this);
  564. // User defined input ports
  565. this.inports = new Object();
  566. this.inports["button_ui_input"] = controller.addInputPort("button_ui_input", this);
  567. this.controller = controller;
  568. this.object_manager = (controller == null ? null : controller.object_manager);
  569. this.current_state = new Object();
  570. this.history_state = new Object();
  571. // Initialize statechart
  572. this.current_state[this.Root] = new Array();
  573. };
  574. Button.prototype.start = function() {
  575. RuntimeClassBase.prototype.start.call(this);
  576. this.enter_Root_listening();
  577. };
  578. // put class in global diagram object
  579. DebuggingEnvironment.Button = Button;
  580. // The actual constructor
  581. var Visualizer = function(controller) {
  582. Visualizer.prototype.commonConstructor.call(this,controller);
  583. // constructor body (user-defined)
  584. the_controller = this.controller;
  585. this.simulation_info = d3.select("body").append("div")
  586. .attr("class", "simulationInfo")
  587. .style("margin", "5px")
  588. .style("display", "block");
  589. this.simulation_time = this.simulation_info.append("span")
  590. .append("text")
  591. .text("SIMULATION TIME: (not started)")
  592. .style("float", "left");
  593. this.simulation_steps = this.simulation_info.append("span")
  594. .style("margin", "5px")
  595. .style("float", "left")
  596. .attr("class", "invisibleInfo")
  597. .attr("id", "smallStepInfo");
  598. this.simulation_steps.selectAll("div").data([0,1,2,3,4,5,6,7])
  599. .enter()
  600. .append("div")
  601. .attr("id", function(d) {return "smallStepInfo_" + d})
  602. .attr("class", "smallStepInfo inactive")
  603. .style("transform", function(d) {return "translate(" + d * 5 + "px, -4px) rotate(45deg)"});
  604. d3.select("body").append("br");
  605. this.breakpoint_info = d3.select("body").append("div")
  606. .attr("class", "breakpointInfo")
  607. .style("margin", "5px")
  608. .style("display", "block");
  609. this.breakpoint_text = this.breakpoint_info.append("span")
  610. .append("text")
  611. .text("BREAKPOINTS: ")
  612. .style("float", "left");
  613. this.breakpoint_infos = this.breakpoint_info.append("span")
  614. .style("margin", "5px")
  615. .style("float", "left")
  616. .attr("id", "breakpointInfos");
  617. this.breakpoints = [];
  618. this.data = [];
  619. this.port_connections = [];
  620. this.loc_to_item = {};
  621. event_to_inject = undefined;
  622. god_event_to_process = undefined;
  623. // TODO: this is domain-specific!
  624. this.particle_id_to_item = {};
  625. var margin = {top: 50, right: 0, bottom: 0, left: 0},
  626. width = 960 - margin.right - margin.left,
  627. height = 1024 - margin.top - margin.bottom;
  628. this.node_id = 0;
  629. this.tree = d3.layout.tree()
  630. .size([width, height]);
  631. this.diagonal = d3.svg.diagonal();
  632. this.port_connection_diagonal = d3.svg.diagonal().projection(function(d) {return [d.x, d.y]});
  633. this.parent_svg = d3.select("body").append("svg")
  634. .attr("width", width + margin.right + margin.left)
  635. .attr("height", height + margin.top + margin.bottom);
  636. var defs = this.parent_svg.append('svg:defs')
  637. var markers = [{name: 'arrow', path: 'M2,2 L2,11 L10,6 L2,2', fill: "red"},
  638. {name: 'arrow_green', path: 'M2,2 L2,11 L10,6 L2,2', fill: "green"}];
  639. var marker = defs.selectAll('marker')
  640. .data(markers)
  641. .enter()
  642. .append('svg:marker')
  643. .attr('id', function(d){ return 'marker_' + d.name})
  644. .attr('markerHeight', 13)
  645. .attr('markerWidth', 13)
  646. .attr('markerUnits', 'strokeWidth')
  647. .attr('orient', 'auto')
  648. .attr('refX', 2)
  649. .attr('refY', 6)
  650. .append('svg:path')
  651. .attr('d', function(d){ return d.path })
  652. .attr('fill', function(d){ return d.fill });
  653. this.svg = this.parent_svg.append("g")
  654. .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  655. function godEvent() {
  656. god_event_to_process = {'model': $('#currLoc').text(), 'attribute': $('#godEventName').val(), 'value': eval($('#godEventValue').val())};
  657. the_controller.addInput(new Event("process_god_event", "ui_input", [god_event_to_process]), 0.0);
  658. dialog.dialog("close");
  659. }
  660. dialog = $( "#godEventPopup" ).dialog({
  661. autoOpen: false,
  662. height: 200,
  663. width: 325,
  664. modal: true,
  665. buttons: {
  666. "Submit": godEvent,
  667. Cancel: function() {
  668. dialog.dialog( "close" );
  669. }
  670. },
  671. close: function() {
  672. form[ 0 ].reset();
  673. }
  674. }).css("font-size", "14px");;
  675. form = dialog.find( "form" ).on( "submit", function( event ) {
  676. event.preventDefault();
  677. godEvent();
  678. });
  679. function injectEvent() {
  680. event_to_inject = {'port': $('#currLoc').text(), 'event': eval($('#injectEvent').val()), 'time': eval($('#injectTime').val())};
  681. the_controller.addInput(new Event("inject_event", "ui_input", [event_to_inject]), 0.0);
  682. inject_dialog.dialog("close");
  683. }
  684. inject_dialog = $( "#injectEventPopup" ).dialog({
  685. autoOpen: false,
  686. height: 200,
  687. width: 325,
  688. modal: true,
  689. buttons: {
  690. "Submit": injectEvent,
  691. Cancel: function() {
  692. inject_dialog.dialog( "close" );
  693. }
  694. },
  695. close: function() {
  696. inject_form[ 0 ].reset();
  697. }
  698. }).css("font-size", "14px");
  699. inject_form = inject_dialog.find( "form" ).on( "submit", function( event ) {
  700. event.preventDefault();
  701. injectEvent();
  702. });
  703. function addBreakpoint() {
  704. breakpoint_to_add = [$('#breakpointName').val(), $('#breakpointFunction').val(), $('#breakpointEnabled').is(":checked"), $('#breakpointDisableOnTrigger').is(":checked")];
  705. the_controller.addInput(new Event("add_breakpoint", "ui_input", [breakpoint_to_add]), 0.0);
  706. breakpoint_dialog.dialog("close");
  707. }
  708. breakpoint_dialog = $( "#breakpointPopup" ).dialog({
  709. autoOpen: false,
  710. height: 400,
  711. width: 600,
  712. modal: true,
  713. buttons: {
  714. "Submit": addBreakpoint,
  715. Cancel: function() {
  716. breakpoint_dialog.dialog( "close" );
  717. }
  718. },
  719. close: function() {
  720. breakpoint_form[ 0 ].reset();
  721. }
  722. }).css("font-size", "14px");
  723. breakpoint_form = breakpoint_dialog.find( "form" ).on( "submit", function( event ) {
  724. event.preventDefault();
  725. addBreakpoint();
  726. });
  727. };
  728. Visualizer.prototype = new RuntimeClassBase();
  729. // Unique IDs for all statechart nodes
  730. Visualizer.prototype.Root = 0;
  731. Visualizer.prototype.Root_initializing = 1;
  732. Visualizer.prototype.Root_running = 2;
  733. // User defined method
  734. Visualizer.prototype.update_vis = function(structural_changes) {
  735. d3.select("#smallStepInfo_7").classed("inactive", false);
  736. var created_models = [],
  737. created_ports = [],
  738. connected_ports = [],
  739. deleted_models = [],
  740. deleted_ports = [],
  741. disconnected_ports = [];
  742. if ('CREATED_MODELS' in structural_changes) {
  743. created_models = structural_changes['CREATED_MODELS'];
  744. }
  745. if ('CREATED_PORTS' in structural_changes) {
  746. created_ports = structural_changes['CREATED_PORTS'];
  747. }
  748. if ('CONNECTED_PORTS' in structural_changes) {
  749. connected_ports = structural_changes['CONNECTED_PORTS'];
  750. }
  751. if ('DELETED_MODELS' in structural_changes) {
  752. deleted_models = structural_changes['DELETED_MODELS'];
  753. }
  754. if ('DELETED_PORTS' in structural_changes) {
  755. deleted_ports = structural_changes['DELETED_PORTS'];
  756. }
  757. if ('DISCONNECTED_PORTS' in structural_changes) {
  758. disconnected_ports = structural_changes['DISCONNECTED_PORTS'];
  759. }
  760. // sort according to their depth (amounts of dots in their name)
  761. created_models.sort(function(a, b) {
  762. return (a.match(/./g) || []).length - (b.match(/./g) || []).length
  763. })
  764. data = this.data;
  765. var node_id = this.node_id;
  766. var loc_to_item = this.loc_to_item;
  767. created_models.forEach(function(item) {
  768. splitted_path = item.split('.');
  769. element_to_insert = data;
  770. while (splitted_path.length > 1) {
  771. curr_name = splitted_path.shift();
  772. element_to_insert = element_to_insert.find(function(el) {return el['name'] == curr_name}).children;
  773. }
  774. var node = {'name': splitted_path[0], 'children': [], 'ports': [], 'loc': item, 'id': node_id++}
  775. element_to_insert.push(node);
  776. loc_to_item[item] = node;
  777. });
  778. created_ports.forEach(function(item) {
  779. splitted_path = item[0].split('.');
  780. curr_array = data;
  781. while (splitted_path.length > 2) {
  782. curr_name = splitted_path.shift();
  783. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  784. }
  785. ports = curr_array.find(function(el) {return el['name'] == splitted_path[0]})['ports'];
  786. var node = {'name': splitted_path[1], 'is_input': item[1], 'loc': item[0], 'id': node_id++};
  787. ports.push(node);
  788. loc_to_item[item[0]] = node;
  789. });
  790. this.node_id = node_id;
  791. port_connections = this.port_connections
  792. connected_ports.forEach(function(item) {
  793. splitted_path_src = item[0].split('.');
  794. curr_array = data;
  795. while (splitted_path_src.length > 2) {
  796. curr_name = splitted_path_src.shift();
  797. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  798. }
  799. src_parent = curr_array.find(function(el) {return el['name'] == splitted_path_src[0]});
  800. src = src_parent['ports'].find(function(el) {return el['name'] == splitted_path_src[1]});
  801. splitted_path_dst = item[1].split('.');
  802. curr_array = data;
  803. while (splitted_path_dst.length > 2) {
  804. curr_name = splitted_path_dst.shift();
  805. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  806. }
  807. dst_parent = curr_array.find(function(el) {return el['name'] == splitted_path_dst[0]});
  808. dst = dst_parent['ports'].find(function(el) {return el['name'] == splitted_path_dst[1]});
  809. port_connections.push({'source': src, 'target': dst});
  810. });
  811. disconnected_ports.forEach(function(item) {
  812. port_connections = port_connections.filter(function(el) {return el.source.loc != item[0] || el.target.loc != item[1];});
  813. });
  814. this.port_connections = port_connections
  815. deleted_ports.forEach(function(item) {
  816. splitted_path = item.split('.');
  817. curr_array = data;
  818. while (splitted_path.length > 2) {
  819. curr_name = splitted_path.shift();
  820. curr_array = curr_array.find(function(el) {return el['name'] == curr_name}).children;
  821. }
  822. parent = curr_array.find(function(el) {return el['name'] == splitted_path[0]});
  823. parent['ports'] = parent['ports'].filter(function(el) {return el['name'] != splitted_path[1]});
  824. });
  825. deleted_models.forEach(function(item) {
  826. splitted_path = item.split('.');
  827. curr_array = data;
  828. while (splitted_path.length > 2) {
  829. curr_name = splitted_path.shift();
  830. curr_array = element_to_insert.find(function(el) {return el['name'] == curr_name}).children;
  831. }
  832. parent = curr_array.find(function(el) {return el['name'] == splitted_path[0]});
  833. parent['children'] = parent['children'].filter(function(el) {return el['name'] != splitted_path[1]});
  834. });
  835. this.data = data;
  836. var nodes = this.tree.nodes(this.data[0]),
  837. links = this.tree.links(nodes);
  838. nodes.forEach(function(d, i) {
  839. d.y = d.depth * 100 + i * 40
  840. d.ports.forEach(function(p, i) {p.dx = 13, p.dy = 18; p.x = (d.x - 40) + i * p.dx; p.y = d.y + p.dy;});
  841. });
  842. // Declare the nodes...
  843. var node = this.svg.selectAll("g.node")
  844. .data(nodes, function(d) { return d.id; });
  845. // Enter the nodes.
  846. var nodeEnter = node.enter().append("g")
  847. .attr("class", "node")
  848. .attr("id", function(d) {return 'instance_' + d.id;})
  849. .attr("transform", function(d) {
  850. return "translate(" + d.x + "," + d.y + ")";
  851. });
  852. nodeEnter.append("rect")
  853. .attr("width", 120)
  854. .attr("height", 25)
  855. .attr("transform", "translate(-60, 0)")
  856. .on("click", function(d) {
  857. console.log(JSON.stringify(d.state, null, 2));
  858. })
  859. .on("mouseover", function(d) {
  860. var node = d3.select("#instance_" + d.id)
  861. var stateInfo = node.selectAll(".stateInfo")
  862. .data(function(n) {if (n.state) {return [n.state]} else {return []}}, function(d) {return d.id});
  863. var stateInfoEnter = stateInfo.enter().append("text")
  864. .attr("transform", "translate(-60, 60)")
  865. .attr("id", this.node_id++)
  866. .attr("class", "stateInfo");
  867. var stateInfoText = stateInfo.selectAll("tspan")
  868. .data(function(d) {return JSON.stringify(d, null, 2).split("\n")});
  869. var stateInfoTextEnter = stateInfoText.enter().append("tspan")
  870. .attr("x", "0.0")
  871. .attr("dy", "1.4em")
  872. .attr("xml:space", "preserve")
  873. .text(function(d) {return d});
  874. })
  875. .on("mouseout", function(d) {
  876. var node = d3.select("#instance_" + d.id)
  877. var stateInfo = node.selectAll(".stateInfo");
  878. stateInfo.selectAll("tspan").data([]).exit().remove();
  879. })
  880. .on("contextmenu", function (d, i) {
  881. $( "#currLoc" ).html(d.loc);
  882. d3.event.preventDefault();
  883. if (!d.children) {
  884. dialog.dialog( "open" );
  885. }
  886. });
  887. nodeEnter.append("text")
  888. .attr("y", 12)
  889. .attr("dy", ".35em")
  890. .attr("text-anchor", "middle")
  891. .text(function(d) { return d.name; })
  892. .style("fill-opacity", 1);
  893. nodeEnter.append("text")
  894. .attr("class", "timeNext")
  895. .attr("y", -10)
  896. .attr("x", 30)
  897. .attr("dy", ".35em")
  898. .attr("text-anchor", "middle")
  899. .text("TN: --")
  900. .style("fill-opacity", 1);
  901. port = node.selectAll("g.port")
  902. .data(function(n) {return n.ports}, function(d) { return d.id; })
  903. portEnter = port.enter().append("g")
  904. .attr("class", "port invisible")
  905. .attr("id", function(d) {return 'port_' + d.id;})
  906. .on("mouseover", function(d) {
  907. d3.selectAll(".source_" + d.id).classed("invisibleLink", false)
  908. .classed("input", false);
  909. d3.selectAll(".target_" + d.id).classed("invisibleLink", false)
  910. .classed("input", true);
  911. port_connections.forEach(function(port_connection) {
  912. if (port_connection.source.id == d.id) {
  913. d3.select('#port_' + port_connection.target.id).attr("class", "port visible");
  914. } else if (port_connection.target.id == d.id) {
  915. d3.select('#port_' + port_connection.source.id).attr("class", "port visible");
  916. }
  917. });
  918. d3.select(this).attr("class", "port visible");
  919. })
  920. .on("mouseout", function(d) {
  921. d3.selectAll(".source_" + d.id).classed("invisibleLink", true);
  922. d3.selectAll(".target_" + d.id).classed("invisibleLink", true);
  923. d3.selectAll(".port").attr("class", "port invisible");
  924. })
  925. .on("click", function (d, i) {
  926. $('#currLoc').html(d.loc);
  927. d3.event.preventDefault();
  928. if (d.is_input) {
  929. inject_dialog.dialog( "open" );
  930. }
  931. });
  932. portEnter.append("rect")
  933. .attr("width", 10)
  934. .attr("height", 10)
  935. .style("fill", function(d) {return d.is_input ? "green" : "purple";})
  936. .attr("transform", "rotate(45)");
  937. portEnter.append("text")
  938. .attr("dy", ".35em")
  939. .attr("text-anchor", "left")
  940. .text(function(d) {return d.name;})
  941. .attr("transform", "translate(0, 20) rotate(30)");
  942. port.attr("transform", function(d, i) {return "translate(" + (-40 + i * d.dx) + ", " + d.dy + ")"});
  943. // Declare the links...
  944. var link = this.svg.selectAll("path.link")
  945. .data(links);
  946. // Enter the links.
  947. link.enter().insert("path", "g")
  948. .attr("class", "link")
  949. .attr("d", this.diagonal);
  950. // Declare port connections...
  951. var port_connection = this.svg.selectAll("path.portConnection")
  952. .data(port_connections);
  953. // Enter port connections.
  954. port_connection.enter().insert("path", "g")
  955. .attr("class", "invisibleLink portConnection");
  956. // Update the nodes.
  957. node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
  958. node.classed("coupled", function(d) {return d.children});
  959. // Transition links to their new position.
  960. link.attr("d", this.diagonal);
  961. // Transition links to their new position.
  962. port_connection.attr("d", function(d) {
  963. var dx = d.target.x - d.source.x,
  964. dy = d.target.y - d.source.y,
  965. dr = Math.sqrt(dx * dx + dy * dy)/4,
  966. mx = d.source.x + dx/2,
  967. my = d.source.y + dy/2 + 30;
  968. return [
  969. "M",d.source.x,d.source.y+5,
  970. "T",mx,my,
  971. "T",d.target.x,d.target.y+5
  972. ].join(" ");
  973. })
  974. .attr("class", function(d) {return "invisibleLink portConnection source_" + d.source.id + " target_" + d.target.id});
  975. // Remove nodes and links.
  976. node.exit().remove();
  977. link.exit().remove();
  978. port.exit().remove();
  979. port_connection.exit().remove();
  980. };
  981. // User defined method
  982. Visualizer.prototype.visualize_initial_state = function(initial_states) {
  983. d3.select("#smallStepInfo").classed("invisibleInfo", true);
  984. d3.selectAll("g.node").attr("class", "node")
  985. .classed("coupled", function(d) {return d.children});
  986. d3.selectAll("circle.inmessage").data([]).exit().remove();
  987. d3.selectAll("circle.outmessage").data([]).exit().remove();
  988. d3.selectAll(".portConnection").classed("invisibleLink", true);
  989. d3.selectAll(".port").classed("visible", false);
  990. d3.selectAll(".port").classed("invisible", true);
  991. d3.selectAll(".stateInfo").data([]).exit().remove();
  992. for (var loc in initial_states) {
  993. var item = this.loc_to_item[loc];
  994. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + initial_states[loc][0][0] + "/" + initial_states[loc][0][1])
  995. item.state = initial_states[loc][1];
  996. if (item.state.particle_id) {
  997. this.particle_id_to_item[item.state.particle_id] = item; // TODO: this is somewhat ugly, we're making a lot of assumptions here and it's no longer domain-independent!
  998. }
  999. }
  1000. };
  1001. // User defined method
  1002. Visualizer.prototype.visualize_new_state = function(new_states, new_tn) {
  1003. d3.select("#smallStepInfo").classed("invisibleInfo", true);
  1004. d3.selectAll("g.node").attr("class", "node")
  1005. .classed("coupled", function(d) {return d.children});
  1006. d3.selectAll("circle.inmessage").data([]).exit().remove();
  1007. d3.selectAll("circle.outmessage").data([]).exit().remove();
  1008. d3.selectAll(".portConnection").classed("invisibleLink", true);
  1009. d3.selectAll(".port").classed("visible", false);
  1010. d3.selectAll(".port").classed("invisible", true);
  1011. d3.selectAll(".stateInfo").data([]).exit().remove();
  1012. for (var loc in new_tn) {
  1013. var item = this.loc_to_item[loc];
  1014. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + new_tn[loc][0] + "/" + new_tn[loc][1])
  1015. item.state = new_states[loc];
  1016. if (item.state.particle_id != undefined) {
  1017. this.particle_id_to_item[item.state.particle_id] = item; // TODO: this is somewhat ugly, we're making a lot of assumptions here and it's no longer domain-independent!
  1018. }
  1019. }
  1020. };
  1021. // User defined method
  1022. Visualizer.prototype.visualize_imminents = function(imminents) {
  1023. d3.selectAll(".portConnection").classed("invisibleLink", true);
  1024. d3.selectAll(".port").classed("visible", false);
  1025. d3.selectAll(".port").classed("invisible", true);
  1026. d3.selectAll("circle.inmessage").data([]).exit().remove();
  1027. d3.selectAll("circle.outmessage").data([]).exit().remove();
  1028. if (this.transitioning_nodes) {
  1029. this.transitioning_nodes.forEach(function(n) {n.attr("class", "node")
  1030. .classed("coupled", function(d) {return d.children});});
  1031. }
  1032. d3.select("#smallStepInfo").classed("invisibleInfo", false);
  1033. d3.selectAll(".smallStepInfo").classed("inactive", true);
  1034. d3.select("#smallStepInfo_0").classed("inactive", false);
  1035. var loc_to_item = this.loc_to_item;
  1036. this.imminents = imminents;
  1037. imminents.forEach(function(imminent) {
  1038. d3.select("#instance_" + loc_to_item[imminent].id).classed("imminent", true);
  1039. })
  1040. };
  1041. // User defined method
  1042. Visualizer.prototype.visualize_selected_imminent = function(selected_imminent) {
  1043. d3.select("#smallStepInfo_1").classed("inactive", false);
  1044. var loc_to_item = this.loc_to_item;
  1045. this.imminents.forEach(function(imminent) {
  1046. if (!(imminent == selected_imminent)) {
  1047. d3.select("#instance_" + loc_to_item[imminent].id).classed("imminent", false);
  1048. }
  1049. })
  1050. };
  1051. // User defined method
  1052. Visualizer.prototype.visualize_messages = function(bag, msg_type) {
  1053. var total_msgs = [];
  1054. for (var key in bag) {
  1055. var msgs = bag[key];
  1056. var port = this.loc_to_item[key];
  1057. if (port != undefined) {
  1058. msgs[0].port = port;
  1059. Array.prototype.push.apply(total_msgs, msgs);
  1060. }
  1061. }
  1062. var msgs_vis = this.svg.selectAll("circle." + msg_type)
  1063. .data(total_msgs);
  1064. var msg_enter = msgs_vis.enter().append("circle")
  1065. .attr("class", msg_type)
  1066. .attr("id", function(m) {return "msg_" + m.port.id;})
  1067. .attr("r", 5)
  1068. .attr("transform", function(m) {return "translate(" + m.port.x + "," + (m.port.y + 22) + ")"})
  1069. .on("click", function(d) {console.log(d[0])});
  1070. };
  1071. // User defined method
  1072. Visualizer.prototype.visualize_inbags = function(inbags) {
  1073. d3.select("#smallStepInfo_3").classed("inactive", false);
  1074. function transition(circle, path, source_port_vis, target_port_vis) {
  1075. circle.transition()
  1076. .duration(3000)
  1077. .attrTween("transform", translateAlong(path.node()))
  1078. .each("end", function() {
  1079. path.classed("invisibleLink", true);
  1080. source_port_vis.classed("invisible", true);
  1081. target_port_vis.classed("invisible", true);
  1082. source_port_vis.classed("visible", false);
  1083. target_port_vis.classed("visible", false);
  1084. circle.attr("class", "inmessage");
  1085. });
  1086. }
  1087. // Returns an attrTween for translating along the specified path element.
  1088. function translateAlong(path) {
  1089. var l = path.getTotalLength();
  1090. return function(d, i, a) {
  1091. return function(t) {
  1092. var p = path.getPointAtLength(t * l);
  1093. return "translate(" + p.x + "," + (p.y + 17) + ")";
  1094. };
  1095. };
  1096. }
  1097. var outports_visited = []
  1098. for (var key in inbags) {
  1099. if (inbags[key].length == 2) {
  1100. var msgs = inbags[key][1];
  1101. var inport = this.loc_to_item[key];
  1102. if (inport != undefined) {
  1103. var circle = undefined;
  1104. var outport_id = this.loc_to_item[inbags[key][0]].id;
  1105. if (outports_visited.indexOf(outport_id) > -1) {
  1106. circle = d3.select('#msg_' + outport_id);
  1107. var parent = d3.select(circle.node().parentNode);
  1108. circle = parent.append("circle")
  1109. .attr("class", "outmessage")
  1110. .attr("id", circle.id + outports_visited.indexOf(outport_id))
  1111. .attr("r", 5)
  1112. .attr("transform", circle.transform)
  1113. .on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  1114. } else {
  1115. circle = d3.select('#msg_' + outport_id);
  1116. circle.on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  1117. }
  1118. var path = d3.select(".source_" + outport_id + ".target_" + inport.id);
  1119. var source_port_vis = d3.select("#port_" + outport_id)
  1120. var target_port_vis = d3.select("#port_" + inport.id)
  1121. source_port_vis.classed("invisible", false);
  1122. target_port_vis.classed("invisible", false);
  1123. source_port_vis.classed("visible", true);
  1124. target_port_vis.classed("visible", true);
  1125. path.classed("invisibleLink", false);
  1126. transition(circle, path, source_port_vis, target_port_vis);
  1127. outports_visited.push(outport_id);
  1128. }
  1129. } else {
  1130. var msgs = inbags[key][0];
  1131. var inport = this.loc_to_item[key];
  1132. this.svg.append("circle")
  1133. .attr("class", "inmessage")
  1134. .attr("id", "msg_" + inport.id)
  1135. .attr("r", 5)
  1136. .attr("transform", "translate(" + inport.x + "," + (inport.y + 22) + ")")
  1137. .on("click", (function(msgs) {return function(d) {console.log(msgs[0])}})(msgs));
  1138. }
  1139. }
  1140. };
  1141. // User defined method
  1142. Visualizer.prototype.visualize_transitioning = function(transitioning) {
  1143. var transitioning_nodes = [];
  1144. var loc_to_item = this.loc_to_item;
  1145. Object.keys(transitioning).forEach(function(key) {
  1146. transitioning_nodes.push(d3.select("#instance_" + loc_to_item[key].id).classed(transitioning[key], true));
  1147. });
  1148. this.transitioning_nodes = transitioning_nodes;
  1149. };
  1150. // User defined method
  1151. Visualizer.prototype.handle_internal_state_change = function(new_internal_states) {
  1152. d3.select("#smallStepInfo_5").classed("inactive", false);
  1153. for (var loc in new_internal_states) {
  1154. var item = this.loc_to_item[loc];
  1155. item.state = new_internal_states[loc];
  1156. }
  1157. if (this.transitioning_nodes) {
  1158. this.transitioning_nodes.forEach(function(n) {n.attr("class", "node")
  1159. .classed("coupled", function(d) {return d.children});});
  1160. }
  1161. var node = this.svg.selectAll("g.node");
  1162. var stateInfo = node.selectAll("g.state");
  1163. stateInfo.text(function(d) {return JSON.stringify(d);});
  1164. };
  1165. // User defined method
  1166. Visualizer.prototype.visualize_new_tn = function(new_tn) {
  1167. d3.select("#smallStepInfo_6").classed("inactive", false);
  1168. for (var loc in new_tn) {
  1169. var item = this.loc_to_item[loc];
  1170. d3.select("#instance_" + item.id + " .timeNext").text("TN: " + new_tn[loc][0] + "/" + new_tn[loc][1])
  1171. }
  1172. };
  1173. // User defined method
  1174. Visualizer.prototype.select_instance = function(instance_id) {
  1175. d3.selectAll(".stateInfo").data([]).exit().remove();
  1176. if (instance_id in this.particle_id_to_item) {
  1177. var d = this.particle_id_to_item[instance_id];
  1178. var node = d3.select("#instance_" + d.id)
  1179. var stateInfo = node.selectAll(".stateInfo")
  1180. .data(function(n) {if (n.state) {return [n.state]} else {return []}}, function(d) {return d.id});
  1181. var stateInfoEnter = stateInfo.enter().append("text")
  1182. .attr("transform", "translate(-60, 60)")
  1183. .attr("id", this.node_id++)
  1184. .attr("class", "stateInfo");
  1185. var stateInfoText = stateInfo.selectAll("tspan")
  1186. .data(function(d) {return JSON.stringify(d, null, 2).split("\n")});
  1187. var stateInfoTextEnter = stateInfoText.enter().append("tspan")
  1188. .attr("x", "0.0")
  1189. .attr("dy", "1.4em")
  1190. .attr("xml:space", "preserve")
  1191. .text(function(d) {return d});
  1192. }
  1193. };
  1194. // User defined method
  1195. Visualizer.prototype.visualize_breakpoints = function() {
  1196. for (idx in this.breakpoints) {
  1197. var curr_bp = this.breakpoints[idx];
  1198. if (curr_bp.triggered) {
  1199. this.visualize_messages(curr_bp.outbag, 'outmessage');
  1200. for (var key in curr_bp.inbags) {
  1201. if (curr_bp.inbags[key].length == 2) {
  1202. curr_bp.inbags[key] = [curr_bp.inbags[key][1]];
  1203. }
  1204. }
  1205. this.visualize_messages(curr_bp.inbags, 'inmessage');
  1206. this.visualize_transitioning(curr_bp.transitioned);
  1207. }
  1208. }
  1209. var curr_bps = this.breakpoint_infos.selectAll("div").data(this.breakpoints)
  1210. curr_bps_enter = curr_bps.enter().append("div")
  1211. .attr("id", function(d) {return "breakpoint_" + d.name})
  1212. .attr("class", "breakpoint")
  1213. .style("transform", function(d, i) {return "translate(" + i * 5 + "px, -8px)"})
  1214. .style("float", "left");
  1215. curr_bps_enter.append("text")
  1216. .text(function(d) {return d.name})
  1217. .on("click", function(d) {
  1218. d.enabled = !d.enabled;
  1219. the_controller.addInput(new Event("toggle_breakpoint", "ui_input", [d.name, d.enabled]), 0.0);
  1220. })
  1221. .on('mouseover', function() {
  1222. d3.event.preventDefault();
  1223. });
  1224. curr_bps_enter.append("img")
  1225. .attr('src', 'img/delete-bp.png')
  1226. .style('transform', 'translate(1px, 2px)')
  1227. .on("click", function(d) {
  1228. the_controller.addInput(new Event("del_breakpoint", "ui_input", [d.name]), 0.0);
  1229. });
  1230. curr_bps.exit().remove();
  1231. curr_bps.style("background-color", function(d) {
  1232. if (d.triggered) {
  1233. d.triggered = false;
  1234. if (d.disable_on_trigger) {
  1235. d.enabled = false;
  1236. }
  1237. return "red";
  1238. } else {
  1239. return "transparent";
  1240. }});
  1241. curr_bps.select("text").style("opacity", function(d) {if (d.enabled) return "1"; else return "0.5";});
  1242. };
  1243. // Statechart enter/exit action method(s) :
  1244. Visualizer.prototype.enter_Root_initializing = function() {
  1245. this.current_state[this.Root].push(this.Root_initializing);
  1246. };
  1247. Visualizer.prototype.exit_Root_initializing = function() {
  1248. this.current_state[this.Root] = new Array();
  1249. };
  1250. Visualizer.prototype.enter_Root_running = function() {
  1251. this.current_state[this.Root].push(this.Root_running);
  1252. };
  1253. Visualizer.prototype.exit_Root_running = function() {
  1254. this.current_state[this.Root] = new Array();
  1255. };
  1256. // Statechart transitions :
  1257. Visualizer.prototype.transition_Root = function(event) {
  1258. var catched = false;
  1259. if (!catched) {
  1260. if (this.current_state[this.Root][0] === this.Root_initializing) {
  1261. catched = this.transition_Root_initializing(event);
  1262. }
  1263. else if (this.current_state[this.Root][0] === this.Root_running) {
  1264. catched = this.transition_Root_running(event);
  1265. }
  1266. }
  1267. return catched;
  1268. };
  1269. Visualizer.prototype.transition_Root_initializing = function(event) {
  1270. var catched = false;
  1271. var enableds = new Array();
  1272. enableds.push(1);
  1273. if (enableds.length > 1) {
  1274. console.log("Runtime warning : indeterminism detected in a transition from node Root_initializing. Only the first in document order enabled transition is executed.")
  1275. }
  1276. if (enableds.length > 0) {
  1277. var enabled = enableds[0];
  1278. if (enabled === 1) {
  1279. this.exit_Root_initializing();
  1280. this.controller.outputEvent(new Event("reset", "output", []));
  1281. this.enter_Root_running();
  1282. }
  1283. catched = true;
  1284. }
  1285. return catched;
  1286. };
  1287. Visualizer.prototype.transition_Root_running = function(event) {
  1288. var catched = false;
  1289. var enableds = new Array();
  1290. if (event.name === "all_states_reset" && event.port === "simulation_input") {
  1291. enableds.push(1);
  1292. }
  1293. if (event.name === "all_states" && event.port === "simulation_input") {
  1294. enableds.push(2);
  1295. }
  1296. if (event.name === "new_states" && event.port === "simulation_input") {
  1297. enableds.push(3);
  1298. }
  1299. if (event.name === "imminents" && event.port === "simulation_input") {
  1300. enableds.push(4);
  1301. }
  1302. if (event.name === "selected_imminent" && event.port === "simulation_input") {
  1303. enableds.push(5);
  1304. }
  1305. if (event.name === "outbag" && event.port === "simulation_input") {
  1306. enableds.push(6);
  1307. }
  1308. if (event.name === "inbags" && event.port === "simulation_input") {
  1309. enableds.push(7);
  1310. }
  1311. if (event.name === "transitioning" && event.port === "simulation_input") {
  1312. enableds.push(8);
  1313. }
  1314. if (event.name === "new_internal_states" && event.port === "simulation_input") {
  1315. enableds.push(9);
  1316. }
  1317. if (event.name === "new_tn" && event.port === "simulation_input") {
  1318. enableds.push(10);
  1319. }
  1320. if (event.name === "structural_changes" && event.port === "simulation_input") {
  1321. enableds.push(11);
  1322. }
  1323. if (event.name === "select_instance" && event.port === "ui_input") {
  1324. enableds.push(12);
  1325. }
  1326. if (event.name === "process_god_event" && event.port === "ui_input") {
  1327. enableds.push(13);
  1328. }
  1329. if (event.name === "god_event_ok" && event.port === "simulation_input") {
  1330. enableds.push(14);
  1331. }
  1332. if (event.name === "inject_event" && event.port === "ui_input") {
  1333. enableds.push(15);
  1334. }
  1335. if (event.name === "inject_ok" && event.port === "simulation_input") {
  1336. enableds.push(16);
  1337. }
  1338. if (event.name === "add_breakpoint" && event.port === "ui_input") {
  1339. enableds.push(17);
  1340. }
  1341. if (event.name === "toggle_breakpoint" && event.port === "ui_input") {
  1342. enableds.push(18);
  1343. }
  1344. if (event.name === "del_breakpoint" && event.port === "ui_input") {
  1345. enableds.push(19);
  1346. }
  1347. if (event.name === "breakpoint_triggered" && event.port === "simulation_input") {
  1348. enableds.push(20);
  1349. }
  1350. if (enableds.length > 1) {
  1351. console.log("Runtime warning : indeterminism detected in a transition from node Root_running. Only the first in document order enabled transition is executed.")
  1352. }
  1353. if (enableds.length > 0) {
  1354. var enabled = enableds[0];
  1355. if (enabled === 1) {
  1356. var parameters = event.parameters;
  1357. var the_parameters = parameters[0];
  1358. this.exit_Root_running();
  1359. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1360. this.data = [];
  1361. this.port_connections = [];
  1362. this.update_vis(the_parameters[2]);
  1363. this.visualize_initial_state(the_parameters[1]);
  1364. this.breakpoints = the_parameters[3];
  1365. this.visualize_breakpoints();
  1366. this.enter_Root_running();
  1367. }
  1368. else if (enabled === 2) {
  1369. var parameters = event.parameters;
  1370. var the_parameters = parameters[0];
  1371. this.exit_Root_running();
  1372. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1373. this.update_vis(the_parameters[2]);
  1374. this.visualize_initial_state(the_parameters[1]);
  1375. this.visualize_breakpoints();
  1376. this.enter_Root_running();
  1377. }
  1378. else if (enabled === 3) {
  1379. var parameters = event.parameters;
  1380. var the_parameters = parameters[0];
  1381. this.exit_Root_running();
  1382. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1383. this.update_vis(the_parameters[3]);
  1384. this.visualize_new_state(the_parameters[1], the_parameters[2]);
  1385. this.visualize_breakpoints();
  1386. this.enter_Root_running();
  1387. }
  1388. else if (enabled === 4) {
  1389. var parameters = event.parameters;
  1390. var the_parameters = parameters[0];
  1391. this.exit_Root_running();
  1392. this.visualize_breakpoints();
  1393. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1394. this.visualize_imminents(the_parameters[1]);
  1395. this.enter_Root_running();
  1396. }
  1397. else if (enabled === 5) {
  1398. var parameters = event.parameters;
  1399. var the_parameters = parameters[0];
  1400. this.exit_Root_running();
  1401. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1402. this.visualize_selected_imminent(the_parameters[1]);
  1403. this.enter_Root_running();
  1404. }
  1405. else if (enabled === 6) {
  1406. var parameters = event.parameters;
  1407. var the_parameters = parameters[0];
  1408. this.exit_Root_running();
  1409. d3.select("#smallStepInfo_2").classed("inactive", false);
  1410. d3.selectAll("g.node").classed("imminent", false);
  1411. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1412. this.visualize_messages(the_parameters[1], 'outmessage');
  1413. this.enter_Root_running();
  1414. }
  1415. else if (enabled === 7) {
  1416. var parameters = event.parameters;
  1417. var the_parameters = parameters[0];
  1418. this.exit_Root_running();
  1419. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1420. this.visualize_inbags(the_parameters[1]);
  1421. this.enter_Root_running();
  1422. }
  1423. else if (enabled === 8) {
  1424. var parameters = event.parameters;
  1425. var the_parameters = parameters[0];
  1426. this.exit_Root_running();
  1427. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1428. d3.select("#smallStepInfo_4").classed("inactive", false);
  1429. d3.selectAll(".portConnection").classed("invisibleLink", true);
  1430. d3.selectAll(".port").classed("visible", false);
  1431. d3.selectAll(".port").classed("invisible", true);
  1432. d3.selectAll("circle.inmessage").data([]).exit().remove();
  1433. d3.selectAll("circle.outmessage").data([]).exit().remove();
  1434. this.visualize_transitioning(the_parameters[1]);
  1435. this.enter_Root_running();
  1436. }
  1437. else if (enabled === 9) {
  1438. var parameters = event.parameters;
  1439. var the_parameters = parameters[0];
  1440. this.exit_Root_running();
  1441. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1442. this.handle_internal_state_change(the_parameters[1]);
  1443. this.enter_Root_running();
  1444. }
  1445. else if (enabled === 10) {
  1446. var parameters = event.parameters;
  1447. var the_parameters = parameters[0];
  1448. this.exit_Root_running();
  1449. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1450. this.visualize_new_tn(the_parameters[1]);
  1451. this.enter_Root_running();
  1452. }
  1453. else if (enabled === 11) {
  1454. var parameters = event.parameters;
  1455. var the_parameters = parameters[0];
  1456. this.exit_Root_running();
  1457. this.simulation_time.text("SIMULATION TIME: " + the_parameters[0][0] + "/" + the_parameters[0][1]);
  1458. this.update_vis(the_parameters[1]);
  1459. this.enter_Root_running();
  1460. }
  1461. else if (enabled === 12) {
  1462. var parameters = event.parameters;
  1463. var the_parameters = parameters[0];
  1464. this.exit_Root_running();
  1465. this.select_instance(the_parameters);
  1466. this.enter_Root_running();
  1467. }
  1468. else if (enabled === 13) {
  1469. this.exit_Root_running();
  1470. this.controller.outputEvent(new Event("god_event", "output", [god_event_to_process]));
  1471. this.enter_Root_running();
  1472. }
  1473. else if (enabled === 14) {
  1474. var parameters = event.parameters;
  1475. var the_parameters = parameters[0];
  1476. this.exit_Root_running();
  1477. this.handle_internal_state_change(the_parameters[0]);
  1478. this.enter_Root_running();
  1479. }
  1480. else if (enabled === 15) {
  1481. this.exit_Root_running();
  1482. this.controller.outputEvent(new Event("inject", "output", [event_to_inject]));
  1483. this.enter_Root_running();
  1484. }
  1485. else if (enabled === 16) {
  1486. this.exit_Root_running();
  1487. this.enter_Root_running();
  1488. }
  1489. else if (enabled === 17) {
  1490. this.exit_Root_running();
  1491. this.controller.outputEvent(new Event("add_breakpoint", "output", [breakpoint_to_add]));
  1492. this.breakpoints.push({'name': breakpoint_to_add[0], 'enabled': breakpoint_to_add[2], 'disable_on_trigger': breakpoint_to_add[3], 'triggered': false});
  1493. this.visualize_breakpoints();
  1494. this.enter_Root_running();
  1495. }
  1496. else if (enabled === 18) {
  1497. var parameters = event.parameters;
  1498. var breakpoint_id = parameters[0];
  1499. var enabled = parameters[1];
  1500. this.exit_Root_running();
  1501. this.controller.outputEvent(new Event("toggle_breakpoint", "output", [breakpoint_id,enabled]));
  1502. this.visualize_breakpoints();
  1503. this.enter_Root_running();
  1504. }
  1505. else if (enabled === 19) {
  1506. var parameters = event.parameters;
  1507. var breakpoint_id = parameters[0];
  1508. this.exit_Root_running();
  1509. this.controller.outputEvent(new Event("del_breakpoint", "output", [breakpoint_id]));
  1510. this.breakpoints = this.breakpoints.filter(function(bp) {return bp.name != breakpoint_id});
  1511. this.visualize_breakpoints();
  1512. this.enter_Root_running();
  1513. }
  1514. else if (enabled === 20) {
  1515. var parameters = event.parameters;
  1516. var the_parameters = parameters[0];
  1517. this.exit_Root_running();
  1518. for (var idx in this.breakpoints) {
  1519. var curr_bp = this.breakpoints[idx];
  1520. if (curr_bp.name == the_parameters[0]) {
  1521. curr_bp.triggered = true;
  1522. curr_bp.transitioned = the_parameters[1];
  1523. curr_bp.outbag = the_parameters[2];
  1524. curr_bp.inbags = the_parameters[3];
  1525. }
  1526. }
  1527. this.enter_Root_running();
  1528. }
  1529. catched = true;
  1530. }
  1531. return catched;
  1532. };
  1533. // Execute transitions
  1534. Visualizer.prototype.transition = function(event) {
  1535. if (!event) event = new Event();
  1536. this.state_changed = this.transition_Root(event);
  1537. };
  1538. // inState method for statechart
  1539. Visualizer.prototype.inState = function(nodes) {
  1540. for (var c in this.current_state) {
  1541. if (!this.current_state.hasOwnProperty(c)) continue;
  1542. var new_nodes = new Array();
  1543. for (var n in nodes) {
  1544. if (!nodes.hasOwnProperty(n)) continue;
  1545. if (this.current_state[c].indexOf(nodes[n]) === -1) {
  1546. new_nodes.push(nodes[n]);
  1547. }
  1548. }
  1549. nodes = new_nodes;
  1550. if (nodes.length === 0) {
  1551. return true;
  1552. }
  1553. }
  1554. return false;
  1555. };
  1556. Visualizer.prototype.commonConstructor = function(controller) {
  1557. if (!controller) controller = null;
  1558. // Constructor part that is common for all constructors.
  1559. RuntimeClassBase.call(this);
  1560. // User defined input ports
  1561. this.inports = new Object();
  1562. this.controller = controller;
  1563. this.object_manager = (controller == null ? null : controller.object_manager);
  1564. this.current_state = new Object();
  1565. this.history_state = new Object();
  1566. // Initialize statechart
  1567. this.current_state[this.Root] = new Array();
  1568. };
  1569. Visualizer.prototype.start = function() {
  1570. RuntimeClassBase.prototype.start.call(this);
  1571. this.enter_Root_initializing();
  1572. };
  1573. // put class in global diagram object
  1574. DebuggingEnvironment.Visualizer = Visualizer;
  1575. var ObjectManager = function(controller) {
  1576. ObjectManagerBase.call(this, controller);
  1577. };
  1578. ObjectManager.prototype = new ObjectManagerBase();
  1579. ObjectManager.prototype.instantiate = function(class_name, construct_params) {
  1580. if (class_name === "MainApp") {
  1581. var instance = new MainApp(this.controller);
  1582. instance.associations = new Object();
  1583. instance.associations["toolbar"] = new Association("DebuggingToolbar", 1, 1);
  1584. instance.associations["visualizer"] = new Association("Visualizer", 1, 1);
  1585. } else if (class_name === "DebuggingToolbar") {
  1586. var instance = new DebuggingToolbar(this.controller);
  1587. instance.associations = new Object();
  1588. instance.associations["parent"] = new Association("MainApp", 1, 1);
  1589. instance.associations["buttons"] = new Association("Button", 0, -1);
  1590. } else if (class_name === "Button") {
  1591. var instance = new Button(this.controller, construct_params[0], construct_params[1], construct_params[2]);
  1592. instance.associations = new Object();
  1593. instance.associations["parent"] = new Association("DebuggingToolbar", 1, 1);
  1594. } else if (class_name === "Visualizer") {
  1595. var instance = new Visualizer(this.controller);
  1596. instance.associations = new Object();
  1597. instance.associations["parent"] = new Association("MainApp", 1, 1);
  1598. }
  1599. return instance;
  1600. };
  1601. // put in global diagram object
  1602. DebuggingEnvironment.ObjectManager = ObjectManager;
  1603. var Controller = function(keep_running, finished_callback) {
  1604. if (keep_running === undefined) keep_running = true;
  1605. JsEventLoopControllerBase.call(this, new ObjectManager(this), keep_running, finished_callback);
  1606. this.addInputPort("ui_input");
  1607. this.addInputPort("simulation_input");
  1608. this.addOutputPort("output");
  1609. this.object_manager.createInstance("MainApp", []);
  1610. };
  1611. Controller.prototype = new JsEventLoopControllerBase();
  1612. // put in global diagram object
  1613. DebuggingEnvironment.Controller = Controller;
  1614. })();