AnimSystem.cpp
Go to the documentation of this file.
1 #include "AnimSystem.hpp"
2 #include "AnimNode.hpp"
3 #include "AnimConnector.hpp"
4 
5 namespace iv
6 {
7 
9  System( sc ),
10  roots(),
11  _update_id( 0 )
12 {
13 }
14 
16 {
17  return this->_update_id;
18 }
19 
20 void AnimSystem::AnimUpdate_Connector( AnimConnector * connector )
21 {
22  bool ready = true;
23 
24  // are all parents ready for update?
25  connector->anim_eachParent(
26  [&]( AnimNodeI * node )
27  {
28  ready = ready && ( !node->Active() || node->System_UpdateId() == this->update_id() );
29  }
30  );
31 
32  //
33  if( !ready )
34  return;
35 
36  // prepare update on children nodes
37  connector->anim_eachChild(
38  [&]( AnimNodeI * node )
39  {
40  if( node->Active() )
41  {
42  node->System_UpdateStart();
43  }
44  }
45  );
46 
47  // update connector
48  connector->cm.log( SRC_INFO, ::iv::Defs::Log::Animation_SystemUpdate, "Connector pass down." );
49  this->connectors.push_back( connector );
50  connector->UpdatePass_Down();
51 
52  // update children nodes
53  connector->anim_eachChild(
54  [&]( AnimNodeI * node )
55  {
56  if( node->Active() )
57  {
58  this->AnimUpdate_Node( node );
59  }
60  }
61  );
62 }
63 
64 void AnimSystem::AnimUpdate_Node( AnimNodeI * node )
65 {
66  node->cm.log( SRC_INFO, ::iv::Defs::Log::Animation_SystemUpdate, "Node update start." );
67  this->nodes_cnt += 1;
68 
69  node->anim_eachChild(
70  [&]( AnimConnector * con )
71  {
72  this->AnimUpdate_Connector( con );
73  }
74  );
75 }
76 
77 void AnimSystem::AnimUpdate( int delta_ms )
78 {
79  // reset cache
80  this->connectors.clear();
81  this->nodes_cnt = 0;
82 
83  // next update id
84  this->_update_id += 1;
85 
86  this->log( SRC_INFO, ::iv::Defs::Log::NewFrame, "============================< anim_id ", this->_update_id, " >=================================" );
87 
88  //
89  Anim_float step_distance = Anim_float( delta_ms ) / Anim_float( 1000.0 );
90 
91  // down pass - change targets and advance towards them
92  for( AnimNodeI * root : this->roots )
93  if( root->Active() )
94  {
95  root->System_UpdateStart();
96  root->Connector_RequestStep( step_distance );
97  this->AnimUpdate_Node( root );
98  }
99 
100  // up pass - refresh distances
101  for( auto it = this->connectors.rbegin(); it != this->connectors.rend(); ++it )
102  {
103  AnimConnector * connector = *it;
104 
105  // end update on children
106  connector->anim_eachChild(
107  [&]( AnimNodeI * node )
108  {
109  if( node->Active() )
110  {
111  node->cm.log( SRC_INFO, ::iv::Defs::Log::Animation_SystemUpdate, "Node update end." );
112  node->System_UpdateEnd();
113  }
114  }
115  );
116 
117  // up pass update on connector
118  connector->cm.log( SRC_INFO, ::iv::Defs::Log::Animation_SystemUpdate, "Connector pass up." );
119  connector->UpdatePass_Up();
120  }
121 
122  for( AnimNodeI * root : this->roots )
123  if( root->Active() )
124  {
125  root->cm.log( SRC_INFO, ::iv::Defs::Log::Animation_SystemUpdate, "Node update end." );
126  root->System_UpdateEnd();
127  }
128 
129  this->log( SRC_INFO, ::iv::Defs::Log::Animation_Summary, "Summary: ", this->connectors.size(), " connectors updated, ", this->nodes_cnt, " nodes updated." );
130 }
131 
133 {
134  this->roots.insert( client );
135 }
136 
138 {
139  this->roots.erase( client );
140 }
141 
142 void AnimSystem::debug_print_connector( TreeDebugView * tree, AnimConnector * connector, PrintState & state )
143 {
144  tree->Push( connector->cm.name_id().c_str() );
145 
146  if( state.printed_connectors.count( connector ) )
147  {
148  tree->out() << " ..." << std::endl;
149  }
150  else
151  {
152  state.printed_connectors.insert( connector );
153 
154  TreeDebugView subtree( tree->context() );
155  connector->cm.inheritance_root()->print_status_with_inherited( &subtree, &connector->cm );
156  subtree.Write( TreeDebugView::Style::WeakFramesWeakLinks, tree );
157 
158  connector->anim_eachChild(
159  [&]( AnimNodeI * node )
160  {
161  this->debug_print_node( tree, node, state );
162  }
163  );
164  }
165 
166  tree->Pop();
167 }
168 
169 void AnimSystem::debug_print_node( TreeDebugView * tree, AnimNodeI * node, PrintState & state )
170 {
171  tree->Push( ( node->cm.name_id() + " " + node->label() ).c_str() );
172 
173  if( state.printed_nodes.count( node ) )
174  {
175  tree->out() << " ..." << std::endl;
176  }
177  else
178  {
179  state.printed_nodes.insert( node );
180 
181  TreeDebugView subtree( tree->context() );
182  node->cm.inheritance_root()->print_status_with_inherited( &subtree, &node->cm );
183  subtree.Write( TreeDebugView::Style::WeakFramesWeakLinks, tree );
184 
185  node->anim_eachChild(
186  [&]( AnimConnector * connector )
187  {
188  this->debug_print_connector( tree, connector, state );
189  }
190  );
191  }
192 
193  tree->Pop();
194 }
195 
197 {
198  TreeDebugView tc( view->context() );
199 
200  PrintState state;
201 
202  for( AnimNodeI * node : this->roots )
203  {
204  this->debug_print_node( &tc, node, state );
205  }
206 
208 }
209 
210 }