hikkaku 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +25 -0
- package/src/blocks/control.ts +169 -0
- package/src/blocks/data.ts +203 -0
- package/src/blocks/events.ts +116 -0
- package/src/blocks/index.ts +9 -0
- package/src/blocks/looks.ts +189 -0
- package/src/blocks/motion.ts +146 -0
- package/src/blocks/operator.ts +219 -0
- package/src/blocks/procedures.ts +208 -0
- package/src/blocks/sensing.ts +129 -0
- package/src/blocks/sound.ts +77 -0
- package/src/client/fiber.ts +110 -0
- package/src/client/index.ts +26 -0
- package/src/client/types.ts +7 -0
- package/src/compiler/block-helper.ts +49 -0
- package/src/compiler/composer.ts +177 -0
- package/src/compiler/index.ts +6 -0
- package/src/compiler/project.ts +138 -0
- package/src/compiler/types.ts +37 -0
- package/src/index.ts +5 -0
- package/src/utils/assets.ts +4 -0
- package/src/vite/env.ts +46 -0
- package/src/vite/index.ts +77 -0
- package/tsconfig.json +3 -0
- package/tsdown.config.ts +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { fromPrimitiveSource } from '../compiler/block-helper'
|
|
2
|
+
import { block, valueBlock } from '../compiler/composer'
|
|
3
|
+
import type { PrimitiveSource } from '../compiler/types'
|
|
4
|
+
|
|
5
|
+
export const moveSteps = (steps: PrimitiveSource<number>) => {
|
|
6
|
+
return block('motion_movesteps', {
|
|
7
|
+
inputs: {
|
|
8
|
+
STEPS: fromPrimitiveSource(steps),
|
|
9
|
+
},
|
|
10
|
+
})
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const gotoXY = (
|
|
14
|
+
x: PrimitiveSource<number>,
|
|
15
|
+
y: PrimitiveSource<number>,
|
|
16
|
+
) => {
|
|
17
|
+
return block('motion_gotoxy', {
|
|
18
|
+
inputs: {
|
|
19
|
+
X: fromPrimitiveSource(x),
|
|
20
|
+
Y: fromPrimitiveSource(y),
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const changeXBy = (dx: PrimitiveSource<number>) => {
|
|
26
|
+
return block('motion_changexby', {
|
|
27
|
+
inputs: {
|
|
28
|
+
DX: fromPrimitiveSource(dx),
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const changeYBy = (dy: PrimitiveSource<number>) => {
|
|
34
|
+
return block('motion_changeyby', {
|
|
35
|
+
inputs: {
|
|
36
|
+
DY: fromPrimitiveSource(dy),
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const setX = (x: PrimitiveSource<number>) => {
|
|
42
|
+
return block('motion_setx', {
|
|
43
|
+
inputs: {
|
|
44
|
+
X: fromPrimitiveSource(x),
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const setY = (y: PrimitiveSource<number>) => {
|
|
50
|
+
return block('motion_sety', {
|
|
51
|
+
inputs: {
|
|
52
|
+
Y: fromPrimitiveSource(y),
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const goTo = (target: string) => {
|
|
58
|
+
return block('motion_goto', {
|
|
59
|
+
fields: {
|
|
60
|
+
TO: [target, null],
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const turnRight = (degrees: PrimitiveSource<number>) => {
|
|
66
|
+
return block('motion_turnright', {
|
|
67
|
+
inputs: {
|
|
68
|
+
DEGREES: fromPrimitiveSource(degrees),
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const turnLeft = (degrees: PrimitiveSource<number>) => {
|
|
74
|
+
return block('motion_turnleft', {
|
|
75
|
+
inputs: {
|
|
76
|
+
DEGREES: fromPrimitiveSource(degrees),
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const pointInDirection = (direction: PrimitiveSource<number>) => {
|
|
82
|
+
return block('motion_pointindirection', {
|
|
83
|
+
inputs: {
|
|
84
|
+
DIRECTION: fromPrimitiveSource(direction),
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const pointTowards = (target: string) => {
|
|
90
|
+
return block('motion_pointtowards', {
|
|
91
|
+
fields: {
|
|
92
|
+
TOWARDS: [target, null],
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export const glide = (
|
|
98
|
+
seconds: PrimitiveSource<number>,
|
|
99
|
+
x: PrimitiveSource<number>,
|
|
100
|
+
y: PrimitiveSource<number>,
|
|
101
|
+
) => {
|
|
102
|
+
return block('motion_glidesecstoxy', {
|
|
103
|
+
inputs: {
|
|
104
|
+
SECS: fromPrimitiveSource(seconds),
|
|
105
|
+
X: fromPrimitiveSource(x),
|
|
106
|
+
Y: fromPrimitiveSource(y),
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const glideTo = (seconds: PrimitiveSource<number>, target: string) => {
|
|
112
|
+
return block('motion_glideto', {
|
|
113
|
+
inputs: {
|
|
114
|
+
SECS: fromPrimitiveSource(seconds),
|
|
115
|
+
},
|
|
116
|
+
fields: {
|
|
117
|
+
TO: [target, null],
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const ifOnEdgeBounce = () => {
|
|
123
|
+
return block('motion_ifonedgebounce', {})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const setRotationStyle = (
|
|
127
|
+
style: 'all around' | 'left-right' | "don't rotate",
|
|
128
|
+
) => {
|
|
129
|
+
return block('motion_setrotationstyle', {
|
|
130
|
+
fields: {
|
|
131
|
+
STYLE: [style, null],
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const getX = () => {
|
|
137
|
+
return valueBlock('motion_xposition', {})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const getY = () => {
|
|
141
|
+
return valueBlock('motion_yposition', {})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const getDirection = () => {
|
|
145
|
+
return valueBlock('motion_direction', {})
|
|
146
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { fromPrimitiveSource } from '../compiler/block-helper'
|
|
2
|
+
import { valueBlock } from '../compiler/composer'
|
|
3
|
+
import type { PrimitiveSource } from '../compiler/types'
|
|
4
|
+
|
|
5
|
+
export const add = (a: PrimitiveSource<number>, b: PrimitiveSource<number>) => {
|
|
6
|
+
return valueBlock('operator_add', {
|
|
7
|
+
inputs: {
|
|
8
|
+
NUM1: fromPrimitiveSource(a),
|
|
9
|
+
NUM2: fromPrimitiveSource(b),
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const subtract = (
|
|
15
|
+
a: PrimitiveSource<number>,
|
|
16
|
+
b: PrimitiveSource<number>,
|
|
17
|
+
) => {
|
|
18
|
+
return valueBlock('operator_subtract', {
|
|
19
|
+
inputs: {
|
|
20
|
+
NUM1: fromPrimitiveSource(a),
|
|
21
|
+
NUM2: fromPrimitiveSource(b),
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const multiply = (
|
|
27
|
+
a: PrimitiveSource<number>,
|
|
28
|
+
b: PrimitiveSource<number>,
|
|
29
|
+
) => {
|
|
30
|
+
return valueBlock('operator_multiply', {
|
|
31
|
+
inputs: {
|
|
32
|
+
NUM1: fromPrimitiveSource(a),
|
|
33
|
+
NUM2: fromPrimitiveSource(b),
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const divide = (
|
|
39
|
+
a: PrimitiveSource<number>,
|
|
40
|
+
b: PrimitiveSource<number>,
|
|
41
|
+
) => {
|
|
42
|
+
return valueBlock('operator_divide', {
|
|
43
|
+
inputs: {
|
|
44
|
+
NUM1: fromPrimitiveSource(a),
|
|
45
|
+
NUM2: fromPrimitiveSource(b),
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const lt = (
|
|
51
|
+
a: PrimitiveSource<number | string>,
|
|
52
|
+
b: PrimitiveSource<number | string>,
|
|
53
|
+
) => {
|
|
54
|
+
return valueBlock('operator_lt', {
|
|
55
|
+
inputs: {
|
|
56
|
+
OPERAND1: fromPrimitiveSource(a),
|
|
57
|
+
OPERAND2: fromPrimitiveSource(b),
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const equals = (
|
|
63
|
+
a: PrimitiveSource<number | string>,
|
|
64
|
+
b: PrimitiveSource<number | string>,
|
|
65
|
+
) => {
|
|
66
|
+
return valueBlock('operator_equals', {
|
|
67
|
+
inputs: {
|
|
68
|
+
OPERAND1: fromPrimitiveSource(a),
|
|
69
|
+
OPERAND2: fromPrimitiveSource(b),
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const gt = (
|
|
75
|
+
a: PrimitiveSource<number | string>,
|
|
76
|
+
b: PrimitiveSource<number | string>,
|
|
77
|
+
) => {
|
|
78
|
+
return valueBlock('operator_gt', {
|
|
79
|
+
inputs: {
|
|
80
|
+
OPERAND1: fromPrimitiveSource(a),
|
|
81
|
+
OPERAND2: fromPrimitiveSource(b),
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const and = (
|
|
87
|
+
a: PrimitiveSource<boolean>,
|
|
88
|
+
b: PrimitiveSource<boolean>,
|
|
89
|
+
) => {
|
|
90
|
+
return valueBlock('operator_and', {
|
|
91
|
+
inputs: {
|
|
92
|
+
OPERAND1: fromPrimitiveSource(a),
|
|
93
|
+
OPERAND2: fromPrimitiveSource(b),
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export const or = (
|
|
99
|
+
a: PrimitiveSource<boolean>,
|
|
100
|
+
b: PrimitiveSource<boolean>,
|
|
101
|
+
) => {
|
|
102
|
+
return valueBlock('operator_or', {
|
|
103
|
+
inputs: {
|
|
104
|
+
OPERAND1: fromPrimitiveSource(a),
|
|
105
|
+
OPERAND2: fromPrimitiveSource(b),
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export const not = (operand: PrimitiveSource<boolean>) => {
|
|
111
|
+
return valueBlock('operator_not', {
|
|
112
|
+
inputs: {
|
|
113
|
+
OPERAND: fromPrimitiveSource(operand),
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const random = (
|
|
119
|
+
from: PrimitiveSource<number>,
|
|
120
|
+
to: PrimitiveSource<number>,
|
|
121
|
+
) => {
|
|
122
|
+
return valueBlock('operator_random', {
|
|
123
|
+
inputs: {
|
|
124
|
+
FROM: fromPrimitiveSource(from),
|
|
125
|
+
TO: fromPrimitiveSource(to),
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const join = (
|
|
131
|
+
a: PrimitiveSource<string>,
|
|
132
|
+
b: PrimitiveSource<string>,
|
|
133
|
+
) => {
|
|
134
|
+
return valueBlock('operator_join', {
|
|
135
|
+
inputs: {
|
|
136
|
+
STRING1: fromPrimitiveSource(a),
|
|
137
|
+
STRING2: fromPrimitiveSource(b),
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const letterOf = (
|
|
143
|
+
letter: PrimitiveSource<number>,
|
|
144
|
+
text: PrimitiveSource<string>,
|
|
145
|
+
) => {
|
|
146
|
+
return valueBlock('operator_letter_of', {
|
|
147
|
+
inputs: {
|
|
148
|
+
LETTER: fromPrimitiveSource(letter),
|
|
149
|
+
STRING: fromPrimitiveSource(text),
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export const length = (text: PrimitiveSource<string>) => {
|
|
155
|
+
return valueBlock('operator_length', {
|
|
156
|
+
inputs: {
|
|
157
|
+
STRING: fromPrimitiveSource(text),
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const contains = (
|
|
163
|
+
text: PrimitiveSource<string>,
|
|
164
|
+
substring: PrimitiveSource<string>,
|
|
165
|
+
) => {
|
|
166
|
+
return valueBlock('operator_contains', {
|
|
167
|
+
inputs: {
|
|
168
|
+
STRING1: fromPrimitiveSource(text),
|
|
169
|
+
STRING2: fromPrimitiveSource(substring),
|
|
170
|
+
},
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export const mod = (a: PrimitiveSource<number>, b: PrimitiveSource<number>) => {
|
|
175
|
+
return valueBlock('operator_mod', {
|
|
176
|
+
inputs: {
|
|
177
|
+
NUM1: fromPrimitiveSource(a),
|
|
178
|
+
NUM2: fromPrimitiveSource(b),
|
|
179
|
+
},
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export const round = (value: PrimitiveSource<number>) => {
|
|
184
|
+
return valueBlock('operator_round', {
|
|
185
|
+
inputs: {
|
|
186
|
+
NUM: fromPrimitiveSource(value),
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export type MathOpOperator =
|
|
192
|
+
| 'abs'
|
|
193
|
+
| 'floor'
|
|
194
|
+
| 'ceiling'
|
|
195
|
+
| 'sqrt'
|
|
196
|
+
| 'sin'
|
|
197
|
+
| 'cos'
|
|
198
|
+
| 'tan'
|
|
199
|
+
| 'asin'
|
|
200
|
+
| 'acos'
|
|
201
|
+
| 'atan'
|
|
202
|
+
| 'ln'
|
|
203
|
+
| 'log'
|
|
204
|
+
| 'e ^'
|
|
205
|
+
| '10 ^'
|
|
206
|
+
|
|
207
|
+
export const mathop = (
|
|
208
|
+
operator: MathOpOperator,
|
|
209
|
+
value: PrimitiveSource<number>,
|
|
210
|
+
) => {
|
|
211
|
+
return valueBlock('operator_mathop', {
|
|
212
|
+
inputs: {
|
|
213
|
+
NUM: fromPrimitiveSource(value),
|
|
214
|
+
},
|
|
215
|
+
fields: {
|
|
216
|
+
OPERATOR: [operator, null],
|
|
217
|
+
},
|
|
218
|
+
})
|
|
219
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { fromPrimitiveSource } from '../compiler/block-helper'
|
|
2
|
+
import { block, valueBlock } from '../compiler/composer'
|
|
3
|
+
import type { PrimitiveSource } from '../compiler/types'
|
|
4
|
+
|
|
5
|
+
export type ProcedureArgumentDefault = string | boolean
|
|
6
|
+
|
|
7
|
+
export interface ProcedureProcLabel {
|
|
8
|
+
type: 'label'
|
|
9
|
+
text: string
|
|
10
|
+
}
|
|
11
|
+
export interface ProcedureProcBoolean<T = string> {
|
|
12
|
+
type: 'boolean'
|
|
13
|
+
name: T
|
|
14
|
+
}
|
|
15
|
+
export interface ProcedureProcStringOrNumber<T = string> {
|
|
16
|
+
type: 'stringOrNumber'
|
|
17
|
+
name: T
|
|
18
|
+
}
|
|
19
|
+
export type ProcedureProc =
|
|
20
|
+
| ProcedureProcLabel
|
|
21
|
+
| ProcedureProcBoolean
|
|
22
|
+
| ProcedureProcStringOrNumber
|
|
23
|
+
|
|
24
|
+
export const procedureLabel = (text: string): ProcedureProcLabel => {
|
|
25
|
+
return {
|
|
26
|
+
type: 'label',
|
|
27
|
+
text,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const procedureBoolean = <T extends string>(
|
|
32
|
+
name: T,
|
|
33
|
+
): ProcedureProcBoolean<T> => {
|
|
34
|
+
return {
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
name,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const procedureStringOrNumber = <T extends string>(
|
|
41
|
+
name: T,
|
|
42
|
+
): ProcedureProcStringOrNumber<T> => {
|
|
43
|
+
return {
|
|
44
|
+
type: 'stringOrNumber',
|
|
45
|
+
name,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type OnlyArgProc<T> = T extends { type: 'label' } ? never : T
|
|
50
|
+
|
|
51
|
+
export interface ProcedureReferenceBase {
|
|
52
|
+
isProcedureArgument: true
|
|
53
|
+
|
|
54
|
+
name: string
|
|
55
|
+
type: 'boolean' | 'stringOrNumber'
|
|
56
|
+
id: string
|
|
57
|
+
}
|
|
58
|
+
export interface ProcedureBooleanReference extends ProcedureReferenceBase {
|
|
59
|
+
type: 'boolean'
|
|
60
|
+
}
|
|
61
|
+
export interface ProcedureStringOrNumberReference
|
|
62
|
+
extends ProcedureReferenceBase {
|
|
63
|
+
type: 'stringOrNumber'
|
|
64
|
+
}
|
|
65
|
+
export type ProcedureReference =
|
|
66
|
+
| ProcedureBooleanReference
|
|
67
|
+
| ProcedureStringOrNumberReference
|
|
68
|
+
|
|
69
|
+
type ReferencesByProcs<T extends ProcedureProc[]> = {
|
|
70
|
+
[K in OnlyArgProc<T[number]>['name']]: OnlyArgProc<T[number]> extends {
|
|
71
|
+
type: infer U
|
|
72
|
+
}
|
|
73
|
+
? U extends 'boolean'
|
|
74
|
+
? ProcedureBooleanReference
|
|
75
|
+
: U extends 'stringOrNumber'
|
|
76
|
+
? ProcedureStringOrNumberReference
|
|
77
|
+
: never
|
|
78
|
+
: never
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const defineProcedure = <T extends ProcedureProc[]>(
|
|
82
|
+
proclist: T,
|
|
83
|
+
stack?: (references: ReferencesByProcs<T>) => void,
|
|
84
|
+
/**
|
|
85
|
+
* If true, the procedure will run without screen refresh until it completes.
|
|
86
|
+
* This can make the procedure run faster, but the screen will not update until the procedure is done.
|
|
87
|
+
*/
|
|
88
|
+
warp = false,
|
|
89
|
+
) => {
|
|
90
|
+
const proccode = proclist
|
|
91
|
+
.map((proc) => {
|
|
92
|
+
switch (proc.type) {
|
|
93
|
+
case 'label':
|
|
94
|
+
return proc.text
|
|
95
|
+
case 'boolean':
|
|
96
|
+
return '%b'
|
|
97
|
+
case 'stringOrNumber':
|
|
98
|
+
return '%s'
|
|
99
|
+
default:
|
|
100
|
+
throw new Error('Unknown procedure proc type')
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.join(' ')
|
|
104
|
+
|
|
105
|
+
const argumentProcs = proclist.filter((proc) => proc.type !== 'label')
|
|
106
|
+
|
|
107
|
+
const argumentids = argumentProcs.map(() => {
|
|
108
|
+
// Generate a random ID for each argument
|
|
109
|
+
return Math.random().toString(36).substring(2, 15)
|
|
110
|
+
})
|
|
111
|
+
const argumentnames = argumentProcs.map((proc) => {
|
|
112
|
+
return proc.name
|
|
113
|
+
})
|
|
114
|
+
const argumentdefaults = argumentProcs.map((proc) => {
|
|
115
|
+
switch (proc.type) {
|
|
116
|
+
case 'boolean':
|
|
117
|
+
return 'false'
|
|
118
|
+
case 'stringOrNumber':
|
|
119
|
+
return ''
|
|
120
|
+
default:
|
|
121
|
+
throw new Error('Unknown procedure proc type')
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const prototype = block('procedures_prototype', {
|
|
126
|
+
mutation: {
|
|
127
|
+
tagName: 'mutation',
|
|
128
|
+
children: [],
|
|
129
|
+
proccode,
|
|
130
|
+
argumentids: JSON.stringify(argumentids),
|
|
131
|
+
argumentnames: JSON.stringify(argumentnames),
|
|
132
|
+
argumentdefaults: JSON.stringify(argumentdefaults) as unknown as (
|
|
133
|
+
| string
|
|
134
|
+
| boolean
|
|
135
|
+
)[],
|
|
136
|
+
warp: warp.toString() as 'true' | 'false',
|
|
137
|
+
},
|
|
138
|
+
isShadow: true,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const definition = block('procedures_definition', {
|
|
142
|
+
inputs: {
|
|
143
|
+
custom_block: [1, prototype.id],
|
|
144
|
+
},
|
|
145
|
+
topLevel: true,
|
|
146
|
+
})
|
|
147
|
+
const references = Object.fromEntries(
|
|
148
|
+
argumentProcs.map((proc, index) => {
|
|
149
|
+
return [
|
|
150
|
+
proc.name,
|
|
151
|
+
{
|
|
152
|
+
isProcedureArgument: true,
|
|
153
|
+
name: proc.name,
|
|
154
|
+
type: proc.type,
|
|
155
|
+
id: argumentids[index],
|
|
156
|
+
} as ProcedureReference,
|
|
157
|
+
]
|
|
158
|
+
}),
|
|
159
|
+
)
|
|
160
|
+
stack?.(references as ReferencesByProcs<T>)
|
|
161
|
+
return definition
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export const callProcedure = (
|
|
165
|
+
proccode: string,
|
|
166
|
+
argumentIds: string[],
|
|
167
|
+
inputs: Record<string, PrimitiveSource<string | number | boolean>>,
|
|
168
|
+
warp = false,
|
|
169
|
+
) => {
|
|
170
|
+
const resolvedInputs: Record<
|
|
171
|
+
string,
|
|
172
|
+
ReturnType<typeof fromPrimitiveSource>
|
|
173
|
+
> = {}
|
|
174
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
175
|
+
resolvedInputs[key] = fromPrimitiveSource(value)
|
|
176
|
+
}
|
|
177
|
+
return block('procedures_call', {
|
|
178
|
+
inputs: resolvedInputs,
|
|
179
|
+
mutation: {
|
|
180
|
+
tagName: 'mutation',
|
|
181
|
+
children: [],
|
|
182
|
+
proccode,
|
|
183
|
+
argumentids: JSON.stringify(argumentIds),
|
|
184
|
+
warp,
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export const argumentReporterStringNumber = (
|
|
190
|
+
reference: ProcedureStringOrNumberReference,
|
|
191
|
+
) => {
|
|
192
|
+
return valueBlock('argument_reporter_string_number', {
|
|
193
|
+
fields: {
|
|
194
|
+
VALUE: [reference.name, null],
|
|
195
|
+
},
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export const argumentReporterBoolean = (
|
|
200
|
+
reference: ProcedureBooleanReference,
|
|
201
|
+
) => {
|
|
202
|
+
return valueBlock('argument_reporter_boolean', {
|
|
203
|
+
fields: {
|
|
204
|
+
VALUE: [reference.name, null],
|
|
205
|
+
},
|
|
206
|
+
isShadow: false,
|
|
207
|
+
})
|
|
208
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { fromPrimitiveSource } from '../compiler/block-helper'
|
|
2
|
+
import { block, valueBlock } from '../compiler/composer'
|
|
3
|
+
import type { PrimitiveSource } from '../compiler/types'
|
|
4
|
+
|
|
5
|
+
export const getMouseX = () => {
|
|
6
|
+
return valueBlock('sensing_mousex', {})
|
|
7
|
+
}
|
|
8
|
+
export const getMouseY = () => {
|
|
9
|
+
return valueBlock('sensing_mousey', {})
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type CurrentMenu =
|
|
13
|
+
| 'year'
|
|
14
|
+
| 'month'
|
|
15
|
+
| 'date'
|
|
16
|
+
| 'dayofweek'
|
|
17
|
+
| 'hour'
|
|
18
|
+
| 'minute'
|
|
19
|
+
| 'second'
|
|
20
|
+
export type DragMode = 'draggable' | 'not draggable'
|
|
21
|
+
|
|
22
|
+
export const touchingObject = (target: string) => {
|
|
23
|
+
return valueBlock('sensing_touchingobject', {
|
|
24
|
+
inputs: {
|
|
25
|
+
TOUCHINGOBJECTMENU: fromPrimitiveSource(target),
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const touchingColor = (color: PrimitiveSource<string>) => {
|
|
31
|
+
return valueBlock('sensing_touchingcolor', {
|
|
32
|
+
inputs: {
|
|
33
|
+
COLOR: fromPrimitiveSource(color),
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const colorTouchingColor = (
|
|
39
|
+
color: PrimitiveSource<string>,
|
|
40
|
+
targetColor: PrimitiveSource<string>,
|
|
41
|
+
) => {
|
|
42
|
+
return valueBlock('sensing_coloristouchingcolor', {
|
|
43
|
+
inputs: {
|
|
44
|
+
COLOR: fromPrimitiveSource(color),
|
|
45
|
+
COLOR2: fromPrimitiveSource(targetColor),
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const distanceTo = (target: string) => {
|
|
51
|
+
return valueBlock('sensing_distanceto', {
|
|
52
|
+
fields: {
|
|
53
|
+
DISTANCETOMENU: [target, null],
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const getTimer = () => {
|
|
59
|
+
return valueBlock('sensing_timer', {})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const resetTimer = () => {
|
|
63
|
+
return block('sensing_resettimer', {})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const setDragMode = (mode: DragMode) => {
|
|
67
|
+
return block('sensing_setdragmode', {
|
|
68
|
+
fields: {
|
|
69
|
+
DRAG_MODE: [mode, null],
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const getMouseDown = () => {
|
|
75
|
+
return valueBlock('sensing_mousedown', {})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const getKeyPressed = (key: PrimitiveSource<string>) => {
|
|
79
|
+
return valueBlock('sensing_keypressed', {
|
|
80
|
+
inputs: {
|
|
81
|
+
KEY_OPTION: fromPrimitiveSource(key),
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const current = (menu: CurrentMenu) => {
|
|
87
|
+
return valueBlock('sensing_current', {
|
|
88
|
+
fields: {
|
|
89
|
+
CURRENTMENU: [menu, null],
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const getAttributeOf = (property: string, target: string) => {
|
|
95
|
+
return valueBlock('sensing_of', {
|
|
96
|
+
fields: {
|
|
97
|
+
PROPERTY: [property, null],
|
|
98
|
+
OBJECT: [target, null],
|
|
99
|
+
},
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const daysSince2000 = () => {
|
|
104
|
+
return valueBlock('sensing_dayssince2000', {})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const getLoudness = () => {
|
|
108
|
+
return valueBlock('sensing_loudness', {})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const isLoud = () => {
|
|
112
|
+
return valueBlock('sensing_loud', {})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const askAndWait = (question: PrimitiveSource<string>) => {
|
|
116
|
+
return block('sensing_askandwait', {
|
|
117
|
+
inputs: {
|
|
118
|
+
QUESTION: fromPrimitiveSource(question),
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const getAnswer = () => {
|
|
124
|
+
return valueBlock('sensing_answer', {})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const getUsername = () => {
|
|
128
|
+
return valueBlock('sensing_username', {})
|
|
129
|
+
}
|