ferroui-native 0.3.0

The macOS platform of FerroUI: windows, input, clipboard, drag and drop, menus and Metal and OpenGL graphics over a native library
Documentation
#include "common.h"

class PlatformRenderTimer : public ComSingleObject<IFrnPlatformRenderTimer, &IID_IFrnPlatformRenderTimer>
{
private:
    ComPtr<IFrnActionCallback> _callback;
    CVDisplayLinkRef _displayLink;

public:
    FORWARD_IUNKNOWN()

    // The display link calls back with this object as its context: it is
    // stopped and released with the object, or a tick that comes after the
    // last reference was given back (at the exit of the process, while the
    // exit handlers run) reads a freed object.
    virtual ~PlatformRenderTimer()
    {
        if (_displayLink != nil)
        {
            CVDisplayLinkStop(_displayLink);
            CVDisplayLinkRelease(_displayLink);
            _displayLink = nil;
        }
    }

    virtual int RegisterTick (
        IFrnActionCallback* callback) override
    {
        START_COM_CALL;
        
        @autoreleasepool
        {
            if (_displayLink != nil)
            {
                return E_UNEXPECTED;
            }

            _callback = callback;
            auto result = CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
            if (result != 0)
            {
                return result;
            }

            result = CVDisplayLinkSetOutputCallback(_displayLink, OnTick, this);
            if (result != 0)
            {
                return result;
            }
        }
        return S_OK;
    }

    virtual void Start () override
    {
        START_COM_CALL;

        @autoreleasepool
        {
            if (CVDisplayLinkIsRunning(_displayLink) == false) {
                CVDisplayLinkStart(_displayLink);
            }
        }
    }

    virtual void Stop () override
    {
        START_COM_CALL;

        @autoreleasepool
        {
            if (CVDisplayLinkIsRunning(_displayLink) == true) {
                CVDisplayLinkStop(_displayLink);
            }
        }
    }

    virtual bool RunsInBackground () override
    {
        START_COM_CALL;

        @autoreleasepool
        {
            return true;
        }
    }
    
    static CVReturn OnTick(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext)
    {
        START_ARP_CALL;
        PlatformRenderTimer *object = (PlatformRenderTimer *)displayLinkContext;
        object->_callback->Run();
        return kCVReturnSuccess;
    }
};

extern IFrnPlatformRenderTimer* CreatePlatformRenderTimer()
{
    return new PlatformRenderTimer();
}