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/array_list.h> |
34 #include <cx/hash_map.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 CxList *asc_behavior_new_list(void) { |
48 static CxMap *asc_behavior_new_map(void) { |
49 CxList *list = cxArrayListCreate(NULL, NULL, sizeof(AscBehavior), 4); |
49 CxMap *map = cxHashMapCreateSimple(sizeof(AscBehavior)); |
50 cxDefineDestructor(list, asc_behavior_destroy); |
50 cxDefineDestructor(map, asc_behavior_destroy); |
51 return list; |
51 return map; |
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_list(); |
56 node->behaviors = asc_behavior_new_map(); |
57 } |
57 } |
58 AscBehavior *behavior = cxListEmplace(node->behaviors); |
58 cxmutstr name = args.name == NULL |
|
59 ? asc_util_gen_name("behavior") |
|
60 : cx_mutstr(strdup(args.name)); |
|
61 AscBehavior *behavior = cxMapEmplace(node->behaviors, name); |
59 assert(behavior != NULL); |
62 assert(behavior != NULL); |
60 behavior->enabled = true; |
63 behavior->enabled = true; |
61 behavior->killed = false; |
64 behavior->killed = false; |
62 behavior->node = node; |
65 behavior->node = node; |
63 behavior->func = args.func; |
66 behavior->func = args.func; |
64 behavior->destroy_func = args.destroy_func; |
67 behavior->destroy_func = args.destroy_func; |
65 behavior->data = args.data; |
68 behavior->data = args.data; |
66 behavior->interval = args.interval; |
69 behavior->interval = args.interval; |
67 behavior->last_execution = 0; |
70 behavior->last_execution = 0; |
68 asc_behavior_name(behavior, args.name); |
71 behavior->name = name; |
69 asc_dprintf("Create behavior: %"CX_PRIstr, CX_SFMT(behavior->name)); |
72 asc_dprintf("Create behavior: %"CX_PRIstr, CX_SFMT(behavior->name)); |
70 return behavior; |
73 return behavior; |
71 } |
74 } |
72 |
75 |
73 void asc_behavior_remove(AscBehavior *behavior) { |
76 void asc_behavior_remove(AscBehavior *behavior) { |
82 |
85 |
83 behavior->func(behavior); |
86 behavior->func(behavior); |
84 behavior->last_execution = asc_context.total_nanos; |
87 behavior->last_execution = asc_context.total_nanos; |
85 } |
88 } |
86 |
89 |
87 void asc_behavior_name(AscBehavior *behavior, const char *name) { |
|
88 cx_strfree(&behavior->name); |
|
89 if (name == NULL) { |
|
90 behavior->name = asc_util_gen_name(behavior); |
|
91 } else { |
|
92 behavior->name.ptr = strdup(name); |
|
93 behavior->name.length = strlen(name); |
|
94 } |
|
95 } |
|
96 |
|
97 cxstring asc_behavior_get_name(const AscBehavior *behavior) { |
90 cxstring asc_behavior_get_name(const AscBehavior *behavior) { |
98 assert(behavior != NULL); |
91 assert(behavior != NULL); |
99 return cx_strcast(behavior->name); |
92 return cx_strcast(behavior->name); |
100 } |
93 } |
101 |
94 |
102 // TODO: add asc_behavior_find() and asc_behavior_find_global() |
95 // TODO: add asc_behavior_find() and asc_behavior_find_global() |
103 |
96 |
104 void asc_behavior_enable_all(AscSceneNode *node) { |
97 void asc_behavior_enable_all(AscSceneNode *node) { |
105 CxIterator iter = cxListIterator(node->behaviors); |
98 CxMapIterator iter = cxMapIteratorValues(node->behaviors); |
106 cx_foreach(AscBehavior*, behavior, iter) { |
99 cx_foreach(AscBehavior*, behavior, iter) { |
107 behavior->enabled = true; |
100 behavior->enabled = true; |
108 } |
101 } |
109 } |
102 } |
110 |
103 |
111 void asc_behavior_disable_all(AscSceneNode *node) { |
104 void asc_behavior_disable_all(AscSceneNode *node) { |
112 CxIterator iter = cxListIterator(node->behaviors); |
105 CxMapIterator iter = cxMapIteratorValues(node->behaviors); |
113 cx_foreach(AscBehavior*, behavior, iter) { |
106 cx_foreach(AscBehavior*, behavior, iter) { |
114 behavior->enabled = false; |
107 behavior->enabled = false; |
115 } |
108 } |
116 } |
109 } |