Skip to content

Instantly share code, notes, and snippets.

@maxattack
Last active August 29, 2015 13:57
Show Gist options
  • Save maxattack/9588955 to your computer and use it in GitHub Desktop.
Save maxattack/9588955 to your computer and use it in GitHub Desktop.
C++11 Me Am Go Too Far!
#pragma once
#include "GameBase.h"
// Event Book Pool - Apply this to any pool that implements the alloc/release contract
// to have it automatically call enable/disable methods just before the first slot is allocated
// and just after the last slot is released.
template<typename T>
class EventHookPool : public T {
public:
template<typename... Args>
typename T::InstanceType* alloc(Args&&... args) {
if (this->empty()) { T::enable(); }
return T::alloc(std::forward<Args>(args)...);
}
void release(typename T::InstanceType* p) {
T::release(p);
if (this->empty()) { T::disable(); }
}
};
// HookMixinBase - Add empty enable/disable methods so that other mixins can call them without
// producing a compiler error.
template<typename T>
class HookMixinBase : public T {
public:
void enable() {}
void disable() {}
};
// Automatically subscribe to the drawSpline event when active
template<typename T>
class DrawSplineEventMixin : public T {
EventListener<SplinePlotter*> drawSplineListener;
void draw(SplinePlotter *splines) { for (auto p=this->list(); p.next();) { p->draw(splines); } }
public:
DrawSplineEventMixin() :
drawSplineListener(Action<SplinePlotter*>::callMethod<DrawSplineEventMixin<T>, &DrawSplineEventMixin<T>::draw>(this)) {}
void enable() { T::enable(); gEvents.onDrawSplines.bind(&drawSplineListener); }
void disable() { T::disable(); drawSplineListener.unbind(); }
};
// Automatically subscript to the didTick event when active
template<typename T>
class DidTickEventMixin : public T {
EventListener<> didTickListener;
void didTick() { for (auto p=this->list(); p.next();) { p->didTick(); } }
public:
DidTickEventMixin() :
didTickListener(Action<>::callMethod<DidTickEventMixin<T>, &DidTickEventMixin<T>::didTick>(this)) {}
void enable() { T::enable(); gEvents.didTick.bind(&didTickListener); }
void disable() { T::disable(); didTickListener.unbind(); }
};
// Automatically subscribe to the willTIck event with active
template<typename T>
class WillTickEventMixin : public T {
EventListener<> willTickListener;
void willTick() { for (auto p=this->list(); p.next();) { p->willTick(); } }
public:
WillTickEventMixin() :
willTickListener(Action<>::callMethod<WillTickEventMixin<T>, &WillTickEventMixin<T>::willTick>(this)) {}
void enable() { T::enable(); gEvents.willTick.bind(&willTickListener); }
void disable() { T::disable(); willTickListener.unbind(); }
};
@maxattack
Copy link
Author

In practice, it looks like this:

    EventHookPool
        <DidTickEventMixin
        <DrawSplineEventMixin
        <HookMixinBase
        <DynamicPool
        <Tentacle
    >>>>> tentacles;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment