900d860c8465bf3e764f1251f6ed15fcb4a67ebd
[laserbrain_demo] / src / exman.cc
1 #include <algorithm>
2 #include "exman.h"
3 #include "exhibit.h"
4 #include "blob_exhibit.h"
5 #include "treestore.h"
6
7 static Exhibit *create_exhibit(const char *type);
8
9 ExhibitManager::ExhibitManager()
10 {
11 }
12
13 ExhibitManager::~ExhibitManager()
14 {
15         clear();
16 }
17
18 void ExhibitManager::clear()
19 {
20         int num = (int)items.size();
21         for(int i=0; i<num; i++) {
22                 delete items[i];
23         }
24         items.clear();
25 }
26
27 void ExhibitManager::add(Exhibit *ex)
28 {
29         std::vector<Exhibit*>::iterator it = std::find(items.begin(), items.end(), ex);
30         if(it == items.end()) {
31                 items.push_back(ex);
32         }
33 }
34
35 bool ExhibitManager::remove(Exhibit *ex)
36 {
37         std::vector<Exhibit*>::iterator it = std::find(items.begin(), items.end(), ex);
38         if(it != items.end()) {
39                 items.erase(it);
40                 return true;
41         }
42         return false;
43 }
44
45 bool ExhibitManager::load(MetaScene *mscn, const char *fname)
46 {
47         struct ts_node *root = ts_load(fname);
48         if(!root || strcmp(root->name, "exhibits") != 0) {
49                 ts_free_tree(root);
50                 error_log("failed to load exhibits\n");
51                 return false;
52         }
53
54         struct ts_node *iter = root->child_list;
55         while(iter) {
56                 struct ts_node *node = iter;
57                 iter = iter->next;
58
59                 if(strcmp(node->name, "item") == 0) {
60                         SceneNode *snode;
61
62                         const char *amatch = ts_get_attr_str(node, "match_node");
63                         if(!amatch || !(snode = mscn->match_node(amatch))) {
64                                 error_log("ExhibitManager::load: regexp \"%s\" didn't match any nodes\n",
65                                                 amatch ? amatch : "");
66                                 continue;
67                         }
68
69                         Exhibit *ex;
70                         const char *atype = ts_get_attr_str(node, "type");
71                         if(!atype || !(ex = create_exhibit(atype))) {
72                                 error_log("failed to create exhibit of type: %s\n", atype);
73                                 continue;
74                         }
75
76                         ex->set_node(snode);
77                         items.push_back(ex);
78                 }
79         }
80
81         ts_free_tree(root);
82         return true;
83 }
84
85 ExSelection ExhibitManager::select(const Ray &ray) const
86 {
87         ExSelection sel;
88         if(!items.empty()) {
89                 sel.ex = items[0];
90                 sel.selray = ray;
91                 sel.validmask = EXSEL_RAY;
92         }
93         return sel;     // TODO
94 }
95
96 ExSelection ExhibitManager::select(const Sphere &sph) const
97 {
98         ExSelection sel;
99         if(!items.empty()) {
100                 sel.ex = items[0];
101                 sel.selsphere = sph;
102                 sel.validmask = EXSEL_SPHERE;
103         }
104         return sel;     // TODO
105 }
106
107 void ExhibitManager::update(float dt)
108 {
109         int num = items.size();
110         for(int i=0; i<num; i++) {
111                 // if the exhibit is not part of a scene graph, first call its
112                 // node's update function (otherwise it'll have been called recursively earlier)
113                 if(!items[i]->node->get_parent()) {
114                         items[i]->node->update(dt);
115                 }
116                 items[i]->update(dt);
117         }
118 }
119
120 void ExhibitManager::draw() const
121 {
122         int num = items.size();
123         for(int i=0; i<num; i++) {
124                 items[i]->pre_draw();
125                 items[i]->draw();
126                 items[i]->post_draw();
127         }
128 }
129
130 static Exhibit *create_exhibit(const char *type)
131 {
132         if(strcmp(type, "static") == 0) {
133                 debug_log("creating static exhibit\n");
134                 return new Exhibit;
135         } else if(strcmp(type, "blobs") == 0) {
136                 debug_log("creating blobs exhibit\n");
137                 return new BlobExhibit;
138         }
139         error_log("unknown exhibit type: %s\n", type);
140         return 0;
141 }