From 1a3031561753d6c78032328a19f80cf0b3207f3f Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 24 Jul 2023 22:12:16 -0400 Subject: [PATCH 1/2] convert to new node defintion pattern. --- .../Profiles/Core/Debug/AssertExpectTrue.ts | 63 +++++++++---------- .../src/Profiles/Core/registerCoreProfile.ts | 2 +- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/packages/core/src/Profiles/Core/Debug/AssertExpectTrue.ts b/packages/core/src/Profiles/Core/Debug/AssertExpectTrue.ts index f0bb110b..f69653f4 100644 --- a/packages/core/src/Profiles/Core/Debug/AssertExpectTrue.ts +++ b/packages/core/src/Profiles/Core/Debug/AssertExpectTrue.ts @@ -1,36 +1,33 @@ import { Assert } from '../../../Diagnostics/Assert.js'; -import { Fiber } from '../../../Execution/Fiber.js'; -import { IGraphApi } from '../../../Graphs/Graph.js'; -import { FlowNode } from '../../../Nodes/FlowNode.js'; -import { NodeDescription } from '../../../Nodes/Registry/NodeDescription.js'; -import { Socket } from '../../../Sockets/Socket.js'; +import { + makeFlowNodeDefinition, + NodeCategory +} from '../../../Nodes/NodeDefinitions.js'; -export class ExpectTrue extends FlowNode { - public static Description = new NodeDescription( - 'debug/expectTrue', - 'Action', - 'Assert Expect True', - (description, graph) => new ExpectTrue(description, graph) - ); - - constructor(description: NodeDescription, graph: IGraphApi) { - super( - description, - graph, - [ - new Socket('flow', 'flow'), - new Socket('boolean', 'condition'), - new Socket('string', 'description') - ], - [new Socket('flow', 'flow')] - ); - } - - triggered(fiber: Fiber, triggeredSocketName: string) { - Assert.mustBeTrue( - this.readInput('condition'), - this.readInput('description') - ); - fiber.commit(this, 'flow'); +export const ExpectTrue = makeFlowNodeDefinition({ + typeName: 'debug/expectTrue', + category: NodeCategory.Action, + label: 'Assert Expect True', + in: () => { + return [ + { + key: 'flow', + valueType: 'flow' + }, + { + key: 'condition', + valueType: 'boolean' + }, + { + key: 'description', + valueType: 'string' + } + ]; + }, + initialState: undefined, + out: { flow: 'flow' }, + triggered: ({ read, commit }) => { + Assert.mustBeTrue(read('condition'), read('description')); + commit('flow'); } -} +}); diff --git a/packages/core/src/Profiles/Core/registerCoreProfile.ts b/packages/core/src/Profiles/Core/registerCoreProfile.ts index 22f02884..a3aea689 100644 --- a/packages/core/src/Profiles/Core/registerCoreProfile.ts +++ b/packages/core/src/Profiles/Core/registerCoreProfile.ts @@ -75,7 +75,7 @@ export const getCoreNodesMap = memo>(() => { // actions DebugLog, - AssertExpectTrue.Description, + AssertExpectTrue, // events LifecycleOnStart, From e83744b24681f9fbf995c95af4f3ca34b8413a12 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Mon, 24 Jul 2023 22:26:26 -0400 Subject: [PATCH 2/2] logger uses the same function just with severity parameter. --- docs/Abstractions.md | 14 ++--- packages/core/src/Diagnostics/Logger.ts | 53 ++++++++++--------- .../core/src/Graphs/IO/readGraphFromJSON.ts | 2 +- .../Abstractions/Drivers/DefaultLogger.ts | 18 ++----- .../src/Profiles/Core/Abstractions/ILogger.ts | 6 +-- .../core/src/Profiles/Core/Debug/DebugLog.ts | 20 +------ website/docs/core-concepts/abstractions.md | 14 ++--- 7 files changed, 51 insertions(+), 76 deletions(-) diff --git a/docs/Abstractions.md b/docs/Abstractions.md index 285ba730..d167af65 100644 --- a/docs/Abstractions.md +++ b/docs/Abstractions.md @@ -1,18 +1,18 @@ **Abstractions** -Behave-graph is designed as a light weight library that can be plugged into other engines, such as Three.js or Babylon.js. In order to simplify pluggin into other engines, it defines the functionality required for interfacing with these engines as "abstractions", which can then be implemented by the engines. +Behave-graph is designed as a light weight library that can be plugged into other engines, such as Three.js or Babylon.js. In order to simplify pluggin into other engines, it defines the functionality required for interfacing with these engines as "abstractions", which can then be implemented by the engines. -This design is inspired by [Hardware Abstraction layers](https://en.wikipedia.org/wiki/Hardware_abstraction) present in operating systems. HALs, as they are called, are interfaces which are then implemented by drivers that enable that functionality. HALs allow for operating systems to easily be ported to different systems because the machine specific implementations for the operating systems are cordened off from the main operating system behind these HALs. Behave-graph takes this same approach. +This design is inspired by [Hardware Abstraction layers](https://en.wikipedia.org/wiki/Hardware_abstraction) present in operating systems. HALs, as they are called, are interfaces which are then implemented by drivers that enable that functionality. HALs allow for operating systems to easily be ported to different systems because the machine specific implementations for the operating systems are cordened off from the main operating system behind these HALs. Behave-graph takes this same approach. Example abstractions in behave-graph: -* ILogger. The logging interface allows for behave-graph to report verbose, info, warning and error text messages. The command line graph-exec tool uses the driver DefaultLogger to output these messages to the console. -* ILifecycleEventEmitter. This interface is responsible for emitting when the behave-graph should start, tick and stop. -* IScene. This interface is responsible for doing basic scene manipulations. In the three example, this interface is implemented by the ThreeScene class that maps these operations to a Three.js-based scene graph. +- ILogger. The logging interface allows for behave-graph to report verbose, info, warning and error text messages. The command line graph-exec tool uses the driver DefaultLogger to output these messages to the console. +- ILifecycleEventEmitter. This interface is responsible for emitting when the behave-graph should start, tick and stop. +- IScene. This interface is responsible for doing basic scene manipulations. In the three example, this interface is implemented by the ThreeScene class that maps these operations to a Three.js-based scene graph. For example here is the ILogger abstraction, you can see it is just a standard Typescript interface: -``` typescript +```typescript export interface ILogger { verbose(text: string): void; info(text: string): void; @@ -38,7 +38,7 @@ export class DefaultLogger implements ILogger { } warn(text: string): void { - Logger.warn(text); + Logger.warning(text); } error(text: string): void { diff --git a/packages/core/src/Diagnostics/Logger.ts b/packages/core/src/Diagnostics/Logger.ts index 8bc02283..6b752a9e 100644 --- a/packages/core/src/Diagnostics/Logger.ts +++ b/packages/core/src/Diagnostics/Logger.ts @@ -1,14 +1,27 @@ /* eslint-disable no-console */ import { EventEmitter } from '../Events/EventEmitter.js'; +import { LogSeverity } from '../index.js'; export enum LogLevel { Verbose = 0, Info = 1, - Warn = 2, + Warning = 2, Error = 3 } +export function logSeverityToLevel(severity: LogSeverity) { + switch (severity) { + case 'verbose': + return LogLevel.Verbose; + case 'info': + return LogLevel.Info; + case 'warning': + return LogLevel.Warning; + case 'error': + return LogLevel.Error; + } +} export enum PrefixStyle { None = 0, Time = 1 @@ -19,14 +32,13 @@ const FgRed = '\x1b[31m'; const BgYellow = '\x1b[43m'; const Dim = '\x1b[2m'; +export type LogMessage = { severity: LogSeverity; text: string }; + export class Logger { static logLevel = LogLevel.Info; static prefixStyle = PrefixStyle.None; - public static readonly onVerbose = new EventEmitter(); - public static readonly onInfo = new EventEmitter(); - public static readonly onWarn = new EventEmitter(); - public static readonly onError = new EventEmitter(); + public static readonly onLog = new EventEmitter(); static { const prefix = (): string => { @@ -38,36 +50,29 @@ export class Logger { } }; - Logger.onVerbose.addListener((text: string) => { - if (Logger.logLevel > LogLevel.Verbose) return; - console.log(prefix() + `${Dim}${text}${Reset}`); - }); - Logger.onInfo.addListener((text: string) => { - if (Logger.logLevel > LogLevel.Info) return; - console.log(prefix() + `${text}`); - }); - Logger.onWarn.addListener((text: string) => { - if (Logger.logLevel > LogLevel.Warn) return; - console.warn(prefix() + `${BgYellow}${text}${Reset}`); - }); - Logger.onError.addListener((text: string) => { - console.error(prefix() + `${FgRed}${text}}${Reset}`); + Logger.onLog.addListener((logMessage: LogMessage) => { + if (Logger.logLevel > logSeverityToLevel(logMessage.severity)) return; + console.log(prefix() + logMessage.text); }); } + static log(severity: LogSeverity, text: string) { + this.onLog.emit({ severity, text }); + } + static verbose(text: string) { - this.onVerbose.emit(text); + this.onLog.emit({ severity: 'verbose', text }); } static info(text: string) { - this.onInfo.emit(text); + this.onLog.emit({ severity: 'info', text }); } - static warn(text: string) { - this.onWarn.emit(text); + static warning(text: string) { + this.onLog.emit({ severity: 'warning', text }); } static error(text: string) { - this.onError.emit(text); + this.onLog.emit({ severity: 'error', text }); } } diff --git a/packages/core/src/Graphs/IO/readGraphFromJSON.ts b/packages/core/src/Graphs/IO/readGraphFromJSON.ts index 4c0fddae..59ab37ce 100644 --- a/packages/core/src/Graphs/IO/readGraphFromJSON.ts +++ b/packages/core/src/Graphs/IO/readGraphFromJSON.ts @@ -53,7 +53,7 @@ export function readGraphFromJSON({ const nodesJson = graphJson?.nodes ?? []; if (nodesJson.length === 0) { - Logger.warn('readGraphFromJSON: no nodes specified'); + Logger.warning('readGraphFromJSON: no nodes specified'); } const graphApi = makeGraphApi({ diff --git a/packages/core/src/Profiles/Core/Abstractions/Drivers/DefaultLogger.ts b/packages/core/src/Profiles/Core/Abstractions/Drivers/DefaultLogger.ts index 4d21db32..9ebe1f12 100644 --- a/packages/core/src/Profiles/Core/Abstractions/Drivers/DefaultLogger.ts +++ b/packages/core/src/Profiles/Core/Abstractions/Drivers/DefaultLogger.ts @@ -1,21 +1,9 @@ /* eslint-disable class-methods-use-this */ import { Logger } from '../../../../Diagnostics/Logger.js'; -import { ILogger } from '../ILogger.js'; +import { ILogger, LogSeverity } from '../ILogger.js'; export class DefaultLogger implements ILogger { - verbose(text: string): void { - Logger.verbose(text); - } - - info(text: string): void { - Logger.info(text); - } - - warn(text: string): void { - Logger.warn(text); - } - - error(text: string): void { - Logger.error(text); + log(severity: LogSeverity, text: string): void { + Logger.log(severity, text); } } diff --git a/packages/core/src/Profiles/Core/Abstractions/ILogger.ts b/packages/core/src/Profiles/Core/Abstractions/ILogger.ts index 7139dfe3..d955f28c 100644 --- a/packages/core/src/Profiles/Core/Abstractions/ILogger.ts +++ b/packages/core/src/Profiles/Core/Abstractions/ILogger.ts @@ -1,6 +1,4 @@ +export type LogSeverity = 'verbose' | 'info' | 'warning' | 'error'; export interface ILogger { - verbose(text: string): void; - info(text: string): void; - warn(text: string): void; - error(text: string): void; + log(severity: LogSeverity, text: string): void; } diff --git a/packages/core/src/Profiles/Core/Debug/DebugLog.ts b/packages/core/src/Profiles/Core/Debug/DebugLog.ts index 6b8c88a4..48865710 100644 --- a/packages/core/src/Profiles/Core/Debug/DebugLog.ts +++ b/packages/core/src/Profiles/Core/Debug/DebugLog.ts @@ -2,7 +2,7 @@ import { makeFlowNodeDefinition, NodeCategory } from '../../../Nodes/NodeDefinitions.js'; -import { ILogger } from '../Abstractions/ILogger.js'; +import { ILogger, LogSeverity } from '../Abstractions/ILogger.js'; export const Log = makeFlowNodeDefinition({ typeName: 'debug/log', @@ -22,23 +22,7 @@ export const Log = makeFlowNodeDefinition({ initialState: undefined, triggered: ({ read, commit, graph: { getDependency } }) => { const logger = getDependency('ILogger'); - - const text = read('text'); - switch (read('severity')) { - case 'verbose': - logger?.verbose(text); - break; - case 'info': - logger?.info(text); - break; - case 'warning': - logger?.warn(text); - break; - case 'error': - logger?.error(text); - break; - } - + logger?.log(read('severity'), read('text')); commit('flow'); } }); diff --git a/website/docs/core-concepts/abstractions.md b/website/docs/core-concepts/abstractions.md index 270d5a77..bbd299ec 100644 --- a/website/docs/core-concepts/abstractions.md +++ b/website/docs/core-concepts/abstractions.md @@ -4,15 +4,15 @@ sidebar_position: 5 # Abstractions -Behave-graph is designed as a light weight library that can be plugged into other engines, such as Three.js or Babylon.js. In order to simplify pluggin into other engines, it defines the functionality required for interfacing with these engines as "abstractions", which can then be implemented by the engines. +Behave-graph is designed as a light weight library that can be plugged into other engines, such as Three.js or Babylon.js. In order to simplify pluggin into other engines, it defines the functionality required for interfacing with these engines as "abstractions", which can then be implemented by the engines. -This design is inspired by [Hardware Abstraction layers](https://en.wikipedia.org/wiki/Hardware_abstraction) present in operating systems. HALs, as they are called, are interfaces which are then implemented by drivers that enable that functionality. HALs allow for operating systems to easily be ported to different systems because the machine specific implementations for the operating systems are cordened off from the main operating system behind these HALs. Behave-graph takes this same approach. +This design is inspired by [Hardware Abstraction layers](https://en.wikipedia.org/wiki/Hardware_abstraction) present in operating systems. HALs, as they are called, are interfaces which are then implemented by drivers that enable that functionality. HALs allow for operating systems to easily be ported to different systems because the machine specific implementations for the operating systems are cordened off from the main operating system behind these HALs. Behave-graph takes this same approach. Example abstractions in behave-graph: -* **ILogger**. The logging interface allows for behave-graph to report verbose, info, warning and error text messages. The command line graph-exec tool uses the driver DefaultLogger to output these messages to the console. -* **ILifecycleEventEmitter**. This interface is responsible for emitting when the behave-graph should start, tick and stop. -* **IScene**. This interface is responsible for doing basic scene manipulations. In the three example, this interface is implemented by the ThreeScene class that maps these operations to a Three.js-based scene graph. +- **ILogger**. The logging interface allows for behave-graph to report verbose, info, warning and error text messages. The command line graph-exec tool uses the driver DefaultLogger to output these messages to the console. +- **ILifecycleEventEmitter**. This interface is responsible for emitting when the behave-graph should start, tick and stop. +- **IScene**. This interface is responsible for doing basic scene manipulations. In the three example, this interface is implemented by the ThreeScene class that maps these operations to a Three.js-based scene graph. For example here is the ILogger abstraction, you can see it is just a standard Typescript interface: @@ -41,11 +41,11 @@ export class DefaultLogger implements ILogger { } warn(text: string): void { - Logger.warn(text); + Logger.warning(text); } error(text: string): void { Logger.error(text); } } -``` \ No newline at end of file +```