Update yoob.js components to version 0.6.
Chris Pressey
10 years ago
9 | 9 | the esolangs.org wiki. (Which is in the public domain and was mostly |
10 | 10 | written by me anyway.) |
11 | 11 | * the [yoob][] implementation of Wunnel. |
12 | * an implementation of Wunnel in HTML5, using [yoob.js][]. | |
13 | ||
14 | It's all in the public domain; see the file UNLICENSE for more information. | |
12 | 15 | |
13 | 16 | [Wunnel article]: http://esolangs.org/wiki/Wunnel |
14 | [yoob]: http://catseye.tc/node/yoob.html | |
15 | ||
17 | [yoob]: http://catseye.tc/node/yoob | |
18 | [yoob.js]: http://catseye.tc/node/yoob.js |
124 | 124 | <script src="../src/yoob/cursor.js"></script> |
125 | 125 | <script src="../src/yoob/tape.js"></script> |
126 | 126 | <script src="../src/yoob/controller.js"></script> |
127 | <script src="../src/yoob/example-manager.js"></script> | |
127 | <script src="../src/yoob/preset-manager.js"></script> | |
128 | 128 | <script src="../src/wunnel-controller.js"></script> |
129 | 129 | <script> |
130 | 130 | var programView = new yoob.PlayfieldHTMLView().init( |
155 | 155 | 'display': 'display_container' |
156 | 156 | }); |
157 | 157 | c.click_load(); |
158 | e = (new yoob.ExampleManager()).init({ | |
158 | e = (new yoob.PresetManager()).init({ | |
159 | 159 | selectElem: document.getElementById('select_source'), |
160 | 160 | controller: c |
161 | 161 | }).populateFromClass('example_program'); |
0 | 0 | /* |
1 | * This file is part of yoob.js version 0.6-PRE | |
1 | * This file is part of yoob.js version 0.6 | |
2 | 2 | * Available from https://github.com/catseye/yoob.js/ |
3 | 3 | * This file is in the public domain. See http://unlicense.org/ for details. |
4 | 4 | */ |
0 | 0 | /* |
1 | * This file is part of yoob.js version 0.6-PRE | |
1 | * This file is part of yoob.js version 0.6 | |
2 | 2 | * Available from https://github.com/catseye/yoob.js/ |
3 | 3 | * This file is in the public domain. See http://unlicense.org/ for details. |
4 | 4 | */ |
5 | 5 | if (window.yoob === undefined) yoob = {}; |
6 | 6 | |
7 | 7 | /* |
8 | * An object representing a pointer (position vector) into two-dimensional | |
9 | * Cartesian space (possibly a yoob.Playfield) with a direction vector | |
10 | * (that need not be used). | |
8 | * An object representing a position and direction in some space. The space | |
9 | * may be one-dimensional (a yoob.Tape, or a string representing a program | |
10 | * source) or a two-dimensional Cartesian space (such as a yoob.Playfield.) | |
11 | * A direction vector accompanies the position, so the cursor can "know which | |
12 | * way it's headed", but this facility need not be used. | |
11 | 13 | * |
12 | 14 | * A cursor contains a built-in simple view, i.e. it knows how to render |
13 | 15 | * itself on a canvas (drawContext method) or in the midst of HTML text |
14 | * (wrapText method). These methods are used by the playfield view classes. | |
15 | * The supplied methods draw basic block cursors in the colour given by | |
16 | * the fillStyle attribute, if present, or a light green if it is not set. | |
16 | * (wrapText method). These methods are used by the view classes (playfield, | |
17 | * tape, source, etc.) The default methods draw basic block cursors in the | |
18 | * colour given by the fillStyle attribute, if present, or a light green if | |
19 | * it is not defined. | |
17 | 20 | */ |
18 | 21 | yoob.Cursor = function(x, y, dx, dy) { |
19 | 22 | this.x = x; |
20 | 23 | this.y = y; |
21 | 24 | this.dx = dx; |
22 | 25 | this.dy = dy; |
26 | ||
27 | this.getX = function() { | |
28 | return this.x; | |
29 | }; | |
30 | ||
31 | this.getY = function() { | |
32 | return this.y; | |
33 | }; | |
34 | ||
35 | this.setX = function(x) { | |
36 | this.x = x; | |
37 | }; | |
38 | ||
39 | this.setY = function(y) { | |
40 | this.y = y; | |
41 | }; | |
23 | 42 | |
24 | 43 | this.isHeaded = function(dx, dy) { |
25 | 44 | return this.dx === dx && this.dy === dy; |
70 | 89 | } |
71 | 90 | }; |
72 | 91 | |
92 | /* from yoob.TapeHead; may go away or change slightly */ | |
93 | this.move = function(delta) { | |
94 | this.x += delta; | |
95 | }; | |
96 | ||
97 | this.moveLeft = function(amount) { | |
98 | if (amount === undefined) amount = 1; | |
99 | this.x -= amount; | |
100 | }; | |
101 | ||
102 | this.moveRight = function(amount) { | |
103 | if (amount === undefined) amount = 1; | |
104 | this.x += amount; | |
105 | }; | |
106 | ||
107 | this.read = function() { | |
108 | if (!this.tape) return undefined; | |
109 | return this.tape.get(this.x); | |
110 | }; | |
111 | ||
112 | this.write = function(value) { | |
113 | if (!this.tape) return; | |
114 | this.tape.put(this.x, value); | |
115 | }; | |
116 | ||
73 | 117 | /* |
74 | 118 | * For HTML views. Override if you like. |
75 | 119 | */ |
0 | /* | |
1 | * This file is part of yoob.js version 0.6-PRE | |
2 | * Available from https://github.com/catseye/yoob.js/ | |
3 | * This file is in the public domain. See http://unlicense.org/ for details. | |
4 | */ | |
5 | if (window.yoob === undefined) yoob = {}; | |
6 | ||
7 | /* | |
8 | * An object for managing a set of example programs (or other "pre-fab" | |
9 | * things) for use in an esolang interpreter (or other thing that could | |
10 | * use these things. For example, games for an emulator, etc.) | |
11 | * | |
12 | * Mostly intended to be connected to a yoob.Controller. | |
13 | */ | |
14 | yoob.ExampleManager = function() { | |
15 | /* | |
16 | * The single argument is a dictionary (object) where the keys are: | |
17 | * selectElem: (required) the <select> DOM element that will be | |
18 | * populated with the available example programs. Selecting one | |
19 | * will cause the .select() method of this manager to be called. | |
20 | * it will also call .onselect if that method is present. | |
21 | */ | |
22 | this.init = function(cfg) { | |
23 | this.selectElem = cfg.selectElem; | |
24 | this.exampleClass = cfg.exampleClass || null; | |
25 | this.controller = cfg.controller || null; | |
26 | this.clear(); | |
27 | var $this = this; | |
28 | this.selectElem.onchange = function() { | |
29 | $this.select(this.options[this.selectedIndex].value); | |
30 | } | |
31 | return this; | |
32 | }; | |
33 | ||
34 | /* | |
35 | * Removes all options from the selectElem, and their associated data. | |
36 | */ | |
37 | this.clear = function() { | |
38 | this.reactTo = {}; | |
39 | while (this.selectElem.firstChild) { | |
40 | this.selectElem.removeChild(this.selectElem.firstChild); | |
41 | } | |
42 | this.add('(select one...)', function() {}); | |
43 | return this; | |
44 | }; | |
45 | ||
46 | /* | |
47 | * Adds an example to this ExampleManager. When it is selected, | |
48 | * the given callback will be called, being passed the id as the | |
49 | * first argument. If no callback is provided, a default callback, | |
50 | * which loads the contents of the element with the specified id | |
51 | * into the configured controller, will be used. | |
52 | */ | |
53 | this.add = function(id, callback) { | |
54 | var opt = document.createElement("option"); | |
55 | opt.text = id; | |
56 | opt.value = id; | |
57 | this.selectElem.options.add(opt); | |
58 | var $this = this; | |
59 | this.reactTo[id] = callback || function(id) { | |
60 | $this.controller.click_stop(); // in case it is currently running | |
61 | $this.controller.loadSourceFromHTML( | |
62 | document.getElementById(id).innerHTML | |
63 | ); | |
64 | }; | |
65 | return this; | |
66 | }; | |
67 | ||
68 | /* | |
69 | * Called by the selectElem's onchange event. For sanity, you should | |
70 | * probably not call this yourself. | |
71 | */ | |
72 | this.select = function(id) { | |
73 | this.reactTo[id](id); | |
74 | if (this.onselect) { | |
75 | this.onselect(id); | |
76 | } | |
77 | }; | |
78 | ||
79 | /* | |
80 | * When called, every DOM element in the document with the given | |
81 | * class will be considered an example program, and the manager | |
82 | * will be populated with these. Generally the CSS for the class | |
83 | * will have `display: none` and the elements will be <div>s. | |
84 | * | |
85 | * callback is as described for the .add() method. | |
86 | */ | |
87 | this.populateFromClass = function(className, callback) { | |
88 | var elements = document.getElementsByClassName(className); | |
89 | for (var i = 0; i < elements.length; i++) { | |
90 | var e = elements[i]; | |
91 | this.add(e.id, callback); | |
92 | } | |
93 | return this; | |
94 | }; | |
95 | }; |
0 | 0 | /* |
1 | * This file is part of yoob.js version 0.6-PRE | |
1 | * This file is part of yoob.js version 0.6 | |
2 | 2 | * Available from https://github.com/catseye/yoob.js/ |
3 | 3 | * This file is in the public domain. See http://unlicense.org/ for details. |
4 | 4 | */ |
0 | 0 | /* |
1 | * This file is part of yoob.js version 0.6-PRE | |
1 | * This file is part of yoob.js version 0.6 | |
2 | 2 | * Available from https://github.com/catseye/yoob.js/ |
3 | 3 | * This file is in the public domain. See http://unlicense.org/ for details. |
4 | 4 | */ |
0 | /* | |
1 | * This file is part of yoob.js version 0.6 | |
2 | * Available from https://github.com/catseye/yoob.js/ | |
3 | * This file is in the public domain. See http://unlicense.org/ for details. | |
4 | */ | |
5 | if (window.yoob === undefined) yoob = {}; | |
6 | ||
7 | /* | |
8 | * An object for managing a set of "presets" -- which, for an esolang, | |
9 | * might be example programs; for an emulator, might be ROM images; | |
10 | * for a control panel, may be pre-selected combinations of settings; | |
11 | * and so forth. | |
12 | * | |
13 | * Mostly intended to be connected to a yoob.Controller -- but need not be. | |
14 | */ | |
15 | yoob.PresetManager = function() { | |
16 | /* | |
17 | * The single argument is a dictionary (object) where the keys are: | |
18 | * | |
19 | * selectElem: (required) the <select> DOM element that will be | |
20 | * populated with the available example programs. Selecting one | |
21 | * will cause the .select() method of this manager to be called. | |
22 | * it will also call .onselect if that method is present. | |
23 | * | |
24 | * controller: a yoob.Controller (or compatible object) that will | |
25 | * be informed of the selection, if no callback was supplied | |
26 | * when the item was added. | |
27 | */ | |
28 | this.init = function(cfg) { | |
29 | this.selectElem = cfg.selectElem; | |
30 | this.controller = cfg.controller || null; | |
31 | this.clear(); | |
32 | var $this = this; | |
33 | this.selectElem.onchange = function() { | |
34 | $this._select(this.options[this.selectedIndex].value); | |
35 | } | |
36 | return this; | |
37 | }; | |
38 | ||
39 | /* | |
40 | * Removes all options from the selectElem, and their associated data. | |
41 | */ | |
42 | this.clear = function() { | |
43 | this.reactTo = {}; | |
44 | while (this.selectElem.firstChild) { | |
45 | this.selectElem.removeChild(this.selectElem.firstChild); | |
46 | } | |
47 | this.add('(select one...)', function() {}); | |
48 | return this; | |
49 | }; | |
50 | ||
51 | /* | |
52 | * Adds a preset to this PresetManager. When it is selected, | |
53 | * the given callback will be called, being passed the id as the | |
54 | * first argument. If no callback is provided, a default callback, | |
55 | * which loads the contents of the element with the specified id | |
56 | * into the configured yoob.Controller, will be used. | |
57 | */ | |
58 | this.add = function(id, callback) { | |
59 | var opt = document.createElement("option"); | |
60 | opt.text = id; | |
61 | opt.value = id; | |
62 | this.selectElem.options.add(opt); | |
63 | var $this = this; | |
64 | this.reactTo[id] = callback || function(id) { | |
65 | $this.controller.click_stop(); // in case it is currently running | |
66 | $this.controller.loadSourceFromHTML( | |
67 | document.getElementById(id).innerHTML | |
68 | ); | |
69 | }; | |
70 | return this; | |
71 | }; | |
72 | ||
73 | /* | |
74 | * Called by the selectElem's onchange event. For sanity, you should | |
75 | * probably not call this yourself. | |
76 | */ | |
77 | this._select = function(id) { | |
78 | this.reactTo[id](id); | |
79 | if (this.onselect) { | |
80 | this.onselect(id); | |
81 | } | |
82 | }; | |
83 | ||
84 | /* | |
85 | * Call this to programmatically select an item. This will change | |
86 | * the selected option in the selectElem and trigger the appropriate | |
87 | * callback in this PresetManager. | |
88 | */ | |
89 | this.select = function(id) { | |
90 | var i = 0; | |
91 | var opt = this.selectElem.options[i]; | |
92 | while (opt) { | |
93 | if (opt.value === id) { | |
94 | this.selectElem.selectedIndex = i; | |
95 | this._select(id); | |
96 | return this; | |
97 | } | |
98 | i++; | |
99 | opt = this.selectElem.options[i]; | |
100 | } | |
101 | // if not found, select the "(select one...)" option | |
102 | this.selectElem.selectedIndex = 0; | |
103 | return this; | |
104 | }; | |
105 | ||
106 | /* | |
107 | * When called, every DOM element in the document with the given | |
108 | * class will be considered a preset, and the manager | |
109 | * will be populated with these. Generally the CSS for the class | |
110 | * will have `display: none` and the elements will be <div>s. | |
111 | * | |
112 | * callback is as described for the .add() method. | |
113 | */ | |
114 | this.populateFromClass = function(className, callback) { | |
115 | var elements = document.getElementsByClassName(className); | |
116 | for (var i = 0; i < elements.length; i++) { | |
117 | var e = elements[i]; | |
118 | this.add(e.id, callback); | |
119 | } | |
120 | return this; | |
121 | }; | |
122 | }; |