X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fbindable.h;h=8823de5c9773209a1642f5b763887e65ca7ea5d6;hp=cd012fbbcef3d50b984a6dafbace86f49ce7f433;hb=f14435e58bfa0fa697a06ba9a454bb30cd37d9d8;hpb=f17794d55923d4fb4f63e9d082d8d84a735a04e8 diff --git a/source/bindable.h b/source/bindable.h index cd012fbb..8823de5c 100644 --- a/source/bindable.h +++ b/source/bindable.h @@ -1,10 +1,3 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2010 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - #ifndef MSP_GL_BINDABLE_H_ #define MSP_GL_BINDABLE_H_ @@ -24,12 +17,12 @@ protected: if(obj==cur_obj) return false; - cur_obj=obj; + cur_obj = obj; return true; } public: - const T *current() const { return cur_obj; } + static const T *current() { return cur_obj; } }; template @@ -39,7 +32,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 +43,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): binder(o ? new Binder(*o) : 0) { if(!o) T::unbind(); } + Bind(const T *o, bool r = false): + binder(r ? create(o, T::current()) : create(o)) + { } + + template + Bind(T *o, bool r = false): + binder(r ? create(o, T::current()) : create(o)) + { } private: Bind(const Bind &); @@ -73,6 +112,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