Coherent UI  2.5.3
A modern user interface library for games
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
Sample - Custom File Handler Tutorial

This tutorial will guide you through the sample application for custom file handlers.

It demonstrates reading resources from an archive using zlib. In this case the resources are a web page and a couple of images. The web page is then rendered on the whole screen.

Note
Supplied code, unrelated to Coherent UI integration, is not representative for a well-designed, high-performance solution. It's written for simplicity and its purpose is to demonstrate integration in an existing game framework.

Building the sample

The sample solution is already configured and you only have to compile and run it.

It uses the sample application framework described in the previous sections (Base Application Framework, Sample Application Framework).

The output will be in the Coherent/Samples/UI/bin directory.

Prerequisites

  1. It is helpful to check out the Hello samples for non-framework integrations.
  2. You should read the previous sections (Base Application Framework, Sample Application Framework) to get yourself familiar with the sample application framework used. Some details of the sample are hidden in the sample application framework for brevity.
  3. Zlib is required for unpacking the archived resources used in the sample. A static build of zlib 1.2.7 is provided in the Coherent/Samples/UI/C++/Libs folder, and the sample project is already configured to use it.

Key points

  1. Creating a class derived from Coherent::UI::FileHandler that handles I/O requests.
  2. Passing an instance of that class to CreateViewContext.

Sample walkthrough

Start by including the necessary headers for the sample application framework:

#include <Coherent/Libraries/Application/Entry.h>
#include "../Common/Platform.h"
#include "../Common/Application.h"

and the ones for Coherent UI:

#include <Coherent/UI/ViewContext.h>
#include <Coherent/UI/View.h>
#include <Coherent/UI/ViewInfo.h>
#include <Coherent/UI/ViewListener.h>
#include <Coherent/UI/License.h>

To use a custom file handler, additional includes are required (URLParse.h is needed for parsing the URL string supplied in a callback, more on that in a second):

#include <Coherent/UI/FileHandler.h>
#include <Coherent/UI/URLParse.h>

The ViewEventListener class is the same as the one supplied in the sample framework with the exception that it calls SetFocus in OnViewCreated on its corresponding view.

The ContextEventListener class creates a single view when the view context signals for readiness (the OnContextReady method). The URL of the view has a special scheme - coui://. This special scheme is used by Coherent UI to call a user-supplied I/O handler. When using the scheme without supplying your own handler, a default one is used, which reads files from the filesystem.

The resource handler

We will create a new class, MyFileHandler, which is derived from Coherent::UI::FileHandler. Coherent::UI::FileHandler requires you to implement 2 methods:

virtual void ReadFile(const wchar_t* url, ResourceResponse* response) = 0;
virtual void WriteFile(const wchar_t* url, ResourceData* resource) = 0;

The ResourceResponse and ResourceData interfaces are used for data manipulation and signaling Coherent UI for either success or failure of the I/O operation.

The url parameter of the 2 methods should be parsed to obtain the resource path. Coherent UI supplies a default parser that you can use by including URLParse.h and calling CoherentGetURLParser().Parse(...).

In this sample we only need reading, so the WriteFile method is easy:

virtual void WriteFile(const wchar_t* path, Coherent::UI::ResourceData* resource)
{
resource->SignalFailure();
}

The skeleton of a ReadFile method is illustrated as follows:

virtual void ReadFile(const wchar_t* url, Coherent::UI::ResourceResponse* response)
{
size = get_file_size(url);
if (there_was_some_error)
{
response->SignalFailure();
return;
}
void* buffer = response->GetBuffer(size);
if (!buffer)
{
response->SignalFailure();
return;
}
read_file_into(buffer);
response->SignalSuccess();
}

Here we assume that get_file_size is a method that retrieves the size of a specified resource and sets the flag there_was_some_error to true if there was an error while performing that operation; read_file_into is a method that reads a specified resource into a buffer in memory.

Note
We have synchronous reading in this sample, but in case you're using asynchronous I/O, you have to make sure the signaling of either failure or success is done in the thread that is updating the view context.

UI Initialization

To use the custom file handler, the only thing you have to do is create an instance of the MyFileHandler class and pass it to the CreateViewContext method:

MyFileHandler myFileHandler(L"Resources.mpk");
Coherent::UI::ViewContext* context = CreateViewContext(
&listener,
Coherent::Logging::Debug,
nullptr,
&myFileHandler);

That's it! Now resource requests with the coui:// scheme are redirected to your handler.