metascene initial implementation
[laserbrain_demo] / src / metascene.cc
1 #include "metascene.h"
2 #include "scene.h"
3 #include "datamap.h"
4 #include "treestore.h"
5
6 #ifdef WIN32
7 #include <malloc.h>
8 #else
9 #include <alloca.h>
10 #endif
11
12 static bool proc_node(Scene *scn, struct ts_node *node);
13 static struct ts_attr *attr_inscope(struct ts_node *node, const char *name);
14
15 bool load_scene(Scene *scn, const char *fname)
16 {
17         struct ts_node *root = ts_load(fname);
18         if(!root || strcmp(root->name, "scene") != 0) {
19                 ts_free_tree(root);
20                 fprintf(stderr, "failed to load scene metadata: %s\n", fname);
21                 return false;
22         }
23
24         bool res = proc_node(scn, root);
25         ts_free_tree(root);
26         return res;
27 }
28
29 static bool proc_node(Scene *scn, struct ts_node *node)
30 {
31         struct ts_node *c = node->child_list;
32         while(c) {
33                 if(!proc_node(scn, c)) {
34                         return false;
35                 }
36                 c = c->next;
37         }
38
39         // do this last to allow other contents of the node to do their thing
40         if(strcmp(node->name, "scenefile") == 0) {
41                 const char *fname = ts_get_attr_str(node, "file");
42                 if(fname) {
43                         struct ts_attr *adpath = attr_inscope(node, "datapath");
44                         if(adpath && adpath->val.type == TS_STRING) {
45                                 printf("adding data path: %s\n", adpath->val.str);
46                                 datamap_set_path(adpath->val.str);
47                         }
48
49                         int namesz = datamap_lookup(fname, 0, 0);
50                         char *namebuf = (char*)alloca(namesz + 1);
51                         if(datamap_lookup(fname, namebuf, namesz + 1)) {
52                                 fname = namebuf;
53                         }
54
55                         if(!(scn->load(fname, SCNLOAD_FLIPTEX))) {
56                                 return false;
57                         }
58                 }
59                 datamap_reset();
60
61         } else if(strcmp(node->name, "remap") == 0) {
62                 const char *match = ts_get_attr_str(node, "match");
63                 const char *replace = ts_get_attr_str(node, "replace");
64                 if(match && replace) {
65                         datamap_map(match, replace);
66                 }
67         }
68
69         return true;
70 }
71
72 static struct ts_attr *attr_inscope(struct ts_node *node, const char *name)
73 {
74         struct ts_attr *attr = 0;
75
76         while(node && !(attr = ts_get_attr(node, name))) {
77                 node = node->parent;
78         }
79         return attr;
80 }