+/* $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