]> git.tdb.fi Git - libs/gl.git/blobdiff - source/bindable.h
Add object-oriented interfaces for the various tests and blending
[libs/gl.git] / source / bindable.h
diff --git a/source/bindable.h b/source/bindable.h
new file mode 100644 (file)
index 0000000..cd012fb
--- /dev/null
@@ -0,0 +1,81 @@
+/* $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_
+
+namespace Msp {
+namespace GL {
+
+template<typename T>
+class Bindable
+{
+protected:
+       static const T *cur_obj;
+
+       Bindable() { }
+
+       static bool set_current(const T *obj)
+       {
+               if(obj==cur_obj)
+                       return false;
+
+               cur_obj=obj;
+               return true;
+       }
+
+public:
+       const T *current() const { return cur_obj; }
+};
+
+template<typename T>
+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.
+*/
+class Bind
+{
+private:
+       struct Base
+       {
+               virtual ~Base() { }
+       };
+
+       template<typename T>
+       struct Binder: Base
+       {
+               const T &obj;
+
+               Binder(const T &o): obj(o) { obj.bind(); }
+               ~Binder() { obj.unbind(); }
+       };
+
+       Base *binder;
+
+public:
+       template<typename T>
+       Bind(const T &o): binder(new Binder<T>(o)) { }
+
+       template<typename T>
+       Bind(const T *o): binder(o ? new Binder<T>(*o) : 0) { if(!o) T::unbind(); }
+
+private:
+       Bind(const Bind &);
+       Bind &operator=(const Bind &);
+
+public:
+       ~Bind() { delete binder; }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif