src/behavior.c

changeset 286
26a41832c81d
parent 279
97a1a7fb4f1a
equal deleted inserted replaced
285:dc13730ff1ec 286:26a41832c81d
29 #include "ascension/context.h" 29 #include "ascension/context.h"
30 #include "ascension/scene.h" 30 #include "ascension/scene.h"
31 #include "ascension/util.h" 31 #include "ascension/util.h"
32 #include "ascension/error.h" 32 #include "ascension/error.h"
33 33
34 #include <cx/kv_list.h> 34 #include <cx/linked_list.h>
35 #include <cx/tree.h> 35 #include <cx/tree.h>
36 36
37 #include <assert.h> 37 #include <assert.h>
38 38
39 static void asc_behavior_destroy(void *b) { 39 static void asc_behavior_destroy(void *b) {
43 if (behavior->destroy_func) { 43 if (behavior->destroy_func) {
44 behavior->destroy_func(behavior); 44 behavior->destroy_func(behavior);
45 } 45 }
46 } 46 }
47 47
48 static CxMap *asc_behavior_new_map(void) { 48 static CxList *asc_behavior_new_list(void) {
49 CxMap *map = cxKvListCreateAsMapSimple(sizeof(AscBehavior)); 49 CxList *list = cxLinkedListCreateSimple(sizeof(AscBehavior));
50 cxDefineDestructor(map, asc_behavior_destroy); 50 cxDefineDestructor(list, asc_behavior_destroy);
51 return map; 51 return list;
52 } 52 }
53 53
54 AscBehavior *asc_behavior_add_(AscSceneNode *node, struct asc_behavior_create_args args) { 54 AscBehavior *asc_behavior_add_(AscSceneNode *node, struct asc_behavior_create_args args) {
55 if (node->behaviors == NULL) { 55 if (node->behaviors == NULL) {
56 node->behaviors = asc_behavior_new_map(); 56 node->behaviors = asc_behavior_new_list();
57 } 57 }
58 cxmutstr name = args.name == NULL 58 AscBehavior *behavior = cxListEmplace(node->behaviors);
59 ? asc_util_gen_name("behavior")
60 : cx_mutstr(strdup(args.name));
61 AscBehavior *behavior = cxMapEmplace(node->behaviors, name);
62 assert(behavior != NULL); 59 assert(behavior != NULL);
63 behavior->enabled = !args.start_disabled; 60 behavior->enabled = !args.start_disabled;
64 behavior->always_enabled = args.always_enabled; 61 behavior->always_enabled = args.always_enabled;
65 behavior->killed = false; 62 behavior->killed = false;
66 behavior->reactivated = false; 63 behavior->reactivated = false;
69 behavior->destroy_func = args.destroy_func; 66 behavior->destroy_func = args.destroy_func;
70 behavior->data = args.data; 67 behavior->data = args.data;
71 behavior->interval = args.interval; 68 behavior->interval = args.interval;
72 behavior->last_execution = 0; 69 behavior->last_execution = 0;
73 behavior->disable_while_hidden = args.disable_while_hidden; 70 behavior->disable_while_hidden = args.disable_while_hidden;
74 behavior->name = name; 71 behavior->name = args.name == NULL
72 ? asc_util_gen_name("behavior")
73 : cx_mutstr(strdup(args.name));
75 asc_dprintf("Create behavior: %"CX_PRIstr, CX_SFMT(behavior->name)); 74 asc_dprintf("Create behavior: %"CX_PRIstr, CX_SFMT(behavior->name));
76 return behavior; 75 return behavior;
77 } 76 }
78 77
79 void asc_behavior_remove(AscBehavior *behavior) { 78 void asc_behavior_remove(AscBehavior *behavior) {
90 } 89 }
91 // the behavior is not scheduled for execution 90 // the behavior is not scheduled for execution
92 if (behavior->last_execution + behavior->interval > asc_context.total_nanos) { 91 if (behavior->last_execution + behavior->interval > asc_context.total_nanos) {
93 return; 92 return;
94 } 93 }
95 // the behavior is disable while the node is hidden 94 // the behavior is disabled while the node is hidden
96 if (!behavior->always_enabled && behavior->disable_while_hidden && asc_scene_node_is_hidden(behavior->node)) { 95 if (!behavior->always_enabled && behavior->disable_while_hidden && asc_scene_node_is_hidden(behavior->node)) {
97 behavior->reactivated = true; 96 behavior->reactivated = true;
98 return; 97 return;
99 } 98 }
100 99
101 behavior->func(behavior); 100 behavior->func(behavior);
102 behavior->reactivated = false; 101 behavior->reactivated = false;
103 behavior->last_execution = asc_context.total_nanos; 102 behavior->last_execution = asc_context.total_nanos;
104 } 103 }
105 104
106 cxstring asc_behavior_get_name(const AscBehavior *behavior) {
107 assert(behavior != NULL);
108 return cx_strcast(behavior->name);
109 }
110
111 AscBehavior *asc_behavior_find_(const AscSceneNode *node, cxstring name) {
112 return cxMapGet(node->behaviors, name);
113 }
114
115 void asc_behavior_enable_all(AscSceneNode *node) { 105 void asc_behavior_enable_all(AscSceneNode *node) {
116 CxMapIterator iter = cxMapIteratorValues(node->behaviors); 106 CxIterator iter = cxListIterator(node->behaviors);
117 cx_foreach(AscBehavior*, behavior, iter) { 107 cx_foreach(AscBehavior*, behavior, iter) {
118 asc_behavior_enable(behavior); 108 asc_behavior_enable(behavior);
119 } 109 }
120 } 110 }
121 111
122 void asc_behavior_disable_all(AscSceneNode *node) { 112 void asc_behavior_disable_all(AscSceneNode *node) {
123 CxMapIterator iter = cxMapIteratorValues(node->behaviors); 113 CxIterator iter = cxListIterator(node->behaviors);
124 cx_foreach(AscBehavior*, behavior, iter) { 114 cx_foreach(AscBehavior*, behavior, iter) {
125 asc_behavior_disable(behavior); 115 asc_behavior_disable(behavior);
126 } 116 }
127 } 117 }
128 118
129 void asc_behavior_disable_all_while_hidden(AscSceneNode *node) { 119 void asc_behavior_disable_all_while_hidden(AscSceneNode *node) {
130 CxMapIterator iter = cxMapIteratorValues(node->behaviors); 120 CxIterator iter = cxListIterator(node->behaviors);
131 cx_foreach(AscBehavior*, behavior, iter) { 121 cx_foreach(AscBehavior*, behavior, iter) {
132 asc_behavior_disable_while_hidden(behavior); 122 asc_behavior_disable_while_hidden(behavior);
133 } 123 }
134 } 124 }
135 125
136 void asc_behavior_enable_all_while_hidden(AscSceneNode *node) { 126 void asc_behavior_enable_all_while_hidden(AscSceneNode *node) {
137 CxMapIterator iter = cxMapIteratorValues(node->behaviors); 127 CxIterator iter = cxListIterator(node->behaviors);
138 cx_foreach(AscBehavior*, behavior, iter) { 128 cx_foreach(AscBehavior*, behavior, iter) {
139 asc_behavior_enable_while_hidden(behavior); 129 asc_behavior_enable_while_hidden(behavior);
140 } 130 }
141 } 131 }

mercurial