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

    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 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_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