Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
submodels [2026/07/11 22:38] hermann |
submodels [2026/09/08 20:44] (current) hermann |
||
|---|---|---|---|
| Line 34: | Line 34: | ||
| [{{:submodels:submodel_types.png?900|Different Types of Submodels}}] | [{{:submodels:submodel_types.png?900|Different Types of Submodels}}] | ||
| + | |||
| + | ==== Access Scope ==== | ||
| + | |||
| + | The four submodel types differ in who can see and use them, from narrowest to broadest: | ||
| + | |||
| + | * **Local Submodel** — scoped to the single model it belongs to. It is not automatically visible from any other model, not even other models owned by the same user; to use it elsewhere, it must be explicitly copied into that other model (see [[#copying_importing_a_local_submodel_between_models|Copying (Importing) a Local Submodel Between Models]]), becoming an independent copy in the process. | ||
| + | * **User Submodel** — scoped to the user account that created it. It is automatically available across all of that user's models, with no import step needed, but it is not visible to other users of the same machine. | ||
| + | * **Store Submodel** — same per-user scope as a user submodel (available across all of that user's models, not visible to other users), but its content comes from the shared online [[#the_submodel_store|Submodel Store]] rather than from something the user authored. The distinction from a user submodel is about origin, versioning, and storage, not visibility. | ||
| + | * **System Submodel** — the broadest scope: bundled with the Dinamica EGO installation itself, so it is available to every user on every model, and cannot be modified by any user. | ||
| + | |||
| + | This scope ordering is also why local submodels take precedence over user submodels, which in turn take precedence over store submodels, when names collide. A local submodel can be widened to user scope by [[#turning_a_local_submodel_into_a_user_submodel_publishing|publishing]] it; there is no equivalent operation to widen a user or store submodel into a system submodel. | ||
| ==== Where Submodels Are Stored ==== | ==== Where Submodels Are Stored ==== | ||
| Line 72: | Line 83: | ||
| {{youtube>YvoteWC_lnI?size=853x480&rel=0|Creating local submodels }} | {{youtube>YvoteWC_lnI?size=853x480&rel=0|Creating local submodels }} | ||
| + | |||
| + | ==== Creating a Submodel Directly as a Script ==== | ||
| + | |||
| + | A submodel does not have to be created through the GUI: any ''.ego'' file that declares the right set of ''@submodel.*'' properties (name, description, group, and its input/output port declarations) is a valid submodel. See [[ego_script#submodels|Submodels]] in the EGO Script reference for the full property syntax. | ||
| + | |||
| + | Whether a hand-written submodel script becomes a local or a user submodel is determined entirely by where the file is placed, following the same [[#where_submodels_are_stored|storage locations]] used for submodels created through the GUI — the ''@submodel.name'' property, not the filename, is what identifies the submodel. | ||
| ===== Instantiating Local Submodels ===== | ===== Instantiating Local Submodels ===== | ||
| Line 101: | Line 118: | ||
| First, click on the functor whose inputs or outputs will be exported. | First, click on the functor whose inputs or outputs will be exported. | ||
| - | Select //export functor inputs and outputs// on the [[model_presentation#functor_action_bar|functor action bar]] and choose the inputs or outputs that will be exported. It is possible to define the input and output names and their corresponding descriptions. It is also possible to mark an exported input as advanced or optional. Optional inputs can also define an optional value that will be assigned to the port if no explicit value is provided. | + | Select //export functor inputs and outputs// on the [[model_presentation#functor_action_bar|functor action bar]] and choose the inputs or outputs that will be exported. It is possible to define the input and output names and their corresponding descriptions. It is also possible to mark an exported input as advanced or optional. Optional inputs can also define an optional value that will be assigned to the port if no explicit value is provided. A submodel's input ports cannot be declared nullable; a caller-optional input is only made available through this //optional// marking and its associated default value, not by accepting a null value directly. |
| - | Choose //Submodel Options// on the model toolbar and then click //Apply Changes / Edit Submodel Properties//. That brings up the submodel editor dialog where you can define a new name, description and icon for the submodel or reorder its inputs and outputs (or even remove some of them). Clicking //Ok// propagates the changes to all parts of your model (and dependent submodels) where the submodel is used. | + | > **Note:** Any port from the integer family of types can be declared a light enum, which presents it in the GUI as a labeled dropdown instead of a free-form numeric field, via the //Make port available as an enum value// control. This is not specific to submodels — it can be set on any carrier functor of an integer value type in any model, provided the carrier has an editor. When such a carrier's port is exported as a submodel input, its light enum configuration carries over into the submodel's interface. |
| + | |||
| + | Choose //Submodel Options// on the model toolbar and then click //Apply Changes / Edit Submodel Properties//. That brings up the submodel editor dialog where you can define a new name, description, documentation URL, and icon for the submodel, or reorder its inputs and outputs (or even remove some of them). Clicking //Ok// propagates the changes to all parts of your model (and dependent submodels) where the submodel is used. | ||
| The submodel editor dialog also lets you set the submodel's **group**, which controls where it appears in the [[functor_library|Functor Library]]. A group name can contain subgroups by separating them with a colon (''":"''); for example, ''"Elevation Graph:Tools:Debug"'' places the submodel in a //Debug// subgroup, itself inside a //Tools// subgroup, inside an //Elevation Graph// group. This is specific to submodels: an ordinary functor's placement in the Library is fixed by its own definition and cannot be changed by the user, but a submodel's group — and therefore whether it appears in a subgroup — is under the control of whoever creates or edits it. | The submodel editor dialog also lets you set the submodel's **group**, which controls where it appears in the [[functor_library|Functor Library]]. A group name can contain subgroups by separating them with a colon (''":"''); for example, ''"Elevation Graph:Tools:Debug"'' places the submodel in a //Debug// subgroup, itself inside a //Tools// subgroup, inside an //Elevation Graph// group. This is specific to submodels: an ordinary functor's placement in the Library is fixed by its own definition and cannot be changed by the user, but a submodel's group — and therefore whether it appears in a subgroup — is under the control of whoever creates or edits it. | ||
| Line 159: | Line 178: | ||
| Turning a local submodel into a user submodel makes reusing the submodel easier — the submodel will always be available to be used in your next models — but it has some drawbacks as well. You are fully responsible for the consequences of updating a user submodel. Beware that, unlike local submodels, your models will not carry a copy of a user submodel as part of their definition. So, if you change a user submodel in a way that breaks compatibility with the models using its definition, those models will not work anymore. | Turning a local submodel into a user submodel makes reusing the submodel easier — the submodel will always be available to be used in your next models — but it has some drawbacks as well. You are fully responsible for the consequences of updating a user submodel. Beware that, unlike local submodels, your models will not carry a copy of a user submodel as part of their definition. So, if you change a user submodel in a way that breaks compatibility with the models using its definition, those models will not work anymore. | ||
| + | |||
| + | ==== Dependency Propagation When Publishing as a User Submodel ==== | ||
| + | |||
| + | When a local submodel is published as a user submodel, its dependencies become local submodels of the published submodel, rather than independent user submodels of their own. | ||
| + | |||
| + | Consider a local submodel **A** that depends on local submodels **B** and **C**, where **B** also depends on **C**. Publishing **A** as a user submodel produces a single user submodel, **A**, containing **B** and **C** as local submodels of **A**. **B** and **C** sit side by side inside **A**'s own local submodel set, so **B** does not get a separate copy of **C** — it uses the single copy of **C** held by their common parent **A**, the same way one local submodel depends on another local submodel of the same model. **B** and **C** are not added to the user's submodel set as independent, top-level entries — only **A** is. | ||
| + | |||
| + | This flat structure holds regardless of whether **A** uses **C** directly. Even if **C** is used only by **B**, and not by **A** itself, publishing **A** still places **B** and **C** side by side as local submodels of **A** — **C** is not nested inside **B**. | ||
| + | |||
| + | ==== Republishing and Naming Collisions ==== | ||
| + | |||
| + | Publishing or sending a submodel again — whether because the local submodel changed, or because a user submodel of the same name already exists for some other reason — behaves differently depending on the target: | ||
| + | |||
| + | * **User submodels are overwritten by name.** Publishing a local submodel as a user submodel always replaces whatever user submodel currently holds that name, whether that is an earlier published version of the same submodel or an unrelated existing user submodel that happens to share the name. Since dependencies become local submodels of the published submodel rather than independent user submodels (see [[#dependency_propagation_when_publishing_as_a_user_submodel|Dependency Propagation When Publishing as a User Submodel]] above), republishing **A** does not touch any independently named user submodels **B** or **C** — it simply replaces **A**'s local submodels **B** and **C** with their current definitions. | ||
| + | |||
| + | * **Store submodels are versioned, not overwritten.** Sending a submodel to the Store again does not replace the previous submission; it creates a new version, tagged with the Dinamica EGO version in use at the time, following the same versioning behavior described in [[#versioning_and_compatibility|Versioning and Compatibility]]. | ||
| + | |||
| + | ==== Sending a Submodel to the Store ==== | ||
| + | |||
| + | A user submodel can be sent to the online [[#the_submodel_store|Submodel Store]], becoming a store submodel. There are two ways to do this: | ||
| + | |||
| + | * From a local submodel directly, using the //Publish Submodel as a Store Submodel// option on the //Submodel Options// drop-down menu. This first turns the local submodel into a user submodel, then sends that user submodel to the Store. | ||
| + | * From an existing user submodel, using the corresponding button on the //Submodel Manager// dialog (//Submodels// → //Submodel Manager//), which sends that user submodel to the Store directly. | ||
| + | |||
| + | ==== Dependency Propagation When Sending to the Store ==== | ||
| + | |||
| + | When a submodel is sent to the Store, its dependencies are packaged with it rather than published as independent store submodels. | ||
| + | |||
| + | Consider the same local submodel **A**, depending on **B** and **C**, with **B** also depending on **C**. Sending **A** to the Store as a store submodel produces the following structure: | ||
| + | |||
| + | * **A** receives its own local submodel copy of **B** and its own local submodel copy of **C**. | ||
| + | * **B**, in turn, receives its own local submodel copy of **C** — a separate copy from the one held directly by **A**. | ||
| + | |||
| + | The store submodel package therefore ends up containing two independent copies of **C**: one local to **A**, and one local to **B**. Once packaged, these copies are independent of each other, the same as any other local submodels obtained through copying (see [[#copying_importing_a_local_submodel_between_models|Copying (Importing) a Local Submodel Between Models]]). | ||
| + | |||
| + | Unlike publishing to a user submodel, this nesting follows the actual dependency graph. If **C** is used only by **B**, and not by **A** itself, the store submodel package nests **C** inside **B** instead of placing it directly inside **A**: **C** becomes a local submodel of **B**, and **B** a local submodel of **A**. | ||
| + | |||
| + | ==== Dependencies Are Scoped to Their Store Submodel ==== | ||
| + | |||
| + | The local submodel copies of **B** and **C** packaged inside store submodel **A** exist only because **A** depends on them — they have no independent identity of their own. A packaged dependency inside one store submodel is entirely independent of a same-named dependency packaged inside a different store submodel, and of any unrelated user or store submodel that might share the same name; each store submodel's packaged dependencies are private to it. | ||
| ===== The Submodel Store ===== | ===== The Submodel Store ===== | ||
| Line 167: | Line 226: | ||
| To browse and install submodels from the Submodel Store, choose //Submodels// → //Submodel Store// on the model toolbar. Select the desired submodel from the list and click //Install Selected// to download it; it then becomes available locally as a store submodel. | To browse and install submodels from the Submodel Store, choose //Submodels// → //Submodel Store// on the model toolbar. Select the desired submodel from the list and click //Install Selected// to download it; it then becomes available locally as a store submodel. | ||
| + | |||
| + | > **Tip:** To publish your own submodel to the Store instead of installing one, see [[#sending_a_submodel_to_the_store|Sending a Submodel to the Store]]. | ||
| ==== Versioning and Compatibility ==== | ==== Versioning and Compatibility ==== | ||
| Line 215: | Line 276: | ||
| * [[model_presentation|Model Presentation]] | * [[model_presentation|Model Presentation]] | ||
| * [[dinamica_console|Dinamica Console]] | * [[dinamica_console|Dinamica Console]] | ||
| + | * [[ego_script#submodels|EGO Script — Submodels]] | ||