Vixen
dd8b0a81
csharp
public record class AuthoringAssembly

An assembly that declares components or behaviours, named so its declarations run.

Read the guide page for this →

Remarks

Doc 36 § D5's fourth row, and F11's replacement. That was three hardcoded RunModuleConstructor calls inside the component panel — a list, in the application, of which subsystems exist — so a plugin whose components lived in a runtime assembly of its own could not appear in Add ▸ at all. This is a contribution: the application declares the subsystems it ships and a module declares its own, through the same registry.

⚠ A module initializer does not run until something touches the module, and that is the whole problem. A component registers itself to SceneComponentRegistry from a [ModuleInitializer] the generator emits — but the runtime is entitled to defer it indefinitely, so a registry read during the editor's construction sees whatever happened to have been loaded by then. What that looked like was an Add Component menu offering Camera and nothing else, with every component drawn in the viewport arriving a second later and never being offered.

⚠ A declaration rather than a scan, which is SceneComponentRegistry's own argument restated. Walking the output directory reads metadata a trimmed publish has already deleted, and it would make "what can be added" a question with a different answer in the editor, in a worker process and in a shipped game. What is declared is what somebody wrote down.

⚠ This does not make the components appear — it makes them appear on time. The panel re-reads the registries on every enumeration, so an assembly touched by anything at all shows up eventually. The failure this prevents is the one where nothing ever touches it: an audio subsystem the editor references and never calls into is a subsystem whose components exist in the build and in no menu.

⚠ Measured: the Type in the parameter is what does the work, and Touch is belt to its braces. OutOfTreePluginTests compiles a library nothing else in the process has ever heard of, gives it a [ModuleInitializer] that declares a component, and loads it beside an out-of-tree plugin. Naming any type in it from that plugin's Activate — a bare typeof, on a type that is not the component and is not the marker — registers the component; naming none of them registers nothing. And gutting Touch to an empty body leaves all 527 tests in Vixen.Editor.App.Tests passing, ComponentTests.The_subsystems_that_declare_components_are_loaded_before_the_list_is_read included. So on this runtime a module's initializers have run by the time anybody is holding a Type out of it — and nobody can build one of these without holding one.

⚠ Which is why the declaration is still worth writing and the call is still worth making. The declaration is the part that survives: it is the list of assemblies somebody named, and deleting a line from it deletes a component from Add ▸ whatever runs the initializer. The call stays because what was measured is one runtime's behaviour and not a guarantee of the language — Touch costs one call that the runtime answers by doing nothing.

⚠ The contrast that makes it clear which of the two an explicit run is needed for: ProjectAssemblies.Load holds an Assembly and nothing else. It calls RunModuleConstructor on the manifest module because nothing in that path ever names a type in it — "loading is not touching", as it says. Here the caller has named a type by the time there is a record to add, so the touching has already happened.

Fields and properties (1)

  • public Type Marker

    Any type in the assembly. A type rather than an Assembly because the caller has one to hand and writing typeof(AudioSource) says which components are meant, where typeof(X).Assembly says the same thing one indirection later.

Methods (2)

  • public AuthoringAssembly(Type Marker)

    An assembly that declares components or behaviours, named so its declarations run.

  • public void Touch()

    Runs the declaring assembly's module initializers, if they have not run.

Used by (5)

  • AuthoringSubsystemsVixen.Editor.App.Tests
  • ComponentTestsVixen.Editor.App.Tests
  • ComponentsViewVixen.Editor.App
  • EditorApplicationVixen.Editor.App
  • OutOfTreePluginTestsVixen.Editor.App.Tests