]> git.tdb.fi Git - libs/gl.git/blob - source/bindable.h
Update viewer for compatibility with library changes
[libs/gl.git] / source / bindable.h
1 #ifndef MSP_GL_BINDABLE_H_
2 #define MSP_GL_BINDABLE_H_
3
4 namespace Msp {
5 namespace GL {
6
7 template<typename T>
8 class Bindable
9 {
10 protected:
11         static const T *cur_obj;
12
13         Bindable() { }
14
15         static bool set_current(const T *obj)
16         {
17                 if(obj==cur_obj)
18                         return false;
19
20                 cur_obj = obj;
21                 return true;
22         }
23
24 public:
25         static const T *current() { return cur_obj; }
26 };
27
28 template<typename T>
29 const T *Bindable<T>::cur_obj;
30
31
32 /**
33 RAII class for binding things.  Binds the thing upon construction and unbinds
34 it upon destruction.  If a null pointer is given, unbinds upon construction and
35 does nothing upon destruction.  Optionally can restore the previous binding.
36 */
37 class Bind
38 {
39 private:
40         struct Base
41         {
42                 virtual ~Base() { }
43         };
44
45         template<typename T>
46         struct Binder1: Base
47         {
48                 const T *obj;
49
50                 Binder1(const T *o):
51                         obj(o)
52                 {
53                         if(obj)
54                                 obj->bind();
55                         else
56                                 T::unbind();
57                 }
58
59                 ~Binder1()
60                 {
61                         if(obj)
62                                 obj->unbind();
63                 }
64         };
65
66         template<typename T, typename U>
67         struct Binder2: Base
68         {
69                 const T *obj;
70                 const U *old;
71
72                 Binder2(const T *o, const U *l):
73                         obj(o),
74                         old(l)
75                 {
76                         if(obj)
77                                 obj->bind();
78                         else
79                                 T::unbind();
80                 }
81
82                 ~Binder2()
83                 {
84                         if(old)
85                                 old->bind();
86                         else if(obj)
87                                 obj->unbind();
88                 }
89         };
90
91         Base *binder;
92
93 public:
94         template<typename T>
95         Bind(const T &o, bool r = false):
96                 binder(r ? create(&o, T::current()) : create(&o))
97         { }
98
99         template<typename T>
100         Bind(const T *o, bool r = false):
101                 binder(r ? create(o, T::current()) : create(o))
102         { }
103
104         template<typename T>
105         Bind(T *o, bool r = false):
106                 binder(r ? create(o, T::current()) : create(o))
107         { }
108
109 private:
110         Bind(const Bind &);
111         Bind &operator=(const Bind &);
112
113 public:
114         ~Bind() { delete binder; }
115
116 private:
117         template<typename T>
118         Base *create(const T *o)
119         { return new Binder1<T>(o); }
120
121         template<typename T, typename U>
122         Base *create(const T *o, const U *l)
123         { return new Binder2<T, U>(o, l); }
124 };
125
126 } // namespace GL
127 } // namespace Msp
128
129 #endif