]> git.tdb.fi Git - libs/gl.git/blobdiff - source/bindable.h
Drop Id tags and copyright notices from files
[libs/gl.git] / source / bindable.h
index cd012fbbcef3d50b984a6dafbace86f49ce7f433..8823de5c9773209a1642f5b763887e65ca7ea5d6 100644 (file)
@@ -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<typename T>
@@ -39,7 +32,7 @@ const T *Bindable<T>::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<typename T>
-       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<typename T, typename U>
+       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<typename T>
-       Bind(const T &o): binder(new Binder<T>(o)) { }
+       Bind(const T &o, bool r = false):
+               binder(r ? create(&o, T::current()) : create(&o))
+       { }
 
        template<typename T>
-       Bind(const T *o): binder(o ? new Binder<T>(*o) : 0) { if(!o) T::unbind(); }
+       Bind(const T *o, bool r = false):
+               binder(r ? create(o, T::current()) : create(o))
+       { }
+
+       template<typename T>
+       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<typename T>
+       Base *create(const T *o)
+       { return new Binder1<T>(o); }
+
+       template<typename T, typename U>
+       Base *create(const T *o, const U *l)
+       { return new Binder2<T, U>(o, l); }
 };
 
 } // namespace GL