Skip navigation

I posted the following on the Card Kingdom development blog.

Particle Editor and UI Communication

One of the newest features I’ve been working on was the in-engine particle editor. This was a great test for the communication from the UI to the engine, and back again. In developing, this was the “worst case” scenario for communication as there are many parameters that can be set for the particles. Designing a system that could handle this case, as well as simpler ones was vital in making the UI flexible and extensible.

The solution I came up with an event listener and caller system. Using our internal messaging system, components register themselves as event listeners to one or multiple events and can retrieve the event caller for the UI.

The following is the definition for the interfaces of the event listener and caller:

typedef std::vector<const std::string> UIEventArguments;

class IUIEventListener {
public:
	IUIEventListener() {}
	virtual ~IUIEventListener() {}

	virtual void onUIEvent(
		const std::string& e,
		const UIEventArguments& arguments
	) = 0;
};

class IUIEventCaller {
public:
	IUIEventCaller() {}
	virtual ~IUIEventCaller() {}

	virtual void callUIEvent(
		const std::string& e,
		const UIEventArguments& arguments
	) = 0;
};

The listener and caller have the same signature, but are used in different ways. The listener’s onUIEvent() receives “events” from the UI. These events are actually JavaScript functions called on an object created by Awesomium. The function name is the name of the event and the arguments are the ones passed to the function, in string form for ease of use. The caller’s callUIEvent() sends an “event” into the UI. These are actually JavaScript functions inside Awesomium were the event name is the function name and the arguments are the ones passed to the function. With this setup, any UI-to-engine or engine-to-UI communication is very simple, powerful and elegant.

Here is a video of what I’m talking about.

Dynamic Resource Loading

One of the side effects of how we handle resources in our engine exposes a way to reload content while it’s running. All of our resources are “instanced” (I talked about this a bit in a previous post). By creating an instance of a resource, the resource itself can change without having to do anything with the instance. A new UI element was added to list out all of the content currently loaded, as well as the ability to manually reload specific resources.

Having the ability to dynamically reload content makes testing and developing new assets incredibly easy as the application does not need to be restarted every time for minor textures, and even shader updates.