Skip to content

Commit

Permalink
feat(core): improve configurable behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
agviegas committed Aug 24, 2024
1 parent b2d1fc7 commit 292300c
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 52 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@thatopen/components",
"description": "Collection of core functionalities to author BIM apps.",
"version": "2.2.5",
"version": "2.3.0-alpha.1",
"author": "That Open Company",
"contributors": [
"Antonio Gonzalez Viegas (https://github.com/agviegas)",
Expand Down
14 changes: 11 additions & 3 deletions packages/core/src/core/Types/src/base-scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,25 @@ export abstract class BaseScene extends BaseWorldItem implements Disposable {
disposer.destroy(mesh);
}
}

this.deleteAllLights();

this.three.children = [];
this.onDisposed.trigger();
this.onDisposed.reset();
}

deleteAllLights() {
for (const [, light] of this.directionalLights) {
light.removeFromParent();
light.target.removeFromParent();
light.dispose();
}
this.directionalLights.clear();
for (const [, light] of this.ambientLights) {
light.removeFromParent();
light.dispose();
}
this.three.children = [];
this.onDisposed.trigger();
this.onDisposed.reset();
this.ambientLights.clear();
}
}
13 changes: 13 additions & 0 deletions packages/core/src/core/Types/src/component-with-ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Component } from "./component";

export type ComponentUIElement = {
name: string;
componentID: string;
attributes: { [name: string]: string };
get: () => HTMLElement;
};

export abstract class ComponentWithUI extends Component {
abstract name: string;
abstract getUI(): ComponentUIElement[];
}
60 changes: 60 additions & 0 deletions packages/core/src/core/Types/src/config-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
export interface BooleanSettingsControl {
type: "Boolean";
value: boolean;
}

export interface ColorSettingsControl {
type: "Color";
opacity: number;
value: number;
}

export interface TextSettingsControl {
type: "Text";
value: string;
}

export interface NumberSettingControl {
type: "Number";
interpolable: boolean;
min?: number;
max?: number;
value: number;
}

export interface SelectSettingControl {
type: "Select";
options?: string[];
value: string;
}

export interface VectorSettingControl {
type: "Vector";
value: number[];
}

type ControlEntry =
| BooleanSettingsControl
| ColorSettingsControl
| TextSettingsControl
| NumberSettingControl
| SelectSettingControl
| VectorSettingControl;

interface ControlsSchema {
[name: string]: ControlEntry | ControlsSchema;
}

export abstract class ConfigManager<T, U extends ControlsSchema> {
protected abstract _list: U;

protected _component: T;

get controls() {
return JSON.parse(JSON.stringify(this._list));
}

constructor(component: T) {
this._component = component;
}
}
2 changes: 2 additions & 0 deletions packages/core/src/core/Types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export * from "./base-scene";
export * from "./world";
export * from "./data-set";
export * from "./data-map";
export * from "./component-with-ui";
export * from "./config-manager";
9 changes: 4 additions & 5 deletions packages/core/src/core/Types/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,17 @@ export interface Createable {
/**
* Whether this component supports to be configured.
*/
export interface Configurable<T extends Record<string, any>> {
export interface Configurable<T, U> {
/** Wether this components has been already configured. */
isSetup: boolean;

/** Use the provided configuration to setup the tool. */
setup: (config?: Partial<T>) => void | Promise<void>;
/** Use the provided configuration to set up the tool. */
setup: (config?: Partial<U>) => void | Promise<void>;

/** Fired after successfully calling {@link Configurable.setup()} */
readonly onSetup: Event<any>;

/** Object holding the tool configuration. Is not meant to be edited directly, if you need
* to make changes to this object, use {@link Configurable.setup()} just after the tool is instantiated.
/** Object holding the tool configuration. You can edit this directly to change the object.
*/
config: Required<T>;
}
Expand Down
167 changes: 167 additions & 0 deletions packages/core/src/core/Worlds/src/simple-scene-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// eslint-disable-next-line max-classes-per-file
import * as THREE from "three";
import { SimpleScene } from "./simple-scene";
import {
ColorSettingsControl,
ConfigManager,
NumberSettingControl,
VectorSettingControl,
} from "../../Types";

type SimpleSceneConfigType = {
backgroundColor: ColorSettingsControl;
ambientLight: {
color: ColorSettingsControl;
intensity: NumberSettingControl;
};
directionalLight: {
color: ColorSettingsControl;
intensity: NumberSettingControl;
position: VectorSettingControl;
};
};

class DirectionalLightConfig {
private _list: SimpleSceneConfigType;
private _scene: SimpleScene;

constructor(list: SimpleSceneConfigType, scene: SimpleScene) {
this._list = list;
this._scene = scene;
}

get color() {
return this._list.directionalLight.color.value;
}

set color(value: number) {
this._list.directionalLight.color.value = value;
for (const [, light] of this._scene.directionalLights) {
light.color = new THREE.Color(value);
}
}

get intensity() {
return this._list.directionalLight.intensity.value;
}

set intensity(value: number) {
this._list.directionalLight.intensity.value = value;
for (const [, light] of this._scene.directionalLights) {
light.intensity = value;
}
}

get position() {
return this._list.directionalLight.position.value;
}

set position(value: number[]) {
this._list.directionalLight.position.value = value;
const [x, y, z] = value;
for (const [, light] of this._scene.directionalLights) {
light.position.set(x, y, z);
}
}
}

class AmbientLightConfig {
private _list: SimpleSceneConfigType;
private _scene: SimpleScene;

constructor(list: SimpleSceneConfigType, scene: SimpleScene) {
this._list = list;
this._scene = scene;
}

get color() {
return this._list.ambientLight.color.value;
}

set color(value: number) {
this._list.ambientLight.color.value = value;
for (const [, light] of this._scene.ambientLights) {
light.color = new THREE.Color(value);
}
}

get intensity() {
return this._list.ambientLight.intensity.value;
}

set intensity(value: number) {
this._list.ambientLight.intensity.value = value;
for (const [, light] of this._scene.ambientLights) {
light.intensity = value;
}
}
}

/**
* Configuration interface for the {@link SimpleScene}.
*/
export interface SimpleSceneConfig {
directionalLight: {
color: THREE.Color;
intensity: number;
position: THREE.Vector3;
};
ambientLight: {
color: THREE.Color;
intensity: number;
};
}

export class SimpleSceneConfigManager extends ConfigManager<
SimpleScene,
SimpleSceneConfigType
> {
protected _list = {
backgroundColor: {
value: 0,
opacity: 1,
type: "Color" as const,
},
ambientLight: {
color: {
type: "Color" as const,
opacity: 1,
value: 1,
},
intensity: {
type: "Number" as const,
interpolable: false,
value: 2,
},
},
directionalLight: {
color: {
type: "Color" as const,
opacity: 1,
value: 1,
},
intensity: {
type: "Number" as const,
interpolable: false,
value: 2,
},
position: {
type: "Vector" as const,
value: [],
},
},
};

ambientLight = new AmbientLightConfig(this._list, this._component);

directionalLight = new DirectionalLightConfig(this._list, this._component);

get backgroundColor() {
return this._list.backgroundColor.value;
}

set backgroundColor(value: number) {
this._list.backgroundColor.value = value;
this._component.three.background = new THREE.Color(value);
}
}
Loading

0 comments on commit 292300c

Please sign in to comment.