Skip to content

Commit eec213d

Browse files
authored
De objectify (#421)
* remove more fields from classes, replace by function lookup * remove serviceClassName * remove serviceInstanceIndex field * fully remove TileType * remove serviceCommand * remove jdExternalClass * fix compile error * remove json.ts * remove defaultModifier * work in fieldEditor * more work * more fixes * fix up compile errors * refactor * remove abstract class * remove priority * kind to function * removing jdParam * finish jdParam * fix cast * explicitly allocate numbers to tids * fix up compile errors * fix range checks * jdParam2 * done with jdparam2 * separators * simplify constraint data structure * more changes * fix disallow * extract constraints to function * some minor fix and reformat * forgot a few tiles * negate terminal function * fix up sensor read of variable and radio receive * forgot mod radio value * fix up priority logic * removing maps... in progress * a few fixes * some casts * more refactoring * more errors * finish up all but topwriter * done with topwriter * all fixed * a few errors * another fix * create editor as needed * renaming * ranges inclusive * debugging * more debugging * fix deserialize on modifier * remove logging * fix regression of serviceCommandArg * update with new test * fix servo * missed a case! * fix enum error * passed! * comment out assembly * cleanup * reorder * fix up first instance logic * more rearranging
1 parent 43d4349 commit eec213d

17 files changed

+68726
-3107
lines changed

assets.ts

-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ namespace microcode {
189189
if (name == TID_ACTUATOR_RADIO_SEND) return icondb.radio_send
190190
if (name == TID_ACTUATOR_RADIO_SET_GROUP)
191191
return icondb.radio_set_group
192-
if (name == TID_ACTUATOR_MICROPHONE) return icondb.microphone
193192
if (name == TID_ACTUATOR_SPEAKER) return icondb.speakerFun
194193
if (name == TID_ACTUATOR_MUSIC) return icondb.music
195194

button.ts

-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ namespace microcode {
105105

106106
public get bounds() {
107107
// Returns bounds in local space
108-
// This isn't quite right, but it's close enough for now
109108
return Bounds.GrowXY(
110109
this.icon.bounds,
111110
borderLeft(this.style),

docs.ts

-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,6 @@ namespace docs {
360360
microcode.TID_ACTUATOR_SHOW_NUMBER,
361361
microcode.TID_ACTUATOR_RADIO_SEND,
362362
microcode.TID_ACTUATOR_RADIO_SET_GROUP,
363-
microcode.TID_ACTUATOR_MICROPHONE,
364363
microcode.TID_ACTUATOR_SPEAKER,
365364
microcode.TID_ACTUATOR_MUSIC,
366365

editor.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ namespace microcode {
1818
if (!skipBack) editor.forward()
1919
}
2020

21+
export function diskSlots() {
22+
return ["disk1", "disk2", "disk3"]
23+
}
24+
2125
export class Editor extends Scene {
2226
navigator: RuleRowNavigator
2327
private progdef: ProgramDefn
@@ -104,7 +108,7 @@ namespace microcode {
104108
private pickPage() {
105109
const btns: PickerButtonDef[] = PAGE_IDS().map(pageId => {
106110
return {
107-
icon: pageId,
111+
icon: getIcon(pageId) as string,
108112
}
109113
})
110114
this.picker.setGroup(btns)
@@ -120,7 +124,7 @@ namespace microcode {
120124
return
121125
}
122126
this.currPage = index
123-
this.pageBtn.setIcon(PAGE_IDS()[this.currPage])
127+
this.pageBtn.setIcon(getIcon(PAGE_IDS()[this.currPage]) as string)
124128
this.pageEditor = new PageEditor(
125129
this,
126130
this.scrollroot,
@@ -258,7 +262,7 @@ namespace microcode {
258262
this.pageBtn = new Button({
259263
parent: this.hudroot,
260264
style: ButtonStyles.BorderedPurple,
261-
icon: PAGE_IDS()[this.currPage],
265+
icon: getIcon(PAGE_IDS()[this.currPage]),
262266
x: Screen.RIGHT_EDGE - 12,
263267
y: 8,
264268
onClick: () => this.pickPage(),
@@ -406,7 +410,7 @@ namespace microcode {
406410

407411
/* override */ activate() {
408412
super.activate()
409-
this.pageBtn.setIcon(PAGE_IDS()[this.currPage])
413+
this.pageBtn.setIcon(tidToString(PAGE_IDS()[this.currPage]))
410414
if (!this.pageEditor) {
411415
this.switchToPage(this.currPage)
412416
}

fieldeditors.ts

+275-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,278 @@
11
namespace microcode {
2-
export function iconEditor(
2+
export function getFieldEditor(tile: Tile): FieldEditor {
3+
if (tile instanceof ModifierEditor) return tile.fieldEditor
4+
return undefined
5+
}
6+
7+
class FieldEditor {
8+
init(): any {
9+
return undefined
10+
}
11+
clone(field: any): any {
12+
return undefined
13+
}
14+
editor(
15+
field: any,
16+
picker: Picker,
17+
onHide: () => void,
18+
onDelete?: () => void
19+
): void {}
20+
toImage(field: any): Image {
21+
return undefined
22+
}
23+
toBuffer(field: any): Buffer {
24+
return undefined
25+
}
26+
fromBuffer(buf: BufferReader): any {
27+
return undefined
28+
}
29+
}
30+
31+
export class ModifierEditor {
32+
constructor(public tid: number) {
33+
this.firstInstance = false
34+
}
35+
fieldEditor: FieldEditor
36+
firstInstance: boolean
37+
getField(): any {
38+
return null
39+
}
40+
getIcon(): string | Image {
41+
return null
42+
}
43+
getNewInstance(field: any = null): ModifierEditor {
44+
return null
45+
}
46+
serviceCommandArg(): Buffer {
47+
return null
48+
}
49+
}
50+
51+
class IconFieldEditor extends FieldEditor {
52+
init() {
53+
return img`
54+
. . . . .
55+
. 1 . 1 .
56+
. . . . .
57+
1 . . . 1
58+
. 1 1 1 .
59+
`
60+
}
61+
clone(img: Image) {
62+
return img.clone()
63+
}
64+
editor(
65+
field: any,
66+
picker: Picker,
67+
onHide: () => void,
68+
onDelete?: () => void
69+
) {
70+
iconEditor(field, picker, onHide, onDelete)
71+
}
72+
toImage(field: any) {
73+
return icondb.renderMicrobitLEDs(field)
74+
}
75+
toBuffer(img: Image) {
76+
const ret = Buffer.create(4)
77+
for (let index = 0; index < 25; index++) {
78+
let byte = index >> 3
79+
let bit = index & 7
80+
let col = index % 5
81+
let row = Math.idiv(index, 5)
82+
ret[byte] |= img.getPixel(col, row) << bit
83+
}
84+
return ret
85+
}
86+
fromBuffer(br: BufferReader) {
87+
const buf = br.readBuffer(4)
88+
const img = image.create(5, 5)
89+
for (let index = 0; index < 25; index++) {
90+
let byte = index >> 3
91+
let bit = index & 7
92+
let col = index % 5
93+
let row = Math.idiv(index, 5)
94+
img.setPixel(col, row, (buf[byte] >> bit) & 1)
95+
}
96+
return img
97+
}
98+
}
99+
100+
export class IconEditor extends ModifierEditor {
101+
field: Image
102+
constructor(field: Image = null) {
103+
super(Tid.TID_MODIFIER_ICON_EDITOR)
104+
this.fieldEditor = new IconFieldEditor()
105+
this.field = this.fieldEditor.clone(
106+
field ? field : this.fieldEditor.init()
107+
)
108+
}
109+
110+
getField() {
111+
return this.field
112+
}
113+
114+
getIcon(): string | Image {
115+
return this.firstInstance
116+
? getIcon(Tid.TID_MODIFIER_ICON_EDITOR)
117+
: this.fieldEditor.toImage(this.field)
118+
}
119+
120+
getNewInstance(field: any = null) {
121+
return new IconEditor(field ? field : this.field.clone())
122+
}
123+
124+
serviceCommandArg() {
125+
const buf = Buffer.create(5)
126+
for (let col = 0; col < 5; ++col) {
127+
let v = 0
128+
for (let row = 0; row < 5; ++row) {
129+
if (this.field.getPixel(col, row)) v |= 1 << row
130+
}
131+
buf[col] = v
132+
}
133+
return buf
134+
}
135+
}
136+
137+
export interface Melody {
138+
notes: string
139+
tempo: number
140+
}
141+
142+
export const MELODY_LENGTH = 4
143+
export const NUM_NOTES = 5
144+
145+
//export const noteNames = ["C", "D", "E", "F", "G", "A", "B", "C", "D"]
146+
147+
function setNote(buf: Buffer, offset: number, note: string) {
148+
const noteToFreq: { [note: string]: number } = {
149+
"0": 261.63, // C4
150+
"1": 293.66, // D4
151+
"2": 329.63, // E4
152+
"3": 349.23, // F4
153+
"4": 392.0, // G4
154+
"5": 440.0, // A4
155+
"6": 493.88, // B4
156+
"7": 523.25, // C5
157+
"8": 587.33, // D5
158+
}
159+
160+
const period = 1000000 / (note !== "." ? noteToFreq[note] : 1000)
161+
const duty = note === "." ? 0 : (period * 0.5) / 2
162+
const duration = 250
163+
buf.setNumber(NumberFormat.UInt16LE, offset + 0, period)
164+
buf.setNumber(NumberFormat.UInt16LE, offset + 2, duty)
165+
buf.setNumber(NumberFormat.UInt16LE, offset + 4, duration)
166+
}
167+
168+
class MelodyFieldEditor extends FieldEditor {
169+
init() {
170+
return { notes: `0240`, tempo: 120 }
171+
}
172+
clone(melody: Melody) {
173+
return { notes: melody.notes.slice(0), tempo: melody.tempo }
174+
}
175+
editor(
176+
field: any,
177+
picker: Picker,
178+
onHide: () => void,
179+
onDelete?: () => void
180+
) {
181+
melodyEditor(field, picker, onHide, onDelete)
182+
}
183+
toImage(field: any) {
184+
return icondb.melodyToImage(field)
185+
}
186+
toBuffer(melody: Melody) {
187+
const buf = Buffer.create(3)
188+
buf.setUint8(0, melody.tempo)
189+
// convert the melody notes into list of integers
190+
const notes = melody.notes.split("")
191+
// fill the buffer with the notes, 4 bits for each note
192+
for (let i = 0; i < MELODY_LENGTH; i++) {
193+
const byte = i >> 1
194+
const bit = (i & 1) << 2
195+
if (notes[i] != ".") {
196+
const note = (parseInt(notes[i]) || 0) + 1
197+
buf.setUint8(
198+
byte + 1,
199+
buf.getUint8(byte + 1) | (note << bit)
200+
)
201+
}
202+
}
203+
return buf
204+
}
205+
fromBuffer(br: BufferReader) {
206+
const buf = br.readBuffer(3)
207+
const tempo = buf[0]
208+
let notes = ""
209+
// read the notes from the buffer
210+
for (let i = 0; i < MELODY_LENGTH; i++) {
211+
const byte = i >> 1
212+
const bit = (i & 1) << 2
213+
const note = (buf[byte + 1] >> bit) & 0xf
214+
notes += note == 0 ? "." : (note - 1).toString()
215+
}
216+
return { tempo, notes }
217+
}
218+
}
219+
220+
export class MelodyEditor extends ModifierEditor {
221+
field: Melody
222+
constructor(field: Melody = null) {
223+
super(Tid.TID_MODIFIER_MELODY_EDITOR)
224+
this.firstInstance = false
225+
this.fieldEditor = new MelodyFieldEditor()
226+
this.field = this.fieldEditor.clone(
227+
field ? field : this.fieldEditor.init()
228+
)
229+
}
230+
231+
getField() {
232+
return this.field
233+
}
234+
235+
getIcon(): string | Image {
236+
return this.firstInstance
237+
? getIcon(Tid.TID_MODIFIER_MELODY_EDITOR)
238+
: this.fieldEditor.toImage(this.field)
239+
}
240+
241+
getNewInstance(field: any = null) {
242+
return new MelodyEditor(
243+
field ? field : this.fieldEditor.clone(this.field)
244+
)
245+
}
246+
247+
serviceCommandArg() {
248+
const buf = Buffer.create(6 * 8)
249+
for (let i = 0; i < MELODY_LENGTH; i++) {
250+
setNote(buf, i * 6, this.field.notes[i])
251+
}
252+
return buf
253+
}
254+
}
255+
256+
let iconEditorTile: ModifierEditor = undefined
257+
let melodyEditorTile: ModifierEditor = undefined
258+
export function getEditor(tid: Tid): ModifierEditor {
259+
if (tid == Tid.TID_MODIFIER_ICON_EDITOR) {
260+
if (!iconEditorTile) {
261+
iconEditorTile = new IconEditor()
262+
iconEditorTile.firstInstance = true
263+
}
264+
return iconEditorTile
265+
} else if (tid == Tid.TID_MODIFIER_MELODY_EDITOR) {
266+
if (!melodyEditorTile) {
267+
melodyEditorTile = new MelodyEditor()
268+
melodyEditorTile.firstInstance = true
269+
}
270+
return melodyEditorTile
271+
}
272+
return undefined
273+
}
274+
275+
function iconEditor(
3276
image5x5: Image,
4277
picker: Picker,
5278
onHide: () => void,
@@ -44,7 +317,7 @@ namespace microcode {
44317
)
45318
}
46319

47-
export function melodyEditor(
320+
function melodyEditor(
48321
melody: Melody,
49322
picker: Picker,
50323
onHide: () => void,

jacs_stringify.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,9 @@ namespace jacs {
185185
/*
186186
const fmt = OP_PRINT_FMTS[op]
187187
if (!fmt) return `???oops op${op}`
188-
return expandFmt(fmt, t)
189-
*/
188+
return expandFmt(fmt, t)
189+
*/
190+
190191
return "uncomment"
191192
}
192193
}

0 commit comments

Comments
 (0)