2022-07-07 09:49:05 -05:00
|
|
|
import React, { useEffect } from 'react';
|
|
|
|
|
2022-11-16 04:36:30 -06:00
|
|
|
import { SceneComponentProps, SceneEditor, SceneObject } from './types';
|
2022-07-07 09:49:05 -05:00
|
|
|
|
2022-11-15 02:49:39 -06:00
|
|
|
export function SceneComponentWrapper<T extends SceneObject>({
|
|
|
|
model,
|
|
|
|
isEditing,
|
|
|
|
...otherProps
|
|
|
|
}: SceneComponentProps<T>) {
|
2022-07-07 09:49:05 -05:00
|
|
|
const Component = (model as any).constructor['Component'] ?? EmptyRenderer;
|
2022-11-15 02:49:39 -06:00
|
|
|
const inner = <Component {...otherProps} model={model} isEditing={isEditing} />;
|
2022-07-07 09:49:05 -05:00
|
|
|
|
|
|
|
// Handle component activation state state
|
|
|
|
useEffect(() => {
|
|
|
|
if (!model.isActive) {
|
|
|
|
model.activate();
|
|
|
|
}
|
|
|
|
return () => {
|
|
|
|
if (model.isActive) {
|
|
|
|
model.deactivate();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}, [model]);
|
|
|
|
|
2022-11-15 05:54:24 -06:00
|
|
|
/** Useful for tests and evaluating efficiency in reducing renderings */
|
|
|
|
// @ts-ignore
|
|
|
|
model._renderCount += 1;
|
|
|
|
|
2022-07-07 09:49:05 -05:00
|
|
|
if (!isEditing) {
|
|
|
|
return inner;
|
|
|
|
}
|
|
|
|
|
2022-11-16 04:36:30 -06:00
|
|
|
const editor = getSceneEditor(model);
|
|
|
|
const EditWrapper = getSceneEditor(model).getEditComponentWrapper();
|
|
|
|
|
|
|
|
return (
|
|
|
|
<EditWrapper model={model} editor={editor}>
|
|
|
|
{inner}
|
|
|
|
</EditWrapper>
|
|
|
|
);
|
2022-07-07 09:49:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function EmptyRenderer<T>(_: SceneComponentProps<T>): React.ReactElement | null {
|
|
|
|
return null;
|
|
|
|
}
|
2022-11-16 04:36:30 -06:00
|
|
|
|
|
|
|
function getSceneEditor(sceneObject: SceneObject): SceneEditor {
|
|
|
|
const { $editor } = sceneObject.state;
|
|
|
|
if ($editor) {
|
|
|
|
return $editor;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sceneObject.parent) {
|
|
|
|
return getSceneEditor(sceneObject.parent);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('No editor found in scene tree');
|
|
|
|
}
|