Skip to content

Commit

Permalink
Adjusted according to review discussion
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenthoms committed Jan 22, 2024
1 parent 2bf5486 commit 295d251
Show file tree
Hide file tree
Showing 32 changed files with 573 additions and 650 deletions.
36 changes: 18 additions & 18 deletions frontend/src/framework/DataChannelTypes.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
export type { ModuleChannelContentDefinition } from "./internal/DataChannels/ModuleChannelContent";
export type { ModuleChannelDefinition } from "./internal/DataChannels/ModuleChannel";
export type { ModuleChannelReceiverDefinition } from "./internal/DataChannels/ModuleChannelReceiver";
export type { DataGenerator, ModuleChannelContentMetaData } from "./internal/DataChannels/ModuleChannelContent";
export type { ChannelContentDefinition } from "./internal/DataChannels/ChannelContent";
export type { ChannelDefinition } from "./internal/DataChannels/Channel";
export type { ChannelReceiverDefinition } from "./internal/DataChannels/ChannelReceiver";
export type { DataGenerator, ChannelContentMetaData } from "./internal/DataChannels/ChannelContent";
export type { ChannelReceiverChannelContent } from "./internal/DataChannels/hooks/useChannelReceiver";

export enum KeyKind {
TimestampMs = "timestamp-ms",
Realization = "realization",
GridIndex = "grid-index",
GridIJK = "grid-ijk",
MeasuredDepth = "measured-depth",
TIMESTAMP_MS = "timestamp-ms",
REALIZATION = "realization",
GRID_INDEX = "grid-index",
GRID_IJK = "grid-ijk",
MEASURED_DEPTH = "measured-depth",
}

export enum KeyType {
Number = "number",
NumberTriplet = "number-triplet",
NUMBER = "number",
NUMBER_TRIPLET = "number-triplet",
}

export interface KeyKindToKeyTypeMapping {
[KeyKind.TimestampMs]: KeyType.Number;
[KeyKind.Realization]: KeyType.Number;
[KeyKind.GridIndex]: KeyType.Number;
[KeyKind.GridIJK]: KeyType.NumberTriplet;
[KeyKind.MeasuredDepth]: KeyType.Number;
[KeyKind.TIMESTAMP_MS]: KeyType.NUMBER;
[KeyKind.REALIZATION]: KeyType.NUMBER;
[KeyKind.GRID_INDEX]: KeyType.NUMBER;
[KeyKind.GRID_IJK]: KeyType.NUMBER_TRIPLET;
[KeyKind.MEASURED_DEPTH]: KeyType.NUMBER;
}

export interface DataElement<TKeyType extends KeyType> {
Expand All @@ -31,6 +31,6 @@ export interface DataElement<TKeyType extends KeyType> {
}

type KeyTypeToTypeScriptTypeMapping = {
[KeyType.Number]: number;
[KeyType.NumberTriplet]: [number, number, number];
[KeyType.NUMBER]: number;
[KeyType.NUMBER_TRIPLET]: [number, number, number];
};
10 changes: 5 additions & 5 deletions frontend/src/framework/Module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";

import { cloneDeep } from "lodash";

import { ModuleChannelDefinition, ModuleChannelReceiverDefinition } from "./DataChannelTypes";
import { ChannelDefinition, ChannelReceiverDefinition } from "./DataChannelTypes";
import { InitialSettings } from "./InitialSettings";
import { ModuleContext } from "./ModuleContext";
import { ModuleInstance } from "./ModuleInstance";
Expand Down Expand Up @@ -44,8 +44,8 @@ export class Module<StateType extends StateBaseType> {
private _syncableSettingKeys: SyncSettingKey[];
private _drawPreviewFunc: DrawPreviewFunc | null;
private _description: string | null;
private _channelDefinitions: ModuleChannelDefinition[] | null;
private _channelReceiverDefinitions: ModuleChannelReceiverDefinition[] | null;
private _channelDefinitions: ChannelDefinition[] | null;
private _channelReceiverDefinitions: ChannelReceiverDefinition[] | null;

constructor({
name,
Expand All @@ -61,8 +61,8 @@ export class Module<StateType extends StateBaseType> {
syncableSettingKeys?: SyncSettingKey[];
drawPreviewFunc?: DrawPreviewFunc;
description?: string;
channelDefinitions?: ModuleChannelDefinition[];
channelReceiverDefinitions?: ModuleChannelReceiverDefinition[];
channelDefinitions?: ChannelDefinition[];
channelReceiverDefinitions?: ChannelReceiverDefinition[];
}) {
this._name = name;
this._defaultTitle = defaultTitle;
Expand Down
21 changes: 11 additions & 10 deletions frontend/src/framework/ModuleContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
/* eslint-disable react-hooks/rules-of-hooks */
import React from "react";

import { KeyKind, ModuleChannelContentDefinition } from "./DataChannelTypes";
import { ChannelContentDefinition, KeyKind } from "./DataChannelTypes";
import { ModuleInstance } from "./ModuleInstance";
import { ModuleInstanceStatusController } from "./ModuleInstanceStatusController";
import { StateBaseType, StateStore, useSetStoreValue, useStoreState, useStoreValue } from "./StateStore";
import { SyncSettingKey } from "./SyncSettings";
import { DataGenerator } from "./internal/DataChannels/ModuleChannelContent";
import { useChannelReceiver } from "./internal/DataChannels/hooks/useChannelReceiver";
import { usePublishChannelContents } from "./internal/DataChannels/hooks/usePublishChannelContents";

Expand Down Expand Up @@ -74,28 +73,30 @@ export class ModuleContext<S extends StateBaseType> {
}

useChannelReceiver<TKeyKinds extends KeyKind[]>(options: {
idString: string;
receiverIdString: string;
expectedKindsOfKeys: TKeyKinds;
}): ReturnType<typeof useChannelReceiver<(typeof options)["expectedKindsOfKeys"]>> {
const receiver = this._moduleInstance.getChannelManager().getReceiver(options.idString);
const receiver = this._moduleInstance.getChannelManager().getReceiver(options.receiverIdString);

return useChannelReceiver({
receiver,
expectedKindsOfKeys: options.expectedKindsOfKeys,
});
if (!receiver) {
throw new Error(`Receiver '${options.receiverIdString}' does not exist`);
}

return useChannelReceiver(receiver, options.expectedKindsOfKeys);
}

usePublishChannelContents(options: {
channelIdString: string;
dependencies: any[];
enabled?: boolean;
contents: ModuleChannelContentDefinition[];
dataGenerator: (contentIdString: string) => ReturnType<DataGenerator>;
contents: ChannelContentDefinition[];
}) {
const channel = this._moduleInstance.getChannelManager().getChannel(options.channelIdString);

if (!channel) {
throw new Error(`Channel '${options.channelIdString}' does not exist`);
}

return usePublishChannelContents({
channel,
...options,
Expand Down
14 changes: 7 additions & 7 deletions frontend/src/framework/ModuleInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { ErrorInfo } from "react";

import { cloneDeep } from "lodash";

import { ModuleChannelDefinition, ModuleChannelReceiverDefinition } from "./DataChannelTypes";
import { ChannelDefinition, ChannelReceiverDefinition } from "./DataChannelTypes";
import { InitialSettings } from "./InitialSettings";
import { ImportState, Module, ModuleFC } from "./Module";
import { ModuleContext } from "./ModuleContext";
import { StateBaseType, StateOptions, StateStore } from "./StateStore";
import { SyncSettingKey } from "./SyncSettings";
import { ModuleChannelManager } from "./internal/DataChannels/ModuleChannelManager";
import { ChannelManager } from "./internal/DataChannels/ChannelManager";
import { ModuleInstanceStatusControllerInternal } from "./internal/ModuleInstanceStatusControllerInternal";

export enum ModuleInstanceState {
Expand Down Expand Up @@ -36,7 +36,7 @@ export class ModuleInstance<StateType extends StateBaseType> {
private _cachedStateStoreOptions?: StateOptions<StateType>;
private _initialSettings: InitialSettings | null;
private _statusController: ModuleInstanceStatusControllerInternal;
private _channelManager: ModuleChannelManager;
private _channelManager: ChannelManager;

constructor({
module,
Expand All @@ -46,8 +46,8 @@ export class ModuleInstance<StateType extends StateBaseType> {
}: {
module: Module<StateType>;
instanceNumber: number;
channelDefinitions: ModuleChannelDefinition[] | null;
channelReceiverDefinitions: ModuleChannelReceiverDefinition[] | null;
channelDefinitions: ChannelDefinition[] | null;
channelReceiverDefinitions: ChannelReceiverDefinition[] | null;
}) {
this._id = `${module.getName()}-${instanceNumber}`;
this._title = module.getDefaultTitle();
Expand All @@ -66,7 +66,7 @@ export class ModuleInstance<StateType extends StateBaseType> {
this._initialSettings = null;
this._statusController = new ModuleInstanceStatusControllerInternal();

this._channelManager = new ModuleChannelManager(this._id);
this._channelManager = new ChannelManager(this._id);

if (channelReceiverDefinitions) {
this._channelManager.registerReceivers(
Expand All @@ -82,7 +82,7 @@ export class ModuleInstance<StateType extends StateBaseType> {
}
}

getChannelManager(): ModuleChannelManager {
getChannelManager(): ChannelManager {
return this._channelManager;
}

Expand Down
6 changes: 3 additions & 3 deletions frontend/src/framework/ModuleRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ModuleChannelDefinition, ModuleChannelReceiverDefinition } from "./DataChannelTypes";
import { ChannelDefinition, ChannelReceiverDefinition } from "./DataChannelTypes";
import { Module } from "./Module";
import { DrawPreviewFunc } from "./Preview";
import { StateBaseType, StateOptions } from "./StateStore";
Expand All @@ -9,8 +9,8 @@ export type RegisterModuleOptions = {
moduleName: string;
defaultTitle: string;
syncableSettingKeys?: SyncSettingKey[];
channelDefinitions?: ModuleChannelDefinition[];
channelReceiverDefinitions?: ModuleChannelReceiverDefinition[];
channelDefinitions?: ChannelDefinition[];
channelReceiverDefinitions?: ChannelReceiverDefinition[];
preview?: DrawPreviewFunc;
description?: string;
};
Expand Down
105 changes: 105 additions & 0 deletions frontend/src/framework/internal/DataChannels/Channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { KeyKind } from "@framework/DataChannelTypes";

import { ChannelContent, ChannelContentDefinition, ChannelContentNotificationTopic } from "./ChannelContent";
import { ChannelManager } from "./ChannelManager";

export interface ChannelDefinition {
readonly idString: string;
readonly displayName: string;
readonly kindOfKey: KeyKind;
}

export enum ChannelNotificationTopic {
CONTENTS_ARRAY_CHANGE = "contents-array-change",
CONTENTS_DATA_ARRAY_CHANGE = "contents-data-arrays-change",
CHANNEL_ABOUT_TO_BE_REMOVED = "channel-about-to-be-removed",
}

export class Channel {
private _idString: string;
private _displayName: string;
private _kindOfKey: KeyKind;
private _manager: ChannelManager;
private _contents: ChannelContent[] = [];
private _subscribersMap: Map<ChannelNotificationTopic, Set<() => void>> = new Map();

constructor(manager: ChannelManager, def: ChannelDefinition) {
this._manager = manager;
this._idString = def.idString;
this._displayName = def.displayName;
this._kindOfKey = def.kindOfKey;

this.handleContentDataArraysChange = this.handleContentDataArraysChange.bind(this);
}

getIdString(): string {
return this._idString;
}

getDisplayName(): string {
return this._displayName;
}

getManager(): ChannelManager {
return this._manager;
}

getKindOfKey(): KeyKind {
return this._kindOfKey;
}

getContents(): ChannelContent[] {
return this._contents;
}

private handleContentDataArraysChange(): void {
this.notifySubscribers(ChannelNotificationTopic.CONTENTS_DATA_ARRAY_CHANGE);
}

replaceContents(contentDefinitions: ChannelContentDefinition[]): void {
this._contents = [];

for (const contentDefinition of contentDefinitions) {
const content = new ChannelContent({ ...contentDefinition });
content.subscribe(ChannelContentNotificationTopic.DATA_ARRAY_CHANGE, this.handleContentDataArraysChange);
this._contents.push(content);
}

this.notifySubscribers(ChannelNotificationTopic.CONTENTS_ARRAY_CHANGE);
this.notifySubscribers(ChannelNotificationTopic.CONTENTS_DATA_ARRAY_CHANGE);
}

subscribe(topic: ChannelNotificationTopic, callback: () => void): void {
const topicSubscribers = this._subscribersMap.get(topic) || new Set();

topicSubscribers.add(callback);

this._subscribersMap.set(topic, topicSubscribers);
}

unsubscribe(topic: ChannelNotificationTopic, callback: () => void): void {
const topicSubscribers = this._subscribersMap.get(topic);

if (!topicSubscribers) {
return;
}

topicSubscribers.delete(callback);
}

private notifySubscribers(topic: ChannelNotificationTopic): void {
const topicSubscribers = this._subscribersMap.get(topic);

if (!topicSubscribers) {
return;
}

for (const subscriber of topicSubscribers) {
subscriber();
}
}

notifySubscribersOfChannelAboutToBeRemoved(): void {
this.notifySubscribers(ChannelNotificationTopic.CHANNEL_ABOUT_TO_BE_REMOVED);
}
}
Loading

0 comments on commit 295d251

Please sign in to comment.