Jump to content
  • Advertisement
Sign in to follow this  
gretty

Review Component Based Architecture API

This topic is 972 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have written a simple Component Based Architecture API in C++. It verges on Event-Drive Architecture.

The objective is simply to create a Component Based Architecture API that follows C++11 practices (with some C++14) and doesn't use any bad C++ practices or no-nos.

The API can be found including a working example. Its very simple and easy to comprehend in my opinion. The API only has 5 main classes.

I'm hoping people could be kind enough to review the code. I am looking for criticism and advice regarding:

  •  Any bad c++ practices and no-no's
  •  The API relies on void* as a way to pass generic structures. Is there a better alternative/pattern?
  •  How to ensure classes that inherit from IApp can only be instantiated through IApp::create<type>() and not directly through the constructor
  •  Is it thread-safe? What ways could this be optimised?
  •  I recently ran into the 'static initialisation order fiasco', are there any other problems I have implemented that I don't know about?

*Note: Some code is cross-platform but the main objective of the API isn't to be cross-platform. The Win32 example components are (obviously) quite coupled to OS. The objective of the API isn't to be released or be an alternative to existing API's just an exercise to use C++, improve coding skills and fulfil a code boner I've always had for CBA.

 

The main structure is like so:

// Event Delegate //
#pragma message("TODO: Similar to WinForms passing event parameters as a void pointer. Any ideas of a better solution that maintains polymorphism?")
typedef std::weak_ptr<void> EventArgs;
const EventArgs NULL_ARGS;

class EventDelegate
{
public:
	typedef std::function<Status(EventArgs)> EDelegate;

	EventDelegate(EDelegate delegate, GUID gUidContext);

	bool operator== (const EventDelegate& other) const;
	bool operator!= (const EventDelegate& other) const;

	Status operator()(const EventArgs& evtArgs) const;

private:
	GUID gUidContext;
	EDelegate delegate;
};


// Component //
class Component
{
public:
	GUID gUid;

	template<typename T>
	static std::unique_ptr<T> create(std::weak_ptr<IApp> app)
	{
		return std::unique_ptr<T>(new T(app));
	}

	virtual ~Component();

	bool operator< (const Component& other) const;

	template<typename T>
	bool addComponent()
	{
		std::unique_ptr<T> cmp = Component::create<T>(app);
		auto res = components.emplace(cmp->gUid, std::move(cmp));

		return res.second;
	}

protected:
	std::weak_ptr<IApp> app;
	std::unordered_map<GUID, std::unique_ptr<Component>> components;

	Component(std::weak_ptr<IApp> app);
	Component();

	virtual Status init(const EventArgs& evtArgs) = 0;
	virtual Status terminate(const EventArgs& evtArgs) = 0;
	virtual Status registerEvents() = 0;
};


// IApp //
class IApp : protected Component
{
public:

	static Status S_APP_EXIT;
	static Status S_UNREGISTERED_EVT;
	static const int EVT_MOUSE = 50000;
	static const int EVT_KEY = 50001;
	static const int EVT_INIT = 50002;
	static const int EVT_TERMINATE = 50003;
	static const int EVT_EXIT = 50004;

	template<typename T>
	static std::shared_ptr<T> create()
	{
		std::shared_ptr<T> app(new T);
		app->app = app;
		return app;
	}

	Status exec();
	Status registerForEvent(const int& eventId, EventDelegate delegate);
	Status unregisterForEvent(const int& eventId, EventDelegate delegate);

protected:
	static std::unordered_multimap<int, EventDelegate> evtRegistry;

	IApp();
	virtual ~IApp();

	virtual Status update() = 0;
	static Status eventHandler(const int& evtId, const EventArgs& evtArgs);

private:

};
Edited by gretty

Share this post


Link to post
Share on other sites
Advertisement
  •  The API relies on void* as a way to pass generic structures. Is there a better alternative/pattern?

Typedef it to something readable if it going to be used as an API

  •  How to ensure classes that inherit from IApp can only be instantiated through IApp::create<type>() and not directly through the constructor

Make the constructor private

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!