quick backup:
[demo] / src / state_manager.cc
diff --git a/src/state_manager.cc b/src/state_manager.cc
new file mode 100644 (file)
index 0000000..a375cff
--- /dev/null
@@ -0,0 +1,106 @@
+#include <stdio.h>
+#include <map>
+#include <string>
+
+#include <gmath/gmath.h>
+
+#include "state_manager.h"
+
+StateManager state_manager;
+
+State *StateManager::get_state(const char *name)
+{
+       std::map<std::string, int>::iterator it;
+       it = statemap.find(name);
+       return it == statemap.end() ? 0 : &states[it->second];
+}
+
+int StateManager::add_state_element(const char *name, int num_floats)
+{
+       State *st = get_state(name);
+       if(st) {
+               if(st->num != num_floats) {
+                       fprintf(stderr, "Uniform %s, type mismatch!\n", name);
+                       return -1;
+               }
+
+               return st - &states[0];
+       }
+
+       State state;
+       state.num = num_floats;
+
+       state.name = new char[strlen(name) + 1];
+       strcpy(state.name, name);
+
+       int sz = sizeof *state.data * num_floats;
+       state.data = new float[sz];
+       memset(state.data, 0, sz);
+
+       int idx = (int)states.size();
+       states.push_back(state);
+
+       statemap[name] = idx;
+
+       printf("State manager: added state %s with %d float data.\n", name, num_floats);
+       return idx;
+}
+
+void StateManager::set_state(const char *name, float value)
+{
+       set_state(name, Vec4(value, 0, 0, 1));
+}
+
+void StateManager::set_state(const char *name, const Vec3 &vec)
+{
+       set_state(name, Vec4(vec.x, vec.y, vec.z, 1));
+}
+
+void StateManager::set_state(const char *name, const Vec4 &vec)
+{
+       State *state = get_state(name);
+       if(!state)
+               return;
+
+       switch(state->num) {
+       case 4:
+               state->data[3] = vec.w;
+       case 3:
+               state->data[2] = vec.z;
+       case 2:
+               state->data[1] = vec.y;
+       case 1:
+               state->data[0] = vec.x;
+       default:
+               break;
+       }
+}
+
+void StateManager::set_state(const char *name, const Mat4 &mat)
+{
+       State *state = get_state(name);
+
+       if(!state)
+               return;
+
+       if(state->num != 16) {
+               fprintf(stderr, "State manager: state %s can only be a 4x4 matrix.\n", name);
+               return;
+       }
+
+       for(int j=0; j<4; j++) {
+               for(int i=0; i<4; i++) {
+                       state->data[4 * i + j] = mat.m[i][j];
+               }
+       }
+}
+
+const State *StateManager::get_state(const char *name) const
+{
+       return ((StateManager *)this)->get_state(name);
+}
+
+const State *StateManager::get_state(int idx) const
+{
+       return &states[idx];
+}
\ No newline at end of file