Skip to content

Commit 103fc2d

Browse files
authored
pointers
1 parent 66a717a commit 103fc2d

File tree

2 files changed

+303
-26
lines changed

2 files changed

+303
-26
lines changed

src/extension-support/extension-manager.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ const defaultBuiltinExtensions = {
169169
jwScope: () => require("../extensions/jwScope"),
170170
// NEW xml extension
171171
jwXML: () => require("../extensions/jwXML"),
172+
// pointers
173+
jwPointer: () => require("../extensions/jwPointer")
172174

173175
// jw: They'll think its made by jwklong >:)
174176
// (but it's not (yet (maybe (probably not (but its made by ianyourgod)))))

src/extensions/jwPointer/index.js

Lines changed: 301 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,337 @@
1-
const BlockType = require('../../extension-support/block-type')
2-
const BlockShape = require('../../extension-support/block-shape')
3-
const ArgumentType = require('../../extension-support/argument-type')
4-
const TargetType = require('../../extension-support/target-type')
5-
const Cast = require('../../util/cast')
1+
const BlockType = require('../../extension-support/block-type');
2+
const BlockShape = require('../../extension-support/block-shape');
3+
const ArgumentType = require('../../extension-support/argument-type');
4+
const Cast = require('../../util/cast');
65

7-
class Pointer {
8-
constructor(value) {
9-
if (value === undefined) value = null
10-
this.id = jwPointer.pointers.push(value) - 1
6+
function span(text) {
7+
let el = document.createElement('span')
8+
el.innerHTML = text
9+
el.style.display = 'hidden'
10+
el.style.width = '100%'
11+
el.style.boxSizing = 'border-box'
12+
el.style.textAlign = 'center'
13+
return el
14+
}
15+
16+
const pointerLimit = Number.MAX_SAFE_INTEGER;
17+
let currentPointerID = 0;
18+
19+
const pointers = new Map();
20+
21+
class PointerType {
22+
customId = "jwPointer"
23+
24+
constructor(pointerID) {
25+
this.pointerID = pointerID;
26+
}
27+
28+
static create() {
29+
currentPointerID++;
30+
let id = currentPointerID;
31+
if (currentPointerID == pointerLimit) currentPointerID = 0; // your a madman if you achieve this
32+
33+
let pointer = new PointerType(id);
34+
pointer.init();
35+
return pointer;
36+
}
37+
38+
static toPointer(x) {
39+
if (x instanceof PointerType) return x;
40+
41+
let num = Cast.toNumber(x);
42+
if (num <= pointerLimit) return new PointerType(num);
43+
44+
return new PointerType(0);
45+
}
46+
47+
init() {
48+
pointers.set(this.pointerID, null);
49+
}
50+
51+
destroy() {
52+
pointers.delete(this.pointerID);
1153
}
1254

1355
get value() {
14-
return jwPointer.pointers[this.id] === undefined ? null : jwPointer.pointers[this.id]
56+
let value = pointers.get(this.pointerID);
57+
if (value === undefined) {
58+
return null;
59+
}
60+
return value;
61+
}
62+
63+
set value(value) {
64+
if (pointers.get(this.pointerID) === undefined) return;
65+
pointers.set(this.pointerID, value);
66+
}
67+
68+
jwArrayHandler() {
69+
if (this.value === undefined) return "Pointer";
70+
if (this.value === null) return "Pointer&lt;null&gt;";
71+
if (this.value instanceof PointerType) return "Pointer&lt;...&gt;";
72+
if (this.value.jwArrayHandler) return `Pointer&lt;${this.value.jwArrayHandler()}&gt;`;
73+
return `Pointer&lt;${vm.jwArray.Type.display(this.value)}&gt;`;
1574
}
1675

1776
toString() {
18-
return Cast.toString(this.value)
77+
return this.pointerID.toString();
78+
}
79+
80+
toReporterContent() {
81+
let destroyed = pointers.get(this.pointerID) === undefined;
82+
83+
let root = document.createElement('div')
84+
root.style.display = "flex";
85+
root.style.flexDirection = "column";
86+
root.style.maxWidth = "100%";
87+
let pointer = span(`Pointer | ${destroyed ? "Invalid" : this.pointerID}`);
88+
pointer.style.opacity = "0.5";
89+
root.appendChild(pointer);
90+
if (!destroyed) {
91+
let value = (this.value !== null && this.value.toReporterContent) ? this.value.toReporterContent() : span(this.value);
92+
if (value === null) value = span("null");
93+
value.style.maxWidth = "100%";
94+
value.style.overflow = "auto";
95+
root.appendChild(value);
96+
}
97+
return root
1998
}
2099
}
21100

22-
let jwPointer = {
23-
Type: Pointer,
101+
const Pointer = {
102+
Type: PointerType,
24103
Block: {
25104
blockType: BlockType.REPORTER,
26-
forceOutputType: "jwPointer",
105+
forceOutputType: "Pointer",
27106
disableMonitor: true
28107
},
29108
Argument: {
30-
check: ["jwPointer"]
31-
},
32-
33-
pointers: []
34-
}
109+
check: ["Pointer"]
110+
}
111+
};
35112

36113
class Extension {
37114
constructor() {
38-
vm.jwPointer = jwPointer
115+
vm.jwPointer = Pointer
116+
vm.runtime.registerSerializer(
117+
"jwPointer",
118+
v => [v.pointerID, pointers.get(v.pointerID) !== undefined],
119+
v => {
120+
currentPointerID = Math.max(v[0]+1, currentPointerID);
121+
return new Pointer.Type(v[0]);
122+
}
123+
);
124+
125+
vm.runtime.on("PROJECT_START", this.destroyAll.bind(this))
39126
}
40127

41128
getInfo() {
42129
return {
43130
id: "jwPointer",
44131
name: "Pointers",
132+
color1: "#8511d3",
133+
menuIconURI: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCI+CiAgPGVsbGlwc2Ugc3R5bGU9InN0cm9rZS1saW5lam9pbjogcm91bmQ7IHBhaW50LW9yZGVyOiBmaWxsOyBzdHJva2Utd2lkdGg6IDE7IGZpbGw6IHJnYigxMzMsIDE3LCAyMTEpOyBzdHJva2U6IHJnYigxMDYsIDE0LCAxNjkpOyIgY3g9IjEwIiBjeT0iMTAiIHJ4PSI5LjUiIHJ5PSI5LjUiPjwvZWxsaXBzZT4KICA8cGF0aCBkPSJNIDUuMjIzIDguNTMgQyA0LjczMiA4LjUzIDQuNDg4IDguNzc2IDQuNDg4IDkuMjY1IEwgNC40ODggMTAuODgyIEMgNC40ODggMTEuMjc0IDQuNzMyIDExLjQ3IDUuMjIzIDExLjQ3IEwgOC44OTggMTEuNDcgQyA5LjcwOSAxMS40NyAxMC4zNjggMTIuMTI4IDEwLjM2OCAxMi45NCBMIDEwLjM2OCAxNC40MDkgQyAxMC4zNjggMTUuMzkgMTAuODU3IDE1LjM5IDExLjgzNyAxNC40MDkgTCAxNC43NzcgMTEuNDcgQyAxNS43NTYgMTAuNDg5IDE1Ljc1NiA5LjUxMSAxNC43NzcgOC41MyBMIDExLjgzNyA1LjU5MSBDIDEwLjg1NyA0LjYxIDEwLjM2OCA0LjYxIDEwLjM2OCA1LjU5MSBMIDEwLjM2OCA3LjA2IEMgMTAuMzY4IDcuODcyIDkuNzA5IDguNTMgOC44OTggOC41MyBMIDUuMjIzIDguNTMgWiIgZmlsbD0iI2ZmZiIgc3R5bGU9InN0cm9rZS13aWR0aDogMTsiPjwvcGF0aD4KPC9zdmc+",
45134
blocks: [
46135
{
47-
opcode: 'create',
48-
text: 'create pointer [VALUE]',
136+
opcode: "create",
137+
text: "create pointer",
138+
...Pointer.Block
139+
},
140+
{
141+
opcode: "createC",
142+
text: "create pointer",
143+
blockType: BlockType.COMMAND,
144+
},
145+
{
146+
opcode: "createData",
147+
text: "create pointer to data [DATA]",
49148
arguments: {
50-
VALUE: {
149+
DATA: {
51150
type: ArgumentType.STRING,
151+
defaultValue: "data",
52152
exemptFromNormalization: true
53153
}
54154
},
55-
...jwPointer.Block
155+
...Pointer.Block
156+
},
157+
{
158+
opcode: "createDataC",
159+
text: "create pointer to data [DATA]",
160+
blockType: BlockType.COMMAND,
161+
arguments: {
162+
DATA: {
163+
type: ArgumentType.STRING,
164+
defaultValue: "data",
165+
exemptFromNormalization: true
166+
}
167+
}
56168
},
169+
"---",
170+
{
171+
opcode: "findID",
172+
text: "get pointer of ID [ID]",
173+
arguments: {
174+
ID: {
175+
type: ArgumentType.NUMBER,
176+
defaultValue: 0
177+
}
178+
},
179+
...Pointer.Block
180+
},
181+
"---",
182+
{
183+
opcode: "getData",
184+
text: "value of [POINTER]",
185+
blockType: BlockType.REPORTER,
186+
allowDropAnywhere: true,
187+
arguments: {
188+
POINTER: Pointer.Argument
189+
}
190+
},
191+
{
192+
opcode: "getID",
193+
text: "ID of [POINTER]",
194+
blockType: BlockType.REPORTER,
195+
arguments: {
196+
POINTER: Pointer.Argument
197+
}
198+
},
199+
{
200+
opcode: "isDestroyed",
201+
text: "is [POINTER] valid?",
202+
blockType: BlockType.BOOLEAN,
203+
arguments: {
204+
POINTER: Pointer.Argument
205+
}
206+
},
207+
"---",
208+
{
209+
opcode: "setData",
210+
text: "set [POINTER] to [DATA]",
211+
blockType: BlockType.COMMAND,
212+
arguments: {
213+
POINTER: Pointer.Argument,
214+
DATA: {
215+
type: ArgumentType.STRING,
216+
defaultValue: "data",
217+
exemptFromNormalization: true
218+
}
219+
}
220+
},
221+
{
222+
opcode: "changeData",
223+
text: "change [POINTER] by [AMOUNT]",
224+
blockType: BlockType.COMMAND,
225+
arguments: {
226+
POINTER: Pointer.Argument,
227+
AMOUNT: {
228+
type: ArgumentType.NUMBER,
229+
defaultValue: 1
230+
}
231+
}
232+
},
233+
"---",
234+
{
235+
opcode: "destroy",
236+
text: "delete [POINTER]",
237+
blockType: BlockType.COMMAND,
238+
arguments: {
239+
POINTER: Pointer.Argument
240+
}
241+
},
242+
{
243+
opcode: "destroyAll",
244+
text: "delete all pointers",
245+
blockType: BlockType.COMMAND
246+
},
247+
"---",
248+
{
249+
opcode: "lastID",
250+
text: "last pointer ID",
251+
blockType: BlockType.REPORTER
252+
},
253+
...(vm.runtime.ext_jwArray ? ["---"] : []),
254+
{
255+
opcode: "allPointers",
256+
text: "all pointers",
257+
blockType: BlockType.REPORTER,
258+
blockShape: BlockShape.SQUARE,
259+
hideFromPalette: !vm.runtime.ext_jwArray,
260+
...(vm.jwArray ? vm.jwArray.Block : {})
261+
}
57262
]
58-
};
263+
}
264+
}
265+
266+
create() {
267+
return Pointer.Type.create();
268+
}
269+
270+
createC() {
271+
Pointer.Type.create();
272+
}
273+
274+
createData({DATA}) {
275+
let pointer = Pointer.Type.create();
276+
pointer.value = DATA;
277+
return pointer;
278+
}
279+
280+
createDataC({DATA}) {
281+
Pointer.Type.create().value = DATA;
282+
}
283+
284+
findID({ID}) {
285+
ID = Cast.toNumber(ID);
286+
if (pointers.get(ID) === undefined) return new Pointer.Type(0);
287+
return Pointer.Type.toPointer(ID);
288+
}
289+
290+
getData({POINTER}) {
291+
POINTER = Pointer.Type.toPointer(POINTER);
292+
return POINTER.value;
293+
}
294+
295+
getID({POINTER}) {
296+
POINTER = Pointer.Type.toPointer(POINTER);
297+
return POINTER.pointerID;
298+
}
299+
300+
isDestroyed({POINTER}) {
301+
POINTER = Pointer.Type.toPointer(POINTER);
302+
return pointers.get(POINTER.pointerID) === undefined;
303+
}
304+
305+
setData({POINTER, DATA}) {
306+
POINTER = Pointer.Type.toPointer(POINTER);
307+
POINTER.value = DATA;
308+
}
309+
310+
changeData({POINTER, AMOUNT}) {
311+
POINTER = Pointer.Type.toPointer(POINTER);
312+
AMOUNT = Cast.toNumber(AMOUNT);
313+
314+
POINTER.value = Cast.toNumber(POINTER.value) + AMOUNT;
315+
}
316+
317+
destroy({POINTER}) {
318+
POINTER = Pointer.Type.toPointer(POINTER);
319+
POINTER.destroy();
320+
}
321+
322+
destroyAll() {
323+
pointers.clear();
324+
}
325+
326+
lastID() {
327+
return currentPointerID;
328+
}
329+
330+
allPointers() {
331+
if (!vm.jwArray) return 0;
332+
let array = Array.from(pointers.keys()).map(v => new Pointer.Type(v));
333+
return vm.jwArray.Type.toArray(array);
59334
}
60335
}
61336

62-
module.exports = Extension
337+
module.exports = Extension;

0 commit comments

Comments
 (0)