Jump to content

Scalable desktop applications


Josh
 Share

Recommended Posts

This is a little bit of code I use to organize complex projects. Very simple, but it helps to break complex applications up into manageable pieces.

Header:

#pragma once
#include "UltraEngine.h"

class UIElement : public Object
{
protected:
    static bool EventCallback(const Event& e, shared_ptr<Object> extra);
    virtual bool ProcessEvent(const Event& e);
    virtual void Listen(const EventID eventid, shared_ptr<Widget> widget = NULL);
};

CPP:

#include "UltraEngine.h"
#include "UIElement.h"

bool UIElement::EventCallback(const Event& e, shared_ptr<Object> extra)
{
    auto elem = extra->As<UIElement>();
    return elem->ProcessEvent(e);
}

bool UIElement::ProcessEvent(const Event& e)
{
    return true;
}

void UIElement::Listen(const EventID eventid, shared_ptr<Widget> widget)
{
    ListenEvent(eventid, widget, UIElement::EventCallback, Self());
}

You then create classes that extend it like so:

#pragma once
#include "UltraEngine.h"
#include "../../Editor/UIElement.h"

using namespace UltraEngine;
using namespace std;

class BillingPanel : public UIElement
{
public:
	shared_ptr<Widget> panel, eulapanel, eulabutton;

	virtual void Initialize(const int x, const int y, const int width, const int height, shared_ptr<Widget> parent);
	virtual bool ProcessEvent(const Event& e);
};

In your initialize() method you can create the main panel and all widgets, and call Listen() for any events you want the ProcessEvent() method to evaluate:

void BillingPanel::Initialize(const int x, const int y, const int width, const int height, shared_ptr<Widget> parent)
{
	panel = CreatePanel(x, y, width, height, parent);
	eulabutton = CreateButton("View EULA", 20, 300 + 26 * 7, 110, 40, panel);
	Listen(EVENT_WIDGETACTION, eulabutton);
}

Evaluating methods is very simple since only the events we specified will ever make it through to the filter:

bool BillingPanel::ProcessEvent(const Event& e)
{
	if (e.source == eulabutton)
	{
		eulapanel->SetHidden(false);
		return false;
	}
	return true;
}

This approach will support very large applications and it makes your life a lot easier. Once your application code gets to be about 1000 lines it's time to think about breaking it up into pieces like this. The event listening system uses STL maps to choose callbacks, so it very efficient. If your ProcessEvent() method returns false, then the event will never show up when WaitEvent() is called in the main loop, it will just get silently skipped since your code already handled it.

  • Like 4

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...