One Little Thing
A couple weeks ago I replaced the Object::SetHook() function with an Object::AddHook() function. The difference is subtle but significant. SetHook() supported a single hook function but AddHook() supports multiple hook functions for each hook ID, that will be called in sequence.
Syntax
- AddHook(const int& hookid, void* hook)
Example
#include "App.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete world; delete window; } void Hook1(Entity* entity) { System::Print("Hook 1"); } void Hook2(Entity* entity) { System::Print("Hook 2"); } void Hook3(Entity* entity) { System::Print("Hook 3"); } bool App::Start() { window = Window::Create(); context = Context::Create(window); world = World::Create(); camera = Camera::Create(); DirectionalLight::Create()->SetRotation(35,45,0); //Create a model model = Model::Box(); model->SetPosition(0,0,3); //Add some hooks model->AddHook(Entity::UpdateMatrixHook,Hook1); model->AddHook(Entity::DrawHook,Hook2); model->AddHook(Entity::DrawEachHook,Hook3); //Remove one hook model->RemoveHook(Entity::DrawEachHook,Hook3); return true; } bool App::Continue() { if (window->Closed() || window->KeyDown(Key::Escape)) return false; //Make the model spin model->Turn(0,Time::GetSpeed()*1.0,0); Time::Update(); world->Update(); world->Render(); context->Sync(); return true; }
Inside the engine, this just uses a multimap, which has some very complicated syntax that I could not type from memory:
//Call hooks std::pair <std::multimap<int,void*>::iterator, std::multimap<int,void*>::iterator> ret; ret = (*entity)->hooks.equal_range(Entity::UpdateWorldHook); for (std::multimap<int,void*>::iterator it=ret.first; it!=ret.second; ++it) { void (*hook)(Entity*) = (void (*)(Entity*))(it->second); hook(*entity); }
So What's the Big Deal?
It's important for the API to be future-compatible. It's okay for new commands to be added, but once the first release is out I really want the API to always act as described in the documentation. We wouldn't be bothering to produce a printed manual otherwise.
This design was adopted so that in the future it can be used for plugins. A plugin would add its own hooks onto objects. If we used SetHook(), it implies there is only a single hook allowed. We want the user to be able to add their own hooks without overriding any plugins they may be using. This also allows multiple plugins to add and remove their own hooks without interfering with one another.
It's too early to worry much about a plugin system. The best thing to do right now is build a really focused tool that fulfills the function it's designed for. However, by anticipating plans for future expansion we can design things now so that we don't have to go back and change them later.
- 1
40 Comments
Recommended Comments