Data model: Difference between revisions

From Resonite Wiki
Created a page for the Data Model.
 
add img
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
The '''Data Model''' refers to the collection of primitive types and abstract concepts within the [[FrooxEngine]], and are therefore synced with the model when defined within the code base in the engine.
The '''data model''' refers to the declaration, structure, and handling of [[types]], data, and changes on data within [[FrooxEngine]]. The data model allows for change detection, value synchronization, unified structure, and serialization of any and all types that FrooxEngine encounters.


An example of a [[Type:Type|type]] that is not defined currently (or at least not very supported) with the Data Model is the [[Type:Guid|GUID]] type, and thus has a high potential of breaking the engine, causing a crash when used in certain ways, and many other oddities.
== Elements ==


Local elements are also not part of the data model and thus also not synced, but are tracked using the [[ProtoFlux:Is Local Element|Is Local Element]] node. There is currently no way of making a slot have this kind of behavior without the use of mods.
Everything that gets managed by the data model in some fashion implements the [[Type:IWorldElement|IWorldElement]] interface. This interface assigns elements with a host of properties, including a [[Type:RefID|reference ID]], possible parent element, and whether the element is persistent or not. Since all types implementing this interface has a reference ID, every element is itself a [[reference type]].


for a complete list of what is in the data model, see [[Core Concepts#Data Model|core concepts]].
This interface doesn't have much behavior by itself--it only specifies a thing as being able to be saved and loaded into [[worlds]] in some fashion. More complex behaviors offered by the data model are provided by types that implement this interface. The three types of elements that directly implement this interface are ''sync elements'', ''workers'', and ''worlds''.
 
== Sync elements ==
 
[[File:Inspector vgd elements worker inspectors.webp|thumb|right|A [[scene inspector]] shows every public sync element under components on a slot as little white text. Worker inspectors display what makes up one particular worker, such as components or sync objects]]
 
[[Type:SyncElement|Sync elements]] represent a value or object that can be written to, [[field linkage|linked]], and send/receive change events from other elements. Sync elements mainly comprise of [[Type:SyncField|fields]] and various types of collections--usually any type name that starts with <code>Sync</code> derives from a sync element.
 
The main thing that separates sync elements from other elements is, well, synchronization. Whenever a sync element is changed, spare few exceptions like [[Type:RawOutput`1|RawOutput&lt;T&gt;]], it and its entire parent hierarchy propagate a change event. This includes the elements getting put in the world's update manager to synchronize their values at the end of the [[update loop]].
 
=== Linkage ===
 
{{Main|Linkage}}
 
Linkage is a way to give exclusive control of a sync element to one source, often referred to a driver. Two types of linkage exist: ''links'' and ''drives'', while drivers may choose an optional ''hook''.
 
When a field is linked, it is shown as cyan in inspectors. Linked fields still send data model events as any normal field, but can only be changed by the driver.
 
When a field is driven, it is shown as purple in inspectors. Driven fields act the same as linked fields, but the value of a driven field will not be synchronized across the network. This allows for per-user values or local calculations of things that would otherwise be expensive to network.
 
== Workers ==
 
[[Type:Worker|Workers]] are, in essence, containers for sync elements and other workers to provide a specific, individual task for the engine. Examples of workers include [[slots]], [[components]], sub-classes of components, and [[streams]]. Workers are able to receive events from their children and propagate events to their parent.
 
Workers themselves are a local construct. However, they usually exist in sync element collections, and thus their existence is usually synchronized across users along with their elements.
 
== Events ==
 
A big part of the data model's function is capturing changes to an element or worker and propagating these changes across the element's parent and references to the element. Everything that exists within the data model can capture and send these events, while things outside the data model will usually not.
 
For example, the [[ProtoFlux:Changeable Source|Changeable Source]] ProtoFlux node is able to receive change events from the element that it references. A changeable source of a [[Type:slot|slot]] plugged in to a [[ProtoFlux:Get Slot Active|Get Slot Active]] node will be able to update a connected [[listener node]] whenever the active state of the slot changes. However, an [[ProtoFlux:Input|Input]] node will not update any connected listener nodes in the same fashion. This is due to the former node receiving events from the data model, while the latter does not. Whenever the active field of a slot (a sync element) changes, it propagates that change to the slot itself (the worker containing the active field), which will then get received by the changeable source and thus the entire [[context]] of the listener node.
 
== World ==
 
The heart of the data model is a [[world]]. The world [[update loop]] controls the communication and events between all individual concepts of the data model as one unified pipeline. This includes, but is not limited to:
 
* The [[Type:UpdateManager|UpdateManager]] for managing all sync elements that are "dirty" and the changes that they incur on other elements/workers.
* The [[Type:LinkManager|LinkManager]] for managing all of linkage within a world.
 
== Strict exclusivity ==
 
The data model can only function without issue when everyone in a session agrees on what the data model should be. If one client tells another client about an element type or worker type that doesn't exist for the recipient, the recipient won't know what to do with the information or how to sync the potential element values. This is the reason why [[plugins]] marked as a [[How To Create Plugins/DataModelAssemblyType|core]] assembly type cause incompatible sessions with those who do not have the plugin.
 
== Further reading ==
 
* [[:Category:Data model]] for more in-depth aspects about various parts of the data model.
 
[[Category:Data model]]

Latest revision as of 06:06, 4 July 2025

The data model refers to the declaration, structure, and handling of types, data, and changes on data within FrooxEngine. The data model allows for change detection, value synchronization, unified structure, and serialization of any and all types that FrooxEngine encounters.

Elements

Everything that gets managed by the data model in some fashion implements the IWorldElement interface. This interface assigns elements with a host of properties, including a reference ID, possible parent element, and whether the element is persistent or not. Since all types implementing this interface has a reference ID, every element is itself a reference type.

This interface doesn't have much behavior by itself--it only specifies a thing as being able to be saved and loaded into worlds in some fashion. More complex behaviors offered by the data model are provided by types that implement this interface. The three types of elements that directly implement this interface are sync elements, workers, and worlds.

Sync elements

A scene inspector shows every public sync element under components on a slot as little white text. Worker inspectors display what makes up one particular worker, such as components or sync objects

Sync elements represent a value or object that can be written to, linked, and send/receive change events from other elements. Sync elements mainly comprise of fields and various types of collections--usually any type name that starts with Sync derives from a sync element.

The main thing that separates sync elements from other elements is, well, synchronization. Whenever a sync element is changed, spare few exceptions like RawOutput<T>, it and its entire parent hierarchy propagate a change event. This includes the elements getting put in the world's update manager to synchronize their values at the end of the update loop.

Linkage

Main article: Linkage

Linkage is a way to give exclusive control of a sync element to one source, often referred to a driver. Two types of linkage exist: links and drives, while drivers may choose an optional hook.

When a field is linked, it is shown as cyan in inspectors. Linked fields still send data model events as any normal field, but can only be changed by the driver.

When a field is driven, it is shown as purple in inspectors. Driven fields act the same as linked fields, but the value of a driven field will not be synchronized across the network. This allows for per-user values or local calculations of things that would otherwise be expensive to network.

Workers

Workers are, in essence, containers for sync elements and other workers to provide a specific, individual task for the engine. Examples of workers include slots, components, sub-classes of components, and streams. Workers are able to receive events from their children and propagate events to their parent.

Workers themselves are a local construct. However, they usually exist in sync element collections, and thus their existence is usually synchronized across users along with their elements.

Events

A big part of the data model's function is capturing changes to an element or worker and propagating these changes across the element's parent and references to the element. Everything that exists within the data model can capture and send these events, while things outside the data model will usually not.

For example, the Changeable Source ProtoFlux node is able to receive change events from the element that it references. A changeable source of a slot plugged in to a Get Slot Active node will be able to update a connected listener node whenever the active state of the slot changes. However, an Input node will not update any connected listener nodes in the same fashion. This is due to the former node receiving events from the data model, while the latter does not. Whenever the active field of a slot (a sync element) changes, it propagates that change to the slot itself (the worker containing the active field), which will then get received by the changeable source and thus the entire context of the listener node.

World

The heart of the data model is a world. The world update loop controls the communication and events between all individual concepts of the data model as one unified pipeline. This includes, but is not limited to:

  • The UpdateManager for managing all sync elements that are "dirty" and the changes that they incur on other elements/workers.
  • The LinkManager for managing all of linkage within a world.

Strict exclusivity

The data model can only function without issue when everyone in a session agrees on what the data model should be. If one client tells another client about an element type or worker type that doesn't exist for the recipient, the recipient won't know what to do with the information or how to sync the potential element values. This is the reason why plugins marked as a core assembly type cause incompatible sessions with those who do not have the plugin.

Further reading