The InitInfo struct in the Instance.hpp header is responsible for data needed to initialise the framework. The members of the struct can be seen below:

struct InitInfo
{
    std::vector<InlineComponent*> inlineComponents;
    std::vector<TitlebarComponent*> titlebarComponents;
    std::vector<WindowComponent*> windowComponents;
 
    // Provide a global data struct to be shared with all components
    void* globalData = nullptr;
    bool bGlobalAllocatedOnHeap = true; // Set this to false if the global is a stack pointer

    GenericRenderer* customRenderer = nullptr;
    GenericTexture* customTexture = nullptr;

    UImGui_CInitInfo* cInitInfo = nullptr;

    FString frameworkLibraryDir;
    FString applicationDir;
    FString applicationLibraryDir;

    FString configDir;
    FString projectDir;

    FString contentDir;

    FString frameworkIncludeDir;
    FString applicationIncludeDir;
};

The 3 arrays contain generic pointers to the different components that should be rendered.

The globalData void pointer contains data that you can fetch on demand in any component by calling UImGui::Instance::getGlobal().

When cleaning up the globalData, we will automatically default to calling free on it. If the pointer is stack allocated, however, this will result in a segmentation fault. For that reason, you need to set bGlobalAllocatedOnHeap to false.

The customRenderer and customTexture pointers refer to custom renderer and texture renderer backends. More info can be found here

The cInitInfo variable is explained in the C API section.

Directory strings

The following members of the InitInfo struct are used to access framework configuration and resource files:

FString frameworkLibraryDir;
FString applicationDir;
FString applicationLibraryDir;

FString configDir;
FString projectDir;

FString contentDir;

FString frameworkIncludeDir;
FString applicationIncludeDir;

When an instance is generated from the UVKBuildTool, the constructor contains the following code, which initialises the variables above:

MyProject::Instance::Instance()
{
    initInfo =
    {
        UIMGUI_INIT_INFO_DEFAULT_DIRS,
    };
}

This macro and other directory macros can be found under the Generated/Config.hpp file, which looks like this:

#pragma once

// Default defines for these directories. They will only be defined while compiling for production
#ifndef UIMGUI_FRAMEWORK_LIBRARY_DIR
    #define UIMGUI_FRAMEWORK_LIBRARY_DIR "."
#endif

#ifndef UIMGUI_APPLICATION_DIR
    #define UIMGUI_APPLICATION_DIR "."
#endif

#ifndef UIMGUI_APPLICATION_LIBRARY_DIR
    #define UIMGUI_APPLICATION_LIBRARY_DIR "."
#endif

#ifndef UIMGUI_CONFIG_DIR
    #define UIMGUI_CONFIG_DIR ".https://madladsquad.com/Config/"
    #define UIMGUI_PROJECT_DIR ".https://madladsquad.com/"
#endif

#ifndef UIMGUI_CONTENT_DIR
    #define UIMGUI_CONTENT_DIR ".https://madladsquad.com/Content/"
#endif

#ifndef UIMGUI_FRAMEWORK_INCLUDE_DIR
    #define UIMGUI_FRAMEWORK_INCLUDE_DIR ".https://madladsquad.com/Framework/"
#endif

#ifndef UIMGUI_APPLICATION_INCLUDE_DIR
    #define UIMGUI_APPLICATION_INCLUDE_DIR ".https://madladsquad.com/Source/"
#endif

#define UIMGUI_INIT_INFO_DEFAULT_DIRS                           \
    .frameworkLibraryDir = UIMGUI_FRAMEWORK_LIBRARY_DIR,        \
    .applicationDir = UIMGUI_APPLICATION_DIR,                   \
    .applicationLibraryDir = UIMGUI_APPLICATION_LIBRARY_DIR,    \
    .configDir = UIMGUI_CONFIG_DIR,                             \
    .projectDir = UIMGUI_PROJECT_DIR,                           \
    .contentDir = UIMGUI_CONTENT_DIR,                           \
    .frameworkIncludeDir = UIMGUI_FRAMEWORK_INCLUDE_DIR,        \
    .applicationIncludeDir = UIMGUI_APPLICATION_INCLUDE_DIR

When compiling for production, these compiler definitions change to the prefix and configuration in the uvproj.yaml file. More on production deployment here.

Rendering the Hello, World application

2 entries ago, we started a hello world application, but we still haven't initialised it yet. Let's render that text! Enter your Instance.hpp file under Source. It should look like this:

#pragma once
#include <Framework.hpp>

namespace UntitledTextEditor
{
    class UIMGUI_PUBLIC_API Instance : public UImGui::Instance
    {
    public:
        Instance();
        virtual void begin() override;
        virtual void tick(float deltaTime) override;
        virtual void end() override;
        virtual ~Instance() override;

        virtual void onEventConfigureStyle(ImGuiStyle& style, ImGuiIO& io) override;
    private:
    };
}

First, include the hello.hpp file above and create an instance of the hello class as a member variable.

In your Instance.cpp file, all you need to do is modify the InitInfo. Simply put this line into your constructor so that it looks like this:

UntitledTextEditor::Instance::Instance()
{
    initInfo.inlineComponents = { &hello };
}

And run your application. We have a hello world message!

Event safety

The entire module is flagged as event safe at Any time.

C API

The UImGui_CInitInfo struct

The C++ version of InitInfo contains a pointer to a struct of type UImGui_CInitInfo, which is the C API version of the InitInfo struct. The 2 structs are completely separate and are not replaced by one another at any point.

The UImGui_CInitInfo struct looks like this:

typedef struct UImGui_CInitInfo
{
    UImGui_CComponentHandle* inlineComponents;
    size_t inlineComponentsSize;

    UImGui_CComponentHandle* titlebarComponents;
    size_t titlebarComponentsSize;

    UImGui_CComponentHandle* windowComponents;
    size_t windowComponentsSize;

    UImGui_CInstanceRegularFun* constructFuncs;
    size_t constructSize;

    UImGui_CInstanceRegularFun* beginFuncs;
    size_t beginSize;

    UImGui_CInstanceTickFun* tickFuncs;
    size_t tickSize;

    UImGui_CInstanceRegularFun* endFuncs;
    size_t endSize;

    UImGui_CInstanceRegularFun* destructFuncs;
    size_t destructSize;

    void* globalData;
    bool bGlobalAllocatedOnHeap;

    UImGui_CGenericRenderer* customRenderer;
    UImGui_CGenericTexture* customTexture;
} UImGui_CInitInfo;

Here there are the familiar 3 events, which store C component handles. Additionally, there are the 2 variables related to global data, globalData and bGlobalAllocatedOnHeap, which are separate from their C++ equivalents.

Finally, there are the Instance events, which can be used to bind to the global instance's events. They are the following:

  1. constructFuncs - Called in the constructor
  2. beginFuncs - Called on begin event
  3. tickFuncs - Called on tick event
  4. endFuncs - Called on end event
  5. destructFuncs - Called in the destructor

These events are of type UImGui_CInstanceRegularFun, which expands to void(*)(UImGui_CInitInfo*), except for tickFuncs, which is of type UImGui_CInstanceTickFun, which expands to void(*)(UImGui_CInitInfo*, float).

All arrays, have their according size variables of type size_t, which must be set correctly.

Interacting with the C API

There are 3 functions that can be used to interact with the C Instance and InitInfo API:

  1. UImGui_Instance_setCInitInfo - given a pointer to a UImGui_CInitInfo struct, it sets the C init info
  2. UImGui_Instance_getCppInitInfoGlobalData - Returns the global data pointer from the C++ side, given a pointer to a bool that will be populated with the C++ value of bGlobalAllocatedOnHeap
  3. UImGui_Instance_getCLIArguments - Returns the array of CLI arguments of type char**, given a pointer to an int, which will be set to the number of arguments.
  4. The rest - Returns a UImGui_String pointing to the directory strings in the C++ InitInfo struct