Trapped-Backend.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. smalltalk.addPackage('Trapped-Backend', {});
  2. smalltalk.addClass('EavModel', smalltalk.Object, ['getBlock', 'putBlock'], 'Trapped-Backend');
  3. smalltalk.EavModel.comment="External actor value model."
  4. smalltalk.addMethod(
  5. "_getBlock_",
  6. smalltalk.method({
  7. selector: "getBlock:",
  8. category: 'accessing',
  9. fn: function (aBlock){
  10. var self=this;
  11. self["@getBlock"]=aBlock;
  12. return self},
  13. args: ["aBlock"],
  14. source: "getBlock: aBlock\x0a\x0agetBlock := aBlock",
  15. messageSends: [],
  16. referencedClasses: []
  17. }),
  18. smalltalk.EavModel);
  19. smalltalk.addMethod(
  20. "_initialize",
  21. smalltalk.method({
  22. selector: "initialize",
  23. category: 'initialization',
  24. fn: function (){
  25. var self=this;
  26. smalltalk.send(self,"_initialize",[],smalltalk.Object);
  27. self["@getBlock"]=(function(){
  28. return smalltalk.send(self,"_error_",["No getter block."]);
  29. });
  30. self["@putBlock"]=(function(){
  31. return smalltalk.send(self,"_error_",["No putter block."]);
  32. });
  33. return self},
  34. args: [],
  35. source: "initialize\x0a\x09super initialize.\x0a\x09getBlock := [ self error: 'No getter block.' ].\x0a\x09putBlock := [ self error: 'No putter block.' ].",
  36. messageSends: ["initialize", "error:"],
  37. referencedClasses: []
  38. }),
  39. smalltalk.EavModel);
  40. smalltalk.addMethod(
  41. "_on_",
  42. smalltalk.method({
  43. selector: "on:",
  44. category: 'accessing',
  45. fn: function (anObject){
  46. var self=this;
  47. var $1;
  48. $1=smalltalk.send(self["@getBlock"],"_value_",[anObject]);
  49. return $1;
  50. },
  51. args: ["anObject"],
  52. source: "on: anObject\x0a\x22Returns value of model applied on object\x22\x0a\x0a^getBlock value: anObject",
  53. messageSends: ["value:"],
  54. referencedClasses: []
  55. }),
  56. smalltalk.EavModel);
  57. smalltalk.addMethod(
  58. "_on_put_",
  59. smalltalk.method({
  60. selector: "on:put:",
  61. category: 'accessing',
  62. fn: function (anObject,anObject2){
  63. var self=this;
  64. var $1;
  65. $1=smalltalk.send(self["@putBlock"],"_value_value_",[anObject,anObject2]);
  66. return $1;
  67. },
  68. args: ["anObject", "anObject2"],
  69. source: "on: anObject put: anObject2\x0a\x22Puts a value via model applied on object\x22\x0a\x0a^putBlock value: anObject value: anObject2",
  70. messageSends: ["value:value:"],
  71. referencedClasses: []
  72. }),
  73. smalltalk.EavModel);
  74. smalltalk.addMethod(
  75. "_putBlock_",
  76. smalltalk.method({
  77. selector: "putBlock:",
  78. category: 'accessing',
  79. fn: function (aBlock){
  80. var self=this;
  81. self["@putBlock"]=aBlock;
  82. return self},
  83. args: ["aBlock"],
  84. source: "putBlock: aBlock\x0a\x0aputBlock := aBlock",
  85. messageSends: [],
  86. referencedClasses: []
  87. }),
  88. smalltalk.EavModel);
  89. smalltalk.addClass('Isolator', smalltalk.Object, ['root'], 'Trapped-Backend');
  90. smalltalk.addMethod(
  91. "_model_modify_",
  92. smalltalk.method({
  93. selector: "model:modify:",
  94. category: 'action',
  95. fn: function (anEavModel,aBlock){
  96. var self=this;
  97. var newValue;
  98. newValue=smalltalk.send(aBlock,"_value_",[smalltalk.send(anEavModel,"_on_",[self])]);
  99. smalltalk.send(anEavModel,"_on_put_",[self,smalltalk.send(newValue,"_deepCopy",[])]);
  100. return self},
  101. args: ["anEavModel", "aBlock"],
  102. source: "model: anEavModel modify: aBlock\x0a\x0a| newValue |\x0anewValue := aBlock value: (anEavModel on: self).\x0aanEavModel on: self put: newValue deepCopy\x0a",
  103. messageSends: ["value:", "on:", "on:put:", "deepCopy"],
  104. referencedClasses: []
  105. }),
  106. smalltalk.Isolator);
  107. smalltalk.addMethod(
  108. "_model_read_",
  109. smalltalk.method({
  110. selector: "model:read:",
  111. category: 'action',
  112. fn: function (anEavModel,aBlock){
  113. var self=this;
  114. smalltalk.send(aBlock,"_value_",[smalltalk.send(smalltalk.send(anEavModel,"_on_",[self]),"_deepCopy",[])]);
  115. return self},
  116. args: ["anEavModel", "aBlock"],
  117. source: "model: anEavModel read: aBlock\x0a\x0aaBlock value: (anEavModel on: self) deepCopy",
  118. messageSends: ["value:", "deepCopy", "on:"],
  119. referencedClasses: []
  120. }),
  121. smalltalk.Isolator);
  122. smalltalk.addMethod(
  123. "_root",
  124. smalltalk.method({
  125. selector: "root",
  126. category: 'accessing',
  127. fn: function (){
  128. var self=this;
  129. return self["@root"];
  130. },
  131. args: [],
  132. source: "root\x0a\x0a^root\x0a",
  133. messageSends: [],
  134. referencedClasses: []
  135. }),
  136. smalltalk.Isolator);
  137. smalltalk.addMethod(
  138. "_root_",
  139. smalltalk.method({
  140. selector: "root:",
  141. category: 'accessing',
  142. fn: function (anObject){
  143. var self=this;
  144. self["@root"]=anObject;
  145. return self},
  146. args: ["anObject"],
  147. source: "root: anObject\x0a\x0aroot := anObject",
  148. messageSends: [],
  149. referencedClasses: []
  150. }),
  151. smalltalk.Isolator);
  152. smalltalk.addMethod(
  153. "_on_",
  154. smalltalk.method({
  155. selector: "on:",
  156. category: 'instance creation',
  157. fn: function (anObject){
  158. var self=this;
  159. var $1;
  160. $1=smalltalk.send(smalltalk.send(self,"_new",[]),"_root_",[anObject]);
  161. return $1;
  162. },
  163. args: ["anObject"],
  164. source: "on: anObject\x0a^self new root: anObject",
  165. messageSends: ["root:", "new"],
  166. referencedClasses: []
  167. }),
  168. smalltalk.Isolator.klass);
  169. smalltalk.addClass('TrappedDispatcher', smalltalk.Object, [], 'Trapped-Backend');
  170. smalltalk.TrappedDispatcher.comment="I am base class for change event dispatchers.\x0aI manage changed path - action block subscriptions.\x0aThese subscription must be three-element arrays\x0a\x09{ dirty. path. block }\x0a\x0aMy subclasses need to provide implementation for:\x0a\x09add:\x0a do:\x0a (optionally) run\x0a"
  171. smalltalk.addMethod(
  172. "_changed_",
  173. smalltalk.method({
  174. selector: "changed:",
  175. category: 'action',
  176. fn: function (path){
  177. var self=this;
  178. var $1;
  179. var needsToRun;
  180. needsToRun=false;
  181. smalltalk.send(self,"_do_",[(function(each){
  182. var aPath;
  183. var lesser;
  184. aPath=smalltalk.send(each,"_second",[]);
  185. aPath;
  186. lesser=smalltalk.send(smalltalk.send(aPath,"_size",[]),"_min_",[smalltalk.send(path,"_size",[])]);
  187. lesser;
  188. $1=smalltalk.send(smalltalk.send(path,"_copyFrom_to_",[(1),lesser]),"__eq",[smalltalk.send(aPath,"_copyFrom_to_",[(1),lesser])]);
  189. if(smalltalk.assert($1)){
  190. smalltalk.send(each,"_at_put_",[(1),true]);
  191. needsToRun=true;
  192. return needsToRun;
  193. };
  194. })]);
  195. smalltalk.send(self,"_dirty_",[needsToRun]);
  196. return self},
  197. args: ["path"],
  198. source: "changed: path\x0a\x09| needsToRun |\x0a needsToRun := false.\x0a\x09self do: [ :each |\x0a\x09\x09| aPath lesser |\x0a\x09\x09aPath := each second.\x0a\x09\x09lesser := aPath size min: path size.\x0a\x09\x09(path copyFrom: 1 to: lesser) = (aPath copyFrom: 1 to: lesser) ifTrue: [\x0a\x09\x09\x09each at: 1 put: true.\x0a needsToRun := true.\x0a\x09\x09]\x0a\x09].\x0a\x09self dirty: needsToRun",
  199. messageSends: ["do:", "second", "min:", "size", "ifTrue:", "at:put:", "=", "copyFrom:to:", "dirty:"],
  200. referencedClasses: []
  201. }),
  202. smalltalk.TrappedDispatcher);
  203. smalltalk.addMethod(
  204. "_dirty_",
  205. smalltalk.method({
  206. selector: "dirty:",
  207. category: 'action',
  208. fn: function (aBoolean){
  209. var self=this;
  210. if(smalltalk.assert(aBoolean)){
  211. smalltalk.send((function(){
  212. return smalltalk.send(self,"_run",[]);
  213. }),"_fork",[]);
  214. };
  215. return self},
  216. args: ["aBoolean"],
  217. source: "dirty: aBoolean\x0a\x09aBoolean ifTrue: [[ self run ] fork]",
  218. messageSends: ["ifTrue:", "fork", "run"],
  219. referencedClasses: []
  220. }),
  221. smalltalk.TrappedDispatcher);
  222. smalltalk.addMethod(
  223. "_run",
  224. smalltalk.method({
  225. selector: "run",
  226. category: 'action',
  227. fn: function (){
  228. var self=this;
  229. var $1;
  230. smalltalk.send(self,"_do_",[(function(each){
  231. $1=smalltalk.send(each,"_first",[]);
  232. if(smalltalk.assert($1)){
  233. return smalltalk.send((function(){
  234. return smalltalk.send(smalltalk.send(each,"_third",[]),"_value",[]);
  235. }),"_ensure_",[(function(){
  236. return smalltalk.send(each,"_at_put_",[(1),false]);
  237. })]);
  238. };
  239. })]);
  240. return self},
  241. args: [],
  242. source: "run\x0a\x09self do: [ :each |\x0a\x09\x09each first ifTrue: [[ each third value ] ensure: [ each at: 1 put: false ]]\x0a\x09]",
  243. messageSends: ["do:", "ifTrue:", "ensure:", "at:put:", "value", "third", "first"],
  244. referencedClasses: []
  245. }),
  246. smalltalk.TrappedDispatcher);
  247. smalltalk.addMethod(
  248. "_reverseTrapAt_",
  249. smalltalk.method({
  250. selector: "reverseTrapAt:",
  251. category: '*Trapped-Backend',
  252. fn: function (anObject){
  253. var self=this;
  254. return nil;
  255. },
  256. args: ["anObject"],
  257. source: "reverseTrapAt: anObject\x0a\x09^nil",
  258. messageSends: [],
  259. referencedClasses: []
  260. }),
  261. smalltalk.Object);
  262. smalltalk.addMethod(
  263. "_reverseTrapAt_put_",
  264. smalltalk.method({
  265. selector: "reverseTrapAt:put:",
  266. category: '*Trapped-Backend',
  267. fn: function (anObject,value){
  268. var self=this;
  269. smalltalk.send(self,"_error_",[smalltalk.send(smalltalk.send("Trapped cannot put at ","__comma",[smalltalk.send(smalltalk.send(self,"_class",[]),"_name",[])]),"__comma",[" type key."])]);
  270. return self},
  271. args: ["anObject", "value"],
  272. source: "reverseTrapAt: anObject put: value\x0a\x09self error: 'Trapped cannot put at ', self class name, ' type key.'",
  273. messageSends: ["error:", ",", "name", "class"],
  274. referencedClasses: []
  275. }),
  276. smalltalk.Object);
  277. smalltalk.addMethod(
  278. "_asEavModel",
  279. smalltalk.method({
  280. selector: "asEavModel",
  281. category: '*Trapped-Backend',
  282. fn: function (){
  283. var self=this;
  284. var $1;
  285. var model;
  286. model=smalltalk.send((smalltalk.EavModel || EavModel),"_new",[]);
  287. smalltalk.send(model,"_getBlock_",[(function(anObject){
  288. return smalltalk.send(self,"_inject_into_",[anObject,(function(soFar,segment){
  289. if(($receiver = soFar) == nil || $receiver == undefined){
  290. return soFar;
  291. } else {
  292. return smalltalk.send(segment,"_reverseTrapAt_",[soFar]);
  293. };
  294. })]);
  295. })]);
  296. $1=smalltalk.send(self,"_isEmpty",[]);
  297. if(! smalltalk.assert($1)){
  298. smalltalk.send(model,"_putBlock_",[(function(anObject,value){
  299. var penultimate;
  300. penultimate=smalltalk.send(smalltalk.send(self,"_allButLast",[]),"_inject_into_",[anObject,(function(soFar,segment){
  301. if(($receiver = soFar) == nil || $receiver == undefined){
  302. return soFar;
  303. } else {
  304. return smalltalk.send(segment,"_reverseTrapAt_",[soFar]);
  305. };
  306. })]);
  307. penultimate;
  308. return smalltalk.send(smalltalk.send(self,"_last",[]),"_reverseTrapAt_put_",[penultimate,value]);
  309. })]);
  310. };
  311. return model;
  312. },
  313. args: [],
  314. source: "asEavModel\x0a | model |\x0a model := EavModel new.\x0a model getBlock: [ :anObject |\x0a self inject: anObject into: [ :soFar :segment |\x0a soFar ifNotNil: [ segment reverseTrapAt: soFar ]]].\x0a self isEmpty ifFalse: [\x0a model putBlock: [ :anObject :value | | penultimate |\x0a penultimate := self allButLast inject: anObject into: [ :soFar :segment |\x0a soFar ifNotNil: [ segment reverseTrapAt: soFar ]].\x0a self last reverseTrapAt: penultimate put: value ]].\x0a ^model",
  315. messageSends: ["new", "getBlock:", "inject:into:", "ifNotNil:", "reverseTrapAt:", "ifFalse:", "putBlock:", "allButLast", "reverseTrapAt:put:", "last", "isEmpty"],
  316. referencedClasses: ["EavModel"]
  317. }),
  318. smalltalk.SequenceableCollection);
  319. smalltalk.addMethod(
  320. "_reverseTrapAt_",
  321. smalltalk.method({
  322. selector: "reverseTrapAt:",
  323. category: '*Trapped-Backend',
  324. fn: function (anObject){
  325. var self=this;
  326. var $1;
  327. $1=smalltalk.send(anObject,"_at_ifAbsent_",[self,(function(){
  328. return nil;
  329. })]);
  330. return $1;
  331. },
  332. args: ["anObject"],
  333. source: "reverseTrapAt: anObject\x0a\x09^anObject at: self ifAbsent: [nil]",
  334. messageSends: ["at:ifAbsent:"],
  335. referencedClasses: []
  336. }),
  337. smalltalk.String);
  338. smalltalk.addMethod(
  339. "_reverseTrapAt_put_",
  340. smalltalk.method({
  341. selector: "reverseTrapAt:put:",
  342. category: '*Trapped-Backend',
  343. fn: function (anObject,value){
  344. var self=this;
  345. var $1;
  346. $1=smalltalk.send(anObject,"_at_put_",[self,value]);
  347. return $1;
  348. },
  349. args: ["anObject", "value"],
  350. source: "reverseTrapAt: anObject put: value\x0a\x09^anObject at: self put: value",
  351. messageSends: ["at:put:"],
  352. referencedClasses: []
  353. }),
  354. smalltalk.String);
  355. smalltalk.addMethod(
  356. "_reverseTrapAt_",
  357. smalltalk.method({
  358. selector: "reverseTrapAt:",
  359. category: '*Trapped-Backend',
  360. fn: function (anObject){
  361. var self=this;
  362. var $1;
  363. var $early={};
  364. try {
  365. $1=smalltalk.send((function(){
  366. return smalltalk.send(anObject,"_perform_",[self]);
  367. }),"_on_do_",[(smalltalk.MessageNotUnderstood || MessageNotUnderstood),(function(){
  368. throw $early=[nil];
  369. })]);
  370. return $1;
  371. }
  372. catch(e) {if(e===$early)return e[0]; throw e}
  373. },
  374. args: ["anObject"],
  375. source: "reverseTrapAt: anObject\x0a\x09^[anObject perform: self] on: MessageNotUnderstood do: [^nil]",
  376. messageSends: ["on:do:", "perform:"],
  377. referencedClasses: ["MessageNotUnderstood"]
  378. }),
  379. smalltalk.Symbol);
  380. smalltalk.addMethod(
  381. "_reverseTrapAt_put_",
  382. smalltalk.method({
  383. selector: "reverseTrapAt:put:",
  384. category: '*Trapped-Backend',
  385. fn: function (anObject,value){
  386. var self=this;
  387. var $1;
  388. $1=smalltalk.send(anObject,"_perform_withArguments_",[smalltalk.send(smalltalk.send(self,"__comma",[":"]),"_asSymbol",[]),[value]]);
  389. return $1;
  390. },
  391. args: ["anObject", "value"],
  392. source: "reverseTrapAt: anObject put: value\x0a ^anObject perform: (self, ':') asSymbol withArguments: { value }",
  393. messageSends: ["perform:withArguments:", "asSymbol", ","],
  394. referencedClasses: []
  395. }),
  396. smalltalk.Symbol);
  397. smalltalk.addMethod(
  398. "_reverseTrapAt_",
  399. smalltalk.method({
  400. selector: "reverseTrapAt:",
  401. category: '*Trapped-Backend',
  402. fn: function (anObject){
  403. var self=this;
  404. var $1;
  405. $1=smalltalk.send(anObject,"_at_ifAbsent_",[self,(function(){
  406. return nil;
  407. })]);
  408. return $1;
  409. },
  410. args: ["anObject"],
  411. source: "reverseTrapAt: anObject\x0a\x09^anObject at: self ifAbsent: [nil]",
  412. messageSends: ["at:ifAbsent:"],
  413. referencedClasses: []
  414. }),
  415. smalltalk.Number);
  416. smalltalk.addMethod(
  417. "_reverseTrapAt_put_",
  418. smalltalk.method({
  419. selector: "reverseTrapAt:put:",
  420. category: '*Trapped-Backend',
  421. fn: function (anObject,value){
  422. var self=this;
  423. var $1;
  424. $1=smalltalk.send(anObject,"_at_put_",[self,value]);
  425. return $1;
  426. },
  427. args: ["anObject", "value"],
  428. source: "reverseTrapAt: anObject put: value\x0a\x09^anObject at: self put: value",
  429. messageSends: ["at:put:"],
  430. referencedClasses: []
  431. }),
  432. smalltalk.Number);