static const T *cur_obj;
Bindable() { }
+ ~Bindable() { if(cur_obj==this) T::unbind(); }
static bool set_current(const T *obj)
{
template<typename T>
class BindableWithDefault: protected Bindable<T>
{
+ friend class Bindable<T>;
+
protected:
BindableWithDefault() { }
+ ~BindableWithDefault() { if(this==&default_object()) Bindable<T>::set_current(0); }
public:
static const T *current()
static void unbind()
{
- default_object().bind();
+ if(Bindable<T>::cur_obj)
+ default_object().bind();
}
static const T &default_object()
class Bind
{
private:
- typedef void CleanupFunc();
+ typedef void CleanupFunc(int);
+ int slot;
CleanupFunc *cleanup;
public:
template<typename T>
Bind(const T &o) { init(&o); }
+ template<typename T, typename S>
+ Bind(T *o, S s) { init(o, s); }
+
+ template<typename T, typename S>
+ Bind(const T *o, S s) { init(o, s); }
+
+ template<typename T, typename S>
+ Bind(const T &o, S s) { init(&o, s); }
+
private:
template<typename T>
void init(const T *o)
{
- cleanup = (o ? &unbind<T> : 0);
+ cleanup = (o ? static_cast<CleanupFunc *>(&unbind<T>) : 0);
+ slot = 0;
if(o)
o->bind();
else
T::unbind();
}
+ template<typename T, typename S>
+ void init(const T *o, S s)
+ {
+ cleanup = (o ? static_cast<CleanupFunc *>(&unbind_from<T, S>) : 0);
+ slot = s;
+ if(o)
+ o->bind_to(s);
+ else
+ T::unbind_from(s);
+ }
+
public:
~Bind()
- { if(cleanup) cleanup(); }
+ { if(cleanup) cleanup(slot); }
private:
template<typename T>
- static void unbind()
+ static void unbind(int)
{ T::unbind(); }
+
+ template<typename T, typename S>
+ static void unbind_from(int s)
+ { T::unbind_from(static_cast<S>(s)); }
};
class BindRestore
{
private:
- typedef void CleanupFunc(const void *);
+ typedef void CleanupFunc(const void *, int);
const void *old;
+ int slot;
CleanupFunc *cleanup;
public:
template<typename T>
BindRestore(const T &o) { init(&o); }
+ template<typename T, typename S>
+ BindRestore(T *o, S s) { init(o, s); }
+
+ template<typename T, typename S>
+ BindRestore(const T *o, S s) { init(o, s); }
+
+ template<typename T, typename S>
+ BindRestore(const T &o, S s) { init(&o, s); }
+
private:
template<typename T>
void init(T *o)
{
old = T::current();
- cleanup = (o!=old ? &restore<T> : 0);
+ slot = 0;
+ cleanup = (o!=old ? static_cast<CleanupFunc *>(&restore<T>) : 0);
if(o)
o->bind();
else if(old)
T::unbind();
}
+ template<typename T, typename S>
+ void init(T *o, S s)
+ {
+ old = T::current(s);
+ slot = s;
+ cleanup = (o!=old ? static_cast<CleanupFunc *>(&restore_to<T, S>) : 0);
+ if(o)
+ o->bind_to(s);
+ else if(old)
+ T::unbind_from(s);
+ }
+
public:
~BindRestore()
- { if(cleanup) cleanup(old); }
+ { if(cleanup) cleanup(old, slot); }
private:
template<typename T>
- static void restore(const void *o)
+ static void restore(const void *o, int)
{
if(o)
reinterpret_cast<const T *>(o)->bind();
else
T::unbind();
}
+
+ template<typename T, typename S>
+ static void restore_to(const void *o, int si)
+ {
+ S s = static_cast<S>(si);
+ if(o)
+ reinterpret_cast<const T *>(o)->bind_to(s);
+ else
+ T::unbind_from(s);
+ }
};
} // namespace GL