Skip to content

EntropyCanvas::SceneReplicator

Schema-driven scene replicator using Flecs runtime API. More…

#include <SceneReplicator.h>

Name
~SceneReplicator() =default
voidsetSchemaService(ComponentSchemaService * service)
Set the schema service for cached schema access.
voidsetMaterialReceivedCallback(MaterialReceivedCallback callback)
Set callback for when new materials are received from network.
voidsetMaterialPropertyChangedCallback(MaterialPropertyChangedCallback callback)
Set callback for when material properties are changed from network.
ComponentSchemaService *schemaService() const
Get the schema service.
voidregisterPostProcessor(const EntropyEngine::Networking::ComponentTypeHash & typeHash, PostProcessHandler handler)
Register a post-processing handler for a component type.
template <typename T >
void
registerComponent(flecs::world & world, const EntropyEngine::Networking::ComponentSchema & schema, ComponentTrustLevel trustLevel =ComponentTrustLevel::AppRegistered, std::function< T()> defaultFactory =[] { return T{};})
Register a component type with its schema.
size_tregisterBuiltinComponents(flecs::world & world)
Register all built-in Canvas components.
SceneReplicator &operator=(const SceneReplicator & ) =delete
SceneReplicator &operator=(SceneReplicator && ) =default
boolisBuiltin(const EntropyEngine::Networking::ComponentTypeHash & typeHash) const
Check if a component type is a built-in (SDK registered).
voidinvokePostProcessor(flecs::entity entity, const PropertyDelta & delta)
Invoke post-processor for a component type if registered.
boolhasComponent(const EntropyEngine::Networking::ComponentTypeHash & typeHash) const
Check if a component type is registered.
voidhandleMaterialReceived(const AssetId & materialId, const MaterialData & data)
Handle a material received from the network.
voidhandleMaterialPropertyChanged(const AssetId & materialId, const std::string & propertyName, const MaterialPropertyValue & value, uint64_t version, uint64_t originSessionId)
Handle a material property change from the network.
std::optional< ComponentTrustLevel >getTrustLevel(const EntropyEngine::Networking::ComponentTypeHash & typeHash) const
Get the trust level for a registered component.
template <typename Func >
void
forEachBuiltin(Func && func) const
Iterate over all registered builtin components.
boolcreateDefaultComponent(flecs::entity entity, const EntropyEngine::Networking::ComponentTypeHash & typeHash)
Create a default component from type hash.
boolapplyPropertyUpdate(const EntropyEngine::Networking::PropertyHash & hash, const EntropyEngine::Networking::PropertyValue & value, flecs::world & world, EntropyEngine::Networking::PropertyRegistry * propertyRegistry)
Apply property update from network using PropertyHash.
boolapplyProperty(flecs::entity entity, const EntropyEngine::Networking::ComponentTypeHash & typeHash, const std::string & propertyName, const EntropyEngine::Networking::PropertyValue & value)
Apply a property value using schema offsets.
SceneReplicator() =default
SceneReplicator(const SceneReplicator & ) =delete
SceneReplicator(SceneReplicator && ) =default
class EntropyCanvas::SceneReplicator;

Schema-driven scene replicator using Flecs runtime API.

SceneReplicator bridges ComponentSchema definitions with Flecs ECS, enabling property updates to be applied using schema offsets for direct memory writes without type-specific handlers.

Usage:

  1. During initialization, register component types with their schemas
  2. At runtime, call applyProperty() to write values using schema offsets
  3. Call createDefaultComponent() to add default-initialized components

Example:

SceneReplicator replicator;
// Initialization (single-threaded)
replicator.registerBuiltinComponents(world);
replicator.registerComponent<MyCustom>(world, mySchema);
// Runtime (caller provides synchronization)
std::lock_guard lock(myMutex);
replicator.applyProperty(entity, typeHash, "position", newPosition);
~SceneReplicator() =default
void setSchemaService(
ComponentSchemaService * service
)

Set the schema service for cached schema access.

Parameters:

  • service Pointer to the schema service (must outlive this object)

Must be called before registerBuiltinComponents().

void setMaterialReceivedCallback(
MaterialReceivedCallback callback
)

Set callback for when new materials are received from network.

Parameters:

  • callback Function to call with material data

Note: NOT thread-safe - call during initialization only

The callback is invoked when handleMaterialReceived() processes a new material. Use this to create local material instances (e.g., in Portal’s MaterialService).

function setMaterialPropertyChangedCallback

Section titled “function setMaterialPropertyChangedCallback”
void setMaterialPropertyChangedCallback(
MaterialPropertyChangedCallback callback
)

Set callback for when material properties are changed from network.

Parameters:

  • callback Function to call with property update info

Note: NOT thread-safe - call during initialization only

The callback is invoked when handleMaterialPropertyChanged() processes an update. Use this to apply property changes to local material instances.

ComponentSchemaService * schemaService() const

Get the schema service.

void registerPostProcessor(
const EntropyEngine::Networking::ComponentTypeHash & typeHash,
PostProcessHandler handler
)

Register a post-processing handler for a component type.

Parameters:

  • typeHash Component type hash (from schema)
  • handler Function to call after property application

Note: NOT thread-safe - call during initialization only

Post-processors are invoked after applyProperty() successfully writes a property value. Use for cache invalidation, asset loading triggers, state activation, etc.

template <typename T >
void registerComponent(
flecs::world & world,
const EntropyEngine::Networking::ComponentSchema & schema,
ComponentTrustLevel trustLevel =ComponentTrustLevel::AppRegistered,
std::function< T()> defaultFactory =[] { return T{};}
)

Register a component type with its schema.

Parameters:

  • world Flecs world to get component ID from
  • schema ComponentSchema with property definitions and offsets
  • trustLevel Trust level for security decisions (default: AppRegistered)
  • defaultFactory Function returning default-initialized T (default: T{})

Template Parameters:

  • T Component type (must be ECS-compatible)

Note: NOT thread-safe - call during initialization only

Must be called during single-threaded initialization with the flecs::world to get the component ID. After registration, applyProperty() can be used to write values using schema offsets.

Security: Built-in components cannot be overwritten. If a component with the same typeHash is already registered as Builtin, registration fails.

size_t registerBuiltinComponents(
flecs::world & world
)

Register all built-in Canvas components.

Parameters:

  • world Flecs world to get component IDs from

Return: Number of components successfully registered

Note:

  • Requires setSchemaService() to be called first
  • NOT thread-safe - call during initialization only

Registers Transform, Light, Mesh, Camera, LightProbe, and ReflectionProbe using schemas from the ComponentSchemaService.

SceneReplicator & operator=(
const SceneReplicator &
) =delete
SceneReplicator & operator=(
SceneReplicator &&
) =default
bool isBuiltin(
const EntropyEngine::Networking::ComponentTypeHash & typeHash
) const

Check if a component type is a built-in (SDK registered).

Parameters:

  • typeHash Component type hash to check

Return: true if registered AND trustLevel is Builtin

Convenience method to check if trustLevel == Builtin.

void invokePostProcessor(
flecs::entity entity,
const PropertyDelta & delta
)

Invoke post-processor for a component type if registered.

Parameters:

  • entity The entity that was modified
  • delta The property delta that was applied

Note: Thread-safe if caller synchronizes entity access

bool hasComponent(
const EntropyEngine::Networking::ComponentTypeHash & typeHash
) const

Check if a component type is registered.

Parameters:

  • typeHash Component type hash to check

Return: true if the component type is registered

void handleMaterialReceived(
const AssetId & materialId,
const MaterialData & data
)

Handle a material received from the network.

Parameters:

  • materialId The AssetId of the material
  • data The complete material data

Invokes the registered MaterialReceivedCallback if set. Call this when receiving CreateMaterialResponse or MaterialResolved messages.

void handleMaterialPropertyChanged(
const AssetId & materialId,
const std::string & propertyName,
const MaterialPropertyValue & value,
uint64_t version,
uint64_t originSessionId
)

Handle a material property change from the network.

Parameters:

  • materialId The AssetId of the material
  • propertyName The name of the changed property
  • value The new property value
  • version The new material version
  • originSessionId The session that made the change

Invokes the registered MaterialPropertyChangedCallback if set. Call this when receiving MaterialPropertyUpdate messages.

std::optional< ComponentTrustLevel > getTrustLevel(
const EntropyEngine::Networking::ComponentTypeHash & typeHash
) const

Get the trust level for a registered component.

Parameters:

  • typeHash Component type hash to check

Return: Trust level if registered, nullopt otherwise

template <typename Func >
inline void forEachBuiltin(
Func && func
) const

Iterate over all registered builtin components.

Parameters:

  • func Callback to invoke for each builtin

Template Parameters:

  • Func Callable with signature void(const ComponentTypeHash&)

Callback receives: (typeHash) for each Builtin component. Use ComponentSchemaService::getSchema(hash) to get schema if needed.

bool createDefaultComponent(
flecs::entity entity,
const EntropyEngine::Networking::ComponentTypeHash & typeHash
)

Create a default component from type hash.

Parameters:

  • entity Target entity
  • typeHash Component type hash identifying which component to create

Return: true if component created successfully, false if typeHash not recognized

Note: Thread-safe if caller synchronizes entity access

Creates a default-initialized component on the entity based on the component type hash. Uses stored component IDs to add the component.

bool applyPropertyUpdate(
const EntropyEngine::Networking::PropertyHash & hash,
const EntropyEngine::Networking::PropertyValue & value,
flecs::world & world,
EntropyEngine::Networking::PropertyRegistry * propertyRegistry
)

Apply property update from network using PropertyHash.

Parameters:

  • hash Property hash from network
  • value Property value to apply
  • world Flecs world to get entity from
  • propertyRegistry Registry for hash → metadata lookup

Return: true if applied successfully

Note: Thread-safe if caller synchronizes entity access

Decodes the PropertyHash via PropertyRegistry to get entity/component/property, then delegates to applyProperty().

bool applyProperty(
flecs::entity entity,
const EntropyEngine::Networking::ComponentTypeHash & typeHash,
const std::string & propertyName,
const EntropyEngine::Networking::PropertyValue & value
)

Apply a property value using schema offsets.

Parameters:

  • entity Target entity
  • typeHash Component type hash (from schema)
  • propertyName Property name (e.g., “position”)
  • value Property value to write

Return: true if property applied successfully, false otherwise

Note: Thread-safe if caller synchronizes entity access

Uses Flecs runtime API to ensure the component exists on the entity, then writes the value directly at the schema-defined offset.

SceneReplicator() =default
SceneReplicator(
const SceneReplicator &
) =delete
SceneReplicator(
SceneReplicator &&
) =default

Updated on 2026-01-26 at 16:50:32 -0500