X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbindable.h;h=000234515aeeea4a5b38effe0bf27173251b8896;hb=2663d392c1c60e0ca511bb836010124024da3276;hp=e26840fa3950e977b309beeeeeca96bb3ee33e6e;hpb=b617c5d7b5283ad260a77f01e42e6170cabbc03d;p=libs%2Fgl.git diff --git a/source/bindable.h b/source/bindable.h index e26840fa..00023451 100644 --- a/source/bindable.h +++ b/source/bindable.h @@ -29,7 +29,7 @@ protected: } public: - const T *current() const { return cur_obj; } + static const T *current() { return cur_obj; } }; template @@ -39,7 +39,7 @@ const T *Bindable::cur_obj; /** RAII class for binding things. Binds the thing upon construction and unbinds it upon destruction. If a null pointer is given, unbinds upon construction and -does nothing upon destruction. +does nothing upon destruction. Optionally can restore the previous binding. */ class Bind { @@ -50,22 +50,68 @@ private: }; template - struct Binder: Base + struct Binder1: Base { - const T &obj; + const T *obj; + + Binder1(const T *o): + obj(o) + { + if(obj) + obj->bind(); + else + T::unbind(); + } + + ~Binder1() + { + if(obj) + obj->unbind(); + } + }; - Binder(const T &o): obj(o) { obj.bind(); } - ~Binder() { obj.unbind(); } + template + struct Binder2: Base + { + const T *obj; + const U *old; + + Binder2(const T *o, const U *l): + obj(o), + old(l) + { + if(obj) + obj->bind(); + else + T::unbind(); + } + + ~Binder2() + { + if(old) + old->bind(); + else if(obj) + obj->unbind(); + } }; Base *binder; public: template - Bind(const T &o): binder(new Binder(o)) { } + Bind(const T &o, bool r = false): + binder(r ? create(&o, T::current()) : create(&o)) + { } + + template + Bind(const T *o, bool r = false): + binder(r ? create(o, T::current()) : create(o)) + { } template - Bind(const T *o): binder(o ? new Binder(*o) : 0) { if(!o) T::unbind(); } + Bind(T *o, bool r = false): + binder(r ? create(o, T::current()) : create(o)) + { } private: Bind(const Bind &); @@ -73,6 +119,15 @@ private: public: ~Bind() { delete binder; } + +private: + template + Base *create(const T *o) + { return new Binder1(o); } + + template + Base *create(const T *o, const U *l) + { return new Binder2(o, l); } }; } // namespace GL