Skip to content

Commit a499551

Browse files
authored
Created BrsDevice static object with deviceInfo, registry and sharedArray (#469)
* Created `BrsDevice` static object with `deviceInfo`, `registry` and `sharedArray` * Reset `lastKeyTime` on app start
1 parent c76c8d3 commit a499551

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+290
-267
lines changed

src/core/BrsDevice.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { dataBufferIndex, DataType, DebugCommand } from "./common";
2+
3+
export class BrsDevice {
4+
static readonly deviceInfo: Map<string, any> = new Map<string, any>();
5+
static readonly registry: Map<string, string> = new Map<string, string>();
6+
static sharedArray: Int32Array = new Int32Array(0);
7+
static displayEnabled: boolean = true;
8+
static lastRemote: number = 0;
9+
static lastKeyTime: number = Date.now();
10+
static currKeyTime: number = Date.now();
11+
12+
/**
13+
* Updates the device registry with the provided data
14+
* @param registry Map with registry content.
15+
*/
16+
static setRegistry(registry: Map<string, string>) {
17+
registry.forEach((value: string, key: string) => {
18+
this.registry.set(key, value);
19+
});
20+
}
21+
22+
/**
23+
* Setup the device sharedArray
24+
* @param sharedArray Int32Array to be used as sharedArray
25+
*/
26+
static setSharedArray(sharedArray: Int32Array) {
27+
this.sharedArray = sharedArray;
28+
}
29+
30+
/**
31+
* Method to check if the Break Command is set in the sharedArray
32+
* @returns the last debug command
33+
*/
34+
static checkBreakCommand(debugMode: boolean): number {
35+
let cmd = debugMode ? DebugCommand.BREAK : -1;
36+
if (!debugMode) {
37+
cmd = Atomics.load(this.sharedArray, DataType.DBG);
38+
if (cmd === DebugCommand.BREAK) {
39+
Atomics.store(this.sharedArray, DataType.DBG, -1);
40+
} else if (cmd === DebugCommand.PAUSE) {
41+
postMessage("debug,pause");
42+
Atomics.wait(this.sharedArray, DataType.DBG, DebugCommand.PAUSE);
43+
Atomics.store(this.sharedArray, DataType.DBG, -1);
44+
cmd = -1;
45+
postMessage("debug,continue");
46+
}
47+
}
48+
return cmd;
49+
}
50+
51+
/**
52+
* Method to extract the data buffer from the sharedArray
53+
* @returns the data buffer as a string
54+
*/
55+
static readDataBuffer(): string {
56+
let data = "";
57+
this.sharedArray.slice(dataBufferIndex).every((char) => {
58+
if (char > 0) {
59+
data += String.fromCharCode(char);
60+
}
61+
return char; // if \0 stops decoding
62+
});
63+
Atomics.store(this.sharedArray, DataType.BUF, -1);
64+
return data;
65+
}
66+
}
File renamed without changes.

src/core/brsTypes/components/BrsObjects.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export const BrsObjects = new BrsObjectsMap([
127127
["roEVPCipher", (_: Interpreter) => new RoEVPCipher()],
128128
["roEVPDigest", (_: Interpreter) => new RoEVPDigest()],
129129
["roHMAC", (_: Interpreter) => new RoHMAC()],
130-
["roDeviceCrypto", (interpreter: Interpreter) => new RoDeviceCrypto(interpreter)],
130+
["roDeviceCrypto", (_: Interpreter) => new RoDeviceCrypto()],
131131
["roChannelStore", (_: Interpreter) => new RoChannelStore()],
132132
["roDateTime", (_: Interpreter) => new RoDateTime()],
133133
["roList", (_: Interpreter) => new RoList()],
@@ -153,27 +153,26 @@ export const BrsObjects = new BrsObjectsMap([
153153
["roInput", (interpreter: Interpreter) => new RoInput(interpreter)],
154154
["roSystemLog", (interpreter: Interpreter) => new RoSystemLog(interpreter)],
155155
["roFileSystem", (_: Interpreter) => new RoFileSystem()],
156-
["roLocalization", (interpreter: Interpreter) => new RoLocalization(interpreter)],
156+
["roLocalization", (_: Interpreter) => new RoLocalization()],
157157
["roFontRegistry", (interpreter: Interpreter) => new RoFontRegistry(interpreter)],
158158
["roRegistry", (_: Interpreter) => new RoRegistry()],
159159
[
160160
"roRegistrySection",
161-
(interpreter: Interpreter, section: BrsString) =>
162-
new RoRegistrySection(interpreter, section),
161+
(_: Interpreter, section: BrsString) => new RoRegistrySection(section),
163162
1,
164163
],
165164
["roAppInfo", (_: Interpreter) => new RoAppInfo()],
166-
["roDeviceInfo", (interpreter: Interpreter) => new RoDeviceInfo(interpreter)],
165+
["roDeviceInfo", (_: Interpreter) => new RoDeviceInfo()],
167166
["roRemoteInfo", (_: Interpreter) => new RoRemoteInfo()],
168167
["roAppMemoryMonitor", (_: Interpreter) => new RoAppMemoryMonitor()],
169-
["roAudioPlayer", (interpreter: Interpreter) => new RoAudioPlayer(interpreter)],
168+
["roAudioPlayer", (_: Interpreter) => new RoAudioPlayer()],
170169
[
171170
"roAudioResource",
172171
(interpreter: Interpreter, name: BrsString) => createAudioResource(interpreter, name),
173172
1,
174173
],
175174
["roAudioMetadata", (_: Interpreter) => new RoAudioMetadata()],
176-
["roVideoPlayer", (interpreter: Interpreter) => new RoVideoPlayer(interpreter)],
175+
["roVideoPlayer", (_: Interpreter) => new RoVideoPlayer()],
177176
["roCompositor", (_: Interpreter) => new RoCompositor()],
178177
[
179178
"roRegion",
@@ -197,8 +196,8 @@ export const BrsObjects = new BrsObjectsMap([
197196
["roURLTransfer", (interpreter: Interpreter) => new RoURLTransfer(interpreter)],
198197
["roInvalid", (_: Interpreter) => new RoInvalid(), -1],
199198
["roNDK", (_: Interpreter) => new RoNDK()],
200-
["roCECStatus", (interpreter: Interpreter) => new RoCECStatus(interpreter)],
201-
["roHdmiStatus", (interpreter: Interpreter) => new RoHdmiStatus(interpreter)],
199+
["roCECStatus", (_: Interpreter) => new RoCECStatus()],
200+
["roHdmiStatus", (_: Interpreter) => new RoHdmiStatus()],
202201
["roSocketAddress", (interpreter: Interpreter) => new RoSocketAddress(interpreter)],
203202
["roStreamSocket", (interpreter: Interpreter) => new RoStreamSocket(interpreter)],
204203
]);

src/core/brsTypes/components/RoAppInfo.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { BrsComponent } from "./BrsComponent";
33
import { BrsType } from "..";
44
import { Callable, StdlibArgument } from "../Callable";
55
import { Interpreter } from "../../interpreter";
6+
import { BrsDevice } from "../../BrsDevice";
67

78
export class RoAppInfo extends BrsComponent implements BrsValue {
89
readonly kind = ValueKind.Object;
@@ -60,7 +61,7 @@ export class RoAppInfo extends BrsComponent implements BrsValue {
6061
returns: ValueKind.String,
6162
},
6263
impl: (interpreter: Interpreter) => {
63-
return new BrsString(interpreter.deviceInfo.get("developerId"));
64+
return new BrsString(BrsDevice.deviceInfo.get("developerId"));
6465
},
6566
});
6667

src/core/brsTypes/components/RoAppManager.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Interpreter } from "../../interpreter";
66
import { Int32 } from "../Int32";
77
import { RoTimespan } from "./RoTimespan";
88
import { AppData, AppExitReason, isAppData } from "../../common";
9+
import { BrsDevice } from "../../BrsDevice";
910

1011
export class RoAppManager extends BrsComponent implements BrsValue {
1112
readonly kind = ValueKind.Object;
@@ -75,8 +76,8 @@ export class RoAppManager extends BrsComponent implements BrsValue {
7576
args: [],
7677
returns: ValueKind.Void,
7778
},
78-
impl: (interpreter: Interpreter) => {
79-
interpreter.lastKeyTime = Date.now();
79+
impl: (_: Interpreter) => {
80+
BrsDevice.lastKeyTime = Date.now();
8081
return BrsInvalid.Instance;
8182
},
8283
});
@@ -135,7 +136,7 @@ export class RoAppManager extends BrsComponent implements BrsValue {
135136
returns: ValueKind.Object,
136137
},
137138
impl: (interpreter: Interpreter) => {
138-
const app = interpreter.deviceInfo.get("appList")?.find((app: AppData) => app.running);
139+
const app = BrsDevice.deviceInfo.get("appList")?.find((app: AppData) => app.running);
139140
const exitInfo = {
140141
exit_code: app?.exitReason ?? AppExitReason.UNKNOWN,
141142
media_player_state: "stopped",
@@ -192,7 +193,7 @@ export class RoAppManager extends BrsComponent implements BrsValue {
192193
returns: ValueKind.Boolean,
193194
},
194195
impl: (interpreter: Interpreter, channelId: BrsString, version: BrsString) => {
195-
const appList = interpreter.deviceInfo.get("appList");
196+
const appList = BrsDevice.deviceInfo.get("appList");
196197
if (appList instanceof Array) {
197198
const app = appList.find((app) => {
198199
return app.id === channelId.value;
@@ -219,7 +220,7 @@ export class RoAppManager extends BrsComponent implements BrsValue {
219220
version: BrsString,
220221
params: RoAssociativeArray
221222
) => {
222-
const appList = interpreter.deviceInfo.get("appList");
223+
const appList = BrsDevice.deviceInfo.get("appList");
223224
if (appList instanceof Array) {
224225
const app = appList.find((app) => {
225226
return app.id === channelId.value;
@@ -270,7 +271,7 @@ export class RoAppManager extends BrsComponent implements BrsValue {
270271
},
271272
impl: (interpreter: Interpreter) => {
272273
const result = new RoArray([]);
273-
const appList = interpreter.deviceInfo.get("appList");
274+
const appList = BrsDevice.deviceInfo.get("appList");
274275
if (appList instanceof Array) {
275276
appList.forEach((app) => {
276277
const appObj = { id: app.id, title: app.title, version: app.version };
@@ -298,8 +299,8 @@ export class RoAppManager extends BrsComponent implements BrsValue {
298299
args: [new StdlibArgument("disabled", ValueKind.Boolean)],
299300
returns: ValueKind.Void,
300301
},
301-
impl: (interpreter: Interpreter, disabled: BrsBoolean) => {
302-
interpreter.displayEnabled = !disabled.toBoolean();
302+
impl: (_: Interpreter, disabled: BrsBoolean) => {
303+
BrsDevice.displayEnabled = !disabled.toBoolean();
303304
postMessage({ displayEnabled: !disabled.toBoolean() });
304305
return Uninitialized.Instance;
305306
},

src/core/brsTypes/components/RoAudioPlayer.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,18 @@ import { Int32 } from "../Int32";
1414
import { DataType } from "../../common";
1515
import { BrsHttpAgent, IfHttpAgent } from "../interfaces/IfHttpAgent";
1616
import { IfSetMessagePort, IfGetMessagePort } from "../interfaces/IfMessagePort";
17+
import { BrsDevice } from "../../BrsDevice";
1718

1819
export class RoAudioPlayer extends BrsComponent implements BrsValue, BrsHttpAgent {
1920
readonly kind = ValueKind.Object;
2021
readonly customHeaders: Map<string, string>;
21-
private readonly interpreter: Interpreter;
2222
private port?: RoMessagePort;
2323
private contentList: RoAssociativeArray[];
2424
private audioFlags: number;
2525
cookiesEnabled: boolean;
2626

27-
constructor(interpreter: Interpreter) {
27+
constructor() {
2828
super("roAudioPlayer");
29-
this.interpreter = interpreter;
3029
this.contentList = new Array();
3130
this.audioFlags = -1;
3231
this.cookiesEnabled = false;
@@ -86,14 +85,14 @@ export class RoAudioPlayer extends BrsComponent implements BrsValue, BrsHttpAgen
8685

8786
private getNewEvents() {
8887
const events: BrsEvent[] = [];
89-
const flags = Atomics.load(this.interpreter.sharedArray, DataType.SND);
88+
const flags = Atomics.load(BrsDevice.sharedArray, DataType.SND);
9089
if (flags !== this.audioFlags) {
9190
this.audioFlags = flags;
9291
if (this.audioFlags >= 0) {
9392
events.push(
9493
new RoAudioPlayerEvent(
9594
this.audioFlags,
96-
Atomics.load(this.interpreter.sharedArray, DataType.IDX)
95+
Atomics.load(BrsDevice.sharedArray, DataType.IDX)
9796
)
9897
);
9998
}

src/core/brsTypes/components/RoAudioResource.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Callable, StdlibArgument } from "../Callable";
55
import { Interpreter } from "../../interpreter";
66
import { Int32 } from "../Int32";
77
import { DataType } from "../../common";
8+
import { BrsDevice } from "../../BrsDevice";
89

910
export class RoAudioResource extends BrsComponent implements BrsValue {
1011
readonly kind = ValueKind.Object;
@@ -17,7 +18,7 @@ export class RoAudioResource extends BrsComponent implements BrsValue {
1718

1819
constructor(interpreter: Interpreter, name: BrsString) {
1920
super("roAudioResource");
20-
this.maxStreams = Math.min(interpreter.deviceInfo.get("maxSimulStreams"), 3) || 2;
21+
this.maxStreams = Math.min(BrsDevice.deviceInfo.get("maxSimulStreams"), 3) || 2;
2122
this.valid = true;
2223
const systemwav = ["select", "navsingle", "navmulti", "deadend"];
2324
const sysIndex = systemwav.findIndex((wav) => wav === name.value.toLowerCase());
@@ -87,7 +88,7 @@ export class RoAudioResource extends BrsComponent implements BrsValue {
8788
impl: (interpreter: Interpreter) => {
8889
if (this.audioId) {
8990
const currentWav = Atomics.load(
90-
interpreter.sharedArray,
91+
BrsDevice.sharedArray,
9192
DataType.WAV + this.currentIndex
9293
);
9394
this.playing = currentWav === this.audioId;

src/core/brsTypes/components/RoBitmap.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import UPNG from "upng-js";
2525
import * as JPEG from "jpeg-js";
2626
import BMP from "decode-bmp";
2727
import { WebPRiffParser, WebPDecoder } from "libwebpjs";
28+
import { BrsDevice } from "../../BrsDevice";
2829

2930
export class RoBitmap extends BrsComponent implements BrsValue, BrsDraw2D {
3031
readonly kind = ValueKind.Object;
@@ -48,7 +49,7 @@ export class RoBitmap extends BrsComponent implements BrsValue, BrsDraw2D {
4849
this.rgbaLast = 0;
4950
this.rgbaRedraw = true;
5051
this.valid = true;
51-
const platform = interpreter.deviceInfo.get("platform");
52+
const platform = BrsDevice.deviceInfo.get("platform");
5253
this.disposeCanvas = platform?.inIOS ?? false;
5354
this.width = 1;
5455
this.height = 1;

src/core/brsTypes/components/RoCECStatus.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@ import { Interpreter } from "../../interpreter";
66
import { RoCECStatusEvent } from "../events/RoCECStatusEvent";
77
import { DataType } from "../../common";
88
import { IfSetMessagePort, IfGetMessagePort } from "../interfaces/IfMessagePort";
9+
import { BrsDevice } from "../../BrsDevice";
910

1011
export class RoCECStatus extends BrsComponent implements BrsValue {
1112
readonly kind = ValueKind.Object;
12-
private readonly interpreter: Interpreter;
1313
private port?: RoMessagePort;
1414
private active: number;
1515

16-
constructor(interpreter: Interpreter) {
16+
constructor() {
1717
super("roCECStatus");
18-
this.interpreter = interpreter;
1918
this.active = 1; // Default to active
2019
const setPortIface = new IfSetMessagePort(this, this.getNewEvents.bind(this));
2120
const getPortIface = new IfGetMessagePort(this);
@@ -44,7 +43,7 @@ export class RoCECStatus extends BrsComponent implements BrsValue {
4443

4544
private getNewEvents() {
4645
const events: BrsEvent[] = [];
47-
const cecActive = Atomics.load(this.interpreter.sharedArray, DataType.CEC);
46+
const cecActive = Atomics.load(BrsDevice.sharedArray, DataType.CEC);
4847
if (cecActive >= 0 && cecActive !== this.active) {
4948
this.active = cecActive;
5049
events.push(new RoCECStatusEvent(this.active !== 0));
@@ -60,8 +59,8 @@ export class RoCECStatus extends BrsComponent implements BrsValue {
6059
args: [],
6160
returns: ValueKind.Boolean,
6261
},
63-
impl: (interpreter: Interpreter) => {
64-
const cecActive = Atomics.load(interpreter.sharedArray, DataType.CEC);
62+
impl: (_: Interpreter) => {
63+
const cecActive = Atomics.load(BrsDevice.sharedArray, DataType.CEC);
6564
return BrsBoolean.from(cecActive !== 0);
6665
},
6766
});

src/core/brsTypes/components/RoChannelStore.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { RoAssociativeArray } from "./RoAssociativeArray";
99
import { AppData } from "../../common";
1010
import { parseString, processors } from "xml2js";
1111
import { IfSetMessagePort, IfGetMessagePort } from "../interfaces/IfMessagePort";
12+
import { BrsDevice } from "../../BrsDevice";
1213

1314
export class RoChannelStore extends BrsComponent implements BrsValue {
1415
readonly kind = ValueKind.Object;
@@ -465,11 +466,11 @@ export class RoChannelStore extends BrsComponent implements BrsValue {
465466
json = `{channel_data="${this.credData}"}`;
466467
status = 0;
467468
}
468-
const app = interpreter.deviceInfo.get("appList")?.find((app: AppData) => app.running);
469+
const app = BrsDevice.deviceInfo.get("appList")?.find((app: AppData) => app.running);
469470
const channelCred = {
470471
channelId: app?.id ?? "dev",
471472
json: json,
472-
publisherDeviceId: interpreter.deviceInfo.get("clientId") ?? "",
473+
publisherDeviceId: BrsDevice.deviceInfo.get("clientId") ?? "",
473474
status: status,
474475
};
475476
return toAssociativeArray(channelCred);

src/core/brsTypes/components/RoDateTime.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Int32 } from "../Int32";
77
import dayjs from "dayjs";
88
import utc from "dayjs/plugin/utc";
99
import customParseFormat from "dayjs/plugin/customParseFormat";
10+
import { BrsDevice } from "../../BrsDevice";
1011

1112
export class RoDateTime extends BrsComponent implements BrsValue {
1213
readonly kind = ValueKind.Object;
@@ -265,7 +266,7 @@ export class RoDateTime extends BrsComponent implements BrsValue {
265266
},
266267
impl: (interpreter: Interpreter, format: BrsString) => {
267268
const rokuDateTokens = ["EEEE", "EEE", "dd", "d", "MMMM", "MMM", "MM", "M", "yy", "y"];
268-
const locale = (interpreter.deviceInfo.get("locale") ?? "en_US").replace("_", "-");
269+
const locale = (BrsDevice.deviceInfo.get("locale") ?? "en_US").replace("_", "-");
269270
const dateFormat = format.value.trim() === "" ? "short" : format.value;
270271
let dateString = this.formatDate(dateFormat, locale);
271272
if (dateString === "") {
@@ -284,7 +285,7 @@ export class RoDateTime extends BrsComponent implements BrsValue {
284285
},
285286
impl: (interpreter: Interpreter, format: BrsString) => {
286287
const rokuTimeTokens = ["HH", "H", "hh", "h", "mm", "m", "a"];
287-
const locale = (interpreter.deviceInfo.get("locale") ?? "en_US").replace("_", "-");
288+
const locale = (BrsDevice.deviceInfo.get("locale") ?? "en_US").replace("_", "-");
288289
const dateFormat = format.value.trim() === "" ? "short" : format.value;
289290
let timeString = this.formatTime(dateFormat, locale);
290291
if (timeString === "") {
@@ -468,7 +469,7 @@ export class RoDateTime extends BrsComponent implements BrsValue {
468469
const tzDate = new Date(date.toLocaleString("en-US", { timeZone: timeZone }));
469470
return Math.round((tzDate.getTime() - utcDate.getTime()) / 6e4);
470471
};
471-
return new Int32(-getOffset(interpreter.deviceInfo.get("timeZone")) + 0);
472+
return new Int32(-getOffset(BrsDevice.deviceInfo.get("timeZone")) + 0);
472473
},
473474
});
474475

0 commit comments

Comments
 (0)