Skip to content

Observing

RoqueDeicide edited this page Dec 30, 2014 · 1 revision

CryCIL implements Observer design pattern. Currently all events are raised by the subsystem itself, however, in the future, many more objects will use it. You can observe initialization events, react to update events and shutdown.

Native Listeners

Since C++ does not have built-in events, you have to do a lot of manual labor. IMonoInterface.h defines IMonoSystemListener that is an interface for native listener objects that must be either passed to IMonoInterface initializer within a list, or registered by calling MonoEnv->AddListener. You can also remove listeners by calling MonoEnv->RemoveListener.

Example of such a listener:

//! Example implementation of IMonoSystemListener.
struct EventListener : IMonoSystemListener
{
public:
    //! Allows IMonoInterface implementation let the listener access it before global
    //! variable MonoEnv is initialized.
    //!
    //! @param handle Pointer to IMonoInterface implementation that can be used.
    virtual void SetInterface(IMonoInterface *handle)
    {
        // Default implementation of this method sets the field with the value.
        // You can, however, use it in any other way.
        this->monoInterface = handle;
    }
    //! Invoked before Mono interface is initialized.
    //!
    //! IMonoInterface object is not usable at this stage.
    virtual void OnPreInitialization()
    {
        // Do anything that needs to be done before CryCIL initialization begins.
    }
    //! Invoked before Mono run-time initialization begins.
    //!
    //! CryCIL Mono run-time API is not usable at this stage.
    virtual void OnRunTimeInitializing()
    {
        // During this stage Mono run-time environment is only about to begin initialization.
    }
    //! Invoked after Mono run-time is initialized.
    //!
    //! Cryambly is loaded at this point and Mono is running: CryCIL API can be used now.
    virtual void OnRunTimeInitialized()
    {
        // Mono is initialized, we can use it now. Use this method if you want to register internal calls.
    }
    //! Invoked before MonoInterface object defined in Cryambly is initialized.
    virtual void OnCryamblyInitilizing()
    {
        // Cryambly contains definition for a class that serves as a conduit between C++ and C# code.
        // The object of that class is about to be initialized.
    }
    //! Invoked before Cryambly attempts to compile game code.
    virtual void OnCompilationStarting()
    {
        // This method is invoked before code compilation starts, such a feature is not in its final form as of v1.
    }
    //! Invoked after Cryambly finishes compilation of game code.
    //!
    //! @param success Indicates whether compilation was successful.
    virtual void OnCompilationComplete(bool success)
    {
        // This method is invoked after code compilation ends, such a feature is not in its final form as of v1.
    }
    //! Invoked when this listener is registered to get indices of initialization stages
    //! this listener would like to subscribe to.
    //!
    //! Resultant list will be deleted after use, so return a deep copy, if you want it
    //! to be used somewhere else.
    //!
    //! @returns A pointer to a list of integer numbers that represent indices of
    //!          initialization stages this listener wants to subscribe to.
    //!          Null can be return if the listener doesn't want to subscribe to anything.
    virtual List<int> *GetSubscribedStages()
    {
        // This is a very important method, since it allows you to subscribe to initialization stages allowing a very flexible initialization process.
    }
    //! Invoked when one of initialization stages this listener has subscribed to begins.
    //!
    //! @param stageIndex Zero-based index of the stage.
    virtual void OnInitializationStage(int stageIndex)
    {
        // Do anything you wanted for this initialization stage.
    }
    //! Invoked after MonoInterface object defined in Cryambly is initialized.
    virtual void OnCryamblyInitilized()
    {
        // The conduit between C++ and C# is constructed and ready to go.
    }
    //! Invoked after all initialization of CryCIL is complete.
    virtual void OnPostInitialization()
    {
        // CryCIL is initialized.
    }
    //! Invoked when logical frame of CryCIL subsystem starts.
    virtual void Update()
    {
        // Beginning of the frame. Use it to update your subsystems.
    }
    //! Invoked when logical frame of CryCIL subsystem ends.
    virtual void PostUpdate()
    {
        // End of the frame. Use it to update your subsystems.
    }
    //! Invoked when CryCIL shuts down.
    virtual void Shutdown()
    {
        // The CryCIL subsystem is shutting down.
    }
};

Managed Observation

Listening to events in C# is a lot easier: There is no need to implement any interfaces, and you just need to use innate C# capabilities to listen.

Example of Managed Observation:

using CryCil.RunTime;

namespace Example
{
    [InitializationClass]
    public class InitClass
    {
        [InitializationStage(100)]
        public static void CustomSetup(int stageIndex)
        {
            // This method will be invoked during stage #100.
            
            Initialize();
            // Subscribe to events.
            MonoInterface.Instance.Updated += Update;
        }
        private static void Initialize()
        {
            // Initialize the subsystem.
        }
        private static void Update()
        {
            // Update the subsystem.
        }
    }
}
Clone this wiki locally