Plugin Architecture

Prysm has a specific initialization/deinitialization structure, Game loop, and thread restrictions that you must comply with for it to function properly. Prysm comes with a pre-implemented integration code that handles all of these details for you. If you wish to create your integration or understand how it works under the hood, you’ll need to take care of the plugin’s workflow and its components yourself.

Initialization

In general, the Unity3D integration plugin goes through the following steps:

On the main thread:

  • Initialize Cohtml - This step occurs upon the initial launch of the Player by initializing the Library.Initialize method.
  • Create System - That happens when calling Library.CreateSystem This step occurs each time the player is launched by initializing the System component existing on the scene. It will not be destroyed when transitioning to a new scene and will persist until the Player is stopped. The system is initialized from the Library instance.
  • Create Views - The Views are created from the already instantiated UI System by the System.CreateView. Their lifespan continues until their destruction or transitioning to another scene.
  • Record events (input mouse, keyboard, touches, etc.) and update internal components - The Advance method of the CohtmlView and CohtmlUISystem components are called on each Update method to send the events registered during the frame.
  • Destroy Views and Systems - when the Player is stopped, will destroy the CohtmlView and CohtmlSystem components.
  • De-initialize Cohtml - When stopping the Player or from Unity3D Editor. Upon this event, it must be ensured that all Views, Systems, and Library are disposed of in that order, as well as their associated components.

On the render thread:

  • Create a System renderer - This happens in the Start method as soon as the component is created registering a render event. An event is sent to the Native Plugin.
  • Create View renderers - An event is sent to the Native Plugin immediately upon object creation in the MonoBehaviour.Start method by registering the native render event in the UnityPlugin.
  • Paint UI in textures - Compose the UI as a HUD or in the game world. The View.Draw method makes a render event in the plugin to update the rendering of each frame.
  • Free rendering resources and destroy renderers - In this step, all Renderers and their associated resources are released first from the loaded page in the View, and then the View object itself is destroyed, as outlined in the Main Thread section.

Game loop

The CohtmlView and the CohtmlUISystem components require constant updating every frame. To achieve this you have to call their update methods in Unity3D’s Update method. For example, NativeView.Advance and SystemNative.Advance methods are invoked on the main thread. These APIs will update the Cohtml internal clock, the animations, DOM events, input events, etc. At the same time, on the render thread, Cohtml renders the UI textures by calling the CohtmlView.Draw method. For more detailed information you can check the looping page for the native Cohtml library.

Deinitialization

  • When destroying Cohtml components, you must follow a specific order - first destroy Views then Systems then Library.
  • Each component is responsible for destroying the component attached before it. For example, the System destroys the attached Views.
  • Each component should first destroy its native Cohtml reference.
  • Each component should first destroy its rendering if it exists.
  • Each component should also destroy all referenced components attached and depend on it. For example, the CohtmlSystem destroys the TextInputHandler.

The deinitialization of objects must happen in the following order:

On the render thread:

  • Destroy each View Renderer - Mark for destroying the native object at the main thread.
  • Destroy each System Renderer - Mark for destroying the native object at the main thread.

On the main thread:

  • Destroy each View. Unload the view page document.
  • Destroy each System, make sure doesn’t have alive Views.
  • Stop the worker’s threads.
  • Destroy the C# Library.
  • On quitting Destroy Native Library.

All resources that are owned by the application - resource readers, loggers etc., must be destroyed after the Cohtml objects that use them.

UPM Packages structure

The Prysm UPM package has the following structure:

  • Editor - contains the editor scripts for Prysm. It will be ignored when building.
  • Plugins - contains the Cohtml libraries. These are automatically copied when building.
  • Runtime - contains the Prysm integration classes. You’ll find a Detail folder inside which contains classes that are internal for the implementation and are used by the “public” classes.
  • StreamingAssets/Cohtml/UIResources - contains the UI resources for Prysm.
    • These are automatically copied when building the Player.
    • You can also load resources from your custom locations.
  • Documentation - Offline content for Prysm documentation.
  • Native Player~ - The folder contains the native Player and Player Overrides project.

Additionally, you can have additional packages containing necessary integration assets for the specific platform you want to support. These packages have the following structure:

  • Managed - The .Net Assembly, which serves as the link between the Plugin and the integration.
  • Plugins - Plugin files needed for the specific platform.
  • Runtime - C# components that extend the integration of this platform. Not every package contains this folder, as some platforms do not have additional implementation details.

Building

The necessary plugin files are configured to be imported accordingly to the different platforms. When you change the target platform and build the Player with the imported Cohtml Plugin - everything should work out of the box. The native plugin files are located in the Plugins folder, divided into subfolders named after the platforms they are intended for. Some platforms have different architectures, so certain platforms are further divided by architecture level.

  • cohtml - The Cohtml native library.
  • RenoirCore - The rendering native library.
  • cohtml_Unity3DPlugin - The native library containing logic needed by Cohtml to work with the Unity3D engine.
  • cohtml.Net - The .Net assembly containing C++ translated into the C# code wrapper for the Cohtml API.
  • HttpServer - this native library provides the DevTools support.
  • MediaDecoders - The native library provides playing video in the HTML pages.

The unspecified files you can find in the Plugins folder are dependencies of the Cohtml library. They need to be present in your project for Cohtml to function correctly in the Unity3D editor or a built player. More information about Cohtml architecture can be found here.

Pre-release remove assets

Some assets can be removed from the UPM package to prevent them from being packaged into the built application. They are located at the following locations:

  • HttpServer and MediaDecoders - If you don’t want these optional features, you can remove them from Packages/[CohtmlPackage]/Plugins/[Platform]/.
  • UPMPackage/Resources/Cohtml/SharedImages - Here are your Preloaded images. You can delete the resources you don’t use.
  • UPMPackage/Resources/Fonts - Preloaded Fonts are stored here. You can delete the resources you don’t use.