API reference
API reference
Select your platform
No SDKs available
No versions available

Context Class

Extends MonoBehaviour
Context is a tool for coordinating the operation of disparate instances in a generalized and decoupled way: different instances can collaborate with one another without directly depending on one another by sharing data and conventions using a Context.
A common example of this kind of collaboration is for instance decoration; for detailed commentary on that usage, see DecoratorBase<InstanceT, DecorationT>.
Conceptually, a Context is a logical scope of ownership and operation which is not bound to a specific region of the implementation. Just as a code scope (the braces after an if or for statement, for example) both owns and provides access to the data it contains for example, an int variable declared in a scope will be automatically released when the scope end, but within the scope it can be accessed by its name so too is a Context capable of owning and providing access to data required by the operations it supports/logically "contains." Contexts are a common feature of many libraries, including examples such as System.AppContext from the .NET API itself.
The Context implementation provided here is specifically designed to support a "safe singleton" pattern in Unity applications. The "safe singleton" pattern aims to provide the majority of the benefits of singletons (mainly simplicity) while avoiding the problems associated with global state; this is achieved because "safe singletons" are not "global" to the app, but are merely "global" to a particular Context instance which owns, enforces the uniqueness of, and provides access to its singletons.
The impact of this pattern on true global state is thus confined to the provided GlobalContext instance. This instance is provided for convenience and is very valuable for quick-and-dirty work. However, because this does have an (albeit confined) impact on centralized global state, development which must be scalable should not rely on the GlobalContext. Libraries, for example, which wish to leverage Context-based patterns should simply define and expose their own Instance to avoid colliding with global considerations.

Properties

Global : Instance
[Get]
The global Context, which can be used as a default Context for quick-and-dirty development.
This Instance is provided for convenience and can be safely used for end-product development (i.e., for the development of an individual game), but development that must incorporate or scale (i.e., library development) should rely on independently Context Instances instead. See the remarks on Context and Instance for a more detailed exploration of this topic.
Signature
Instance Oculus.Interaction.Context.Global

Events

WhenDestroyed : Action
Event which signals the destruction of a Context, allowing dependent instances an opportunity to react.
Signature
Action Oculus.Interaction.Context.WhenDestroyed

Methods

GetOrCreateSingleton< T > ()
Retrieves a Context-local or "safe" singleton instance from this Context.
If an instance of the requested type already exists on this Context, that instance will be returned; otherwise, a new one will be lazily created.
This method implements the "safe singleton" pattern discussed in the remarks on the Context. While the name "GetOrCreate" is used to clarify that the requested instance may be created during this call, this method should really only be thought of as an accessor with any instantiation that may or may not happen being simply an irrelevant implementation detail. Ideally, you should think of Context-local singletons as aspects of the Context itself rather than as separate instances which can be created and destroyed independently. Adhering to this thinking will ensure that order-of-operations and independent lifecycles do not complicate the usage of Context. As long as the Context merely exists, all singletons on it can always be accessed identically using GetOrCreateSingleton; all other considerations are the purview of the singletons themselves.
Signature
T Oculus.Interaction.Context.GetOrCreateSingleton< T >()
Returns
T  A Context-local singleton of the requested type
GetOrCreateSingleton< T > ( factory )
Retrieves a Context-local or "safe" singleton instance from this Context.
If an instance of the requested type already exists on this Context, that instance will be returned; otherwise, a new one will be lazily created by invoking the provided factory callback.
This method differs from GetOrCreateSingleton<T> in that it accepts a factory callback, which it will invoke to create the singleton if necessary instead of simply calling new(). This is useful for singleton types which can only be constructed with arguments, or for types with private constructors. This method implements the "safe singleton" pattern discussed in the remarks on Context and further explored in the remarks on GetOrCreateSingleton<T>.
Signature
T Oculus.Interaction.Context.GetOrCreateSingleton< T >(Func< T > factory)
Parameters
factory: Func< T >  A callback which creates a singleton of the requested type
Returns
T  A Context-local singleton of the requested type

Static Methods

ExecuteOnMainThread ( work )
Executes the specified work on the main Unity thread.
This function provides an easy way for work triggered from arbitrary threads to be performed specifically on the main thread; for example, FinalAction uses this method to cause a callback invoked during destruction (which can happen on any thread) to be executed on the Unity main thread.
Unity 6+ introduces improved support for asynchronous programming techniques, including a new https://docs.unity3d.com/6000.0/Documentation/Manual/async-await-support.html which can be used for the same purpose as this method.
Signature
static void Oculus.Interaction.Context.ExecuteOnMainThread(Action work)
Parameters
work: Action  The work to execute on the main thread
Returns
void

Inner Class

Instance Class

Instance is a helper class for conveniently creating custom Contexts using a code-centric approach.
When creating your own Context instances, there are two main patterns you can use: an Editor-centric pattern and a code-centric pattern. For an Editor-centric pattern, simply attach a Context to a GameObject and "wire it up" to Editor-exposed fields as you would with any other Unity Component. The accessibility and lifespan, in Editor or in Code, of a Context created this way adheres to typical Unity patterns. This usage is most appropriate small-scope uses for example, if an individual prefab needs a Context specific to its own usage to faciliate operations local to the context of each prefab instance.
By contrast, the Instance class is intended to help with a code-centric pattern. In this pattern, the Context in question is lazily created at runtime (rather than saved as part of the scene) and thus cannot be "wired up" to dependencies in the Editor. While the Context within an Instance can be retrieved using Component accessors at runtime, it should typically be accessed through the Instance proper, which will lazily initialize the Context instance as needed. This pattern is most appropriate for large and/or long-lived usage scopes, particularly for Contexts which should not be destroyed before app teardown. Destroying Instance Contexts, as well as accessing them during app teardown, involves special considerations explored more deeply in the remarks on GetInstance.

Constructors

Instance ( name )
Basic constructor.
This sets the name which will be given to the lazily-created GameObject which will host the underlying Context.
Signature
Oculus.Interaction.Context.Instance.Instance(string name)
Parameters
name: string  The name which will be given to the lazily-created GameObject

Methods

GetInstance ()
Retrieves the Context which underlies this Instance; if a valid one does not currently exist, a new one is lazily created.
Note that destroying the GameObject and/or Context created by an Instanceis supported and will successfully tear down the Context; however, if GetInstance is subsequently queried, it will simply lazily create a new Context. This has particular implications on the use of Instance Contexts during app teardown, where order of destruction is not guaranteed and attempts to access an existing InstanceContext may result in the creation of a new Context instead if the prior Context happens to have been destroyed first. For this reason, if access to a specific Context is needed in teardown logic (or to a lesser degree any other logic), you should locally cache a reference to the underlying Context and only invoke GetInstance if the old instance is destroyed and you specifically need a reference to the new one.
Signature
Context Oculus.Interaction.Context.Instance.GetInstance()
Returns
Context  The Context underlying this Instance