| 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 } |