00001 #include "RelationalNode.h"
00002 #include "ViewController.h"
00003 #include "Factory.h"
00004 #include "XMLNode.h"
00005
00006 namespace RenderTools {
00007
00008 RelationalNode::RelationalNode( void ):
00009 TransformNode(){
00010
00011 }
00012
00013 PropertyPtr RelationalNode::create( const XMLNodePtr & xml ){
00014 RelationalNodePtr p( new RelationalNode() );
00015 p->setName( xml );
00016 p->createProperties();
00017 p->setProperties( xml, false );
00018 return( dynamic_pointer_cast< AbstractProperty, RelationalNode >( p ) );
00019 }
00020
00021 void RelationalNode::createProperties( void ){
00022 createProperty( this, "parents", & m_parents );
00023 createProperty( this, "children", & m_children );
00024 }
00025
00026 const string RelationalNode::getTypeName( bool ofComponent ) const {
00027 return( "RelationalNode" );
00028 }
00029
00030 #ifdef RT_PROFILER
00031
00032 void RelationalNode::beginProfiler( const string name, string file, int line ){
00033 string decoratedName = m_name + "[" + name + "]";
00034
00035 map<string, Profiler *>::iterator i;
00036 Profiler * p = 0;
00037 if( ( i = m_profilers.find( decoratedName ) ) == m_profilers.end() ){
00038 p = new Profiler( decoratedName, file, line );
00039 m_profilers[ decoratedName ] = p;
00040 }
00041 else{
00042 p = i->second;
00043 }
00044 if( p ){
00045 p->begin();
00046 }
00047 else{
00048 Error::error( Error::NULL_POINTER, __FILE__, __LINE__ );
00049 }
00050 }
00051
00052 void RelationalNode::endProfiler( const string name ){
00053 map<string, Profiler *>::iterator i;
00054 if( ( i = m_profilers.find( m_name + "[" + name + "]" ) ) == m_profilers.end() ){
00055 Error::error( Error::NULL_POINTER, __FILE__, __LINE__ );
00056 }
00057 else{
00058 i->second->end();
00059 }
00060 }
00061
00062 const map<string, Profiler *> & RelationalNode::getProfilers( void ){
00063 return( m_profilers );
00064 }
00065
00066 #endif
00067
00068 RelationalNode::~RelationalNode( void ){
00069 if( m_parents ){
00070 for( unsigned int i = 0; i < m_parents->size(); i++ ){
00071 m_parents->getItem( i )->removeChild( getSharedPtr< RelationalNode >(), true );
00072 }
00073 }
00074 if( m_children ){
00075 for( unsigned int i = 0; i < m_children->size(); i++ ){
00076 m_children->getItem( i )->removeParent( getSharedPtr< RelationalNode >(), true );
00077 }
00078 }
00079 #ifdef RT_PROFILER
00080 map<string, Profiler *>::iterator i = m_profilers.begin();
00081 for( ; i != m_profilers.end(); i++ ){
00082 delete i->second;
00083 }
00084 m_profilers.clear();
00085 #endif
00086
00087 }
00088
00089 void RelationalNode::onPropertyEvent( const PropertyEvent & e ){
00090
00091 }
00092
00093 void RelationalNode::onInitialize( void ){
00094
00095 }
00096
00097 void RelationalNode::onTransform( const Mat4 & global ){
00098 TransformNode::onTransform( global );
00099
00100 for( unsigned int i = 0; i < m_children->size(); i++ ){
00101 m_children->getItem( i )->transform( m_global );
00102 }
00103 }
00104
00105 void RelationalNode::gatherUniqueChildren( const RelationalNodePtr model, RelationalNodeList & unique ) const {
00106 if( std::find( unique.begin(), unique.end(), model ) == unique.end() ){
00107 unique.push_back( model );
00108 }
00109 for( unsigned int i = 0; i < model->getChildren()->size(); i++ ){
00110 gatherUniqueChildren( model->getChildren()->getItem( i ), unique );
00111 }
00112 }
00113
00114 bool RelationalNode::addParent( const RelationalNodePtr ptr, bool send ){
00115
00116 if( hasParent( ptr ) ){
00117 return( false );
00118 }
00119
00120 m_parents->addProperty( ptr, send );
00121
00122 if( ! ptr->hasChild( getSharedPtr< RelationalNode >() ) ){
00123 ptr->addChild( getSharedPtr< RelationalNode >(), send );
00124 }
00125 return( true );
00126 }
00127
00128 bool RelationalNode::addChild( const RelationalNodePtr ptr, bool send ){
00129
00130 if( hasChild( ptr ) ){
00131 return( false );
00132 }
00133
00134 m_children->addProperty( ptr, send );
00135
00136
00137 if( ! ptr->hasParent( getSharedPtr< RelationalNode >() ) ){
00138 ptr->addParent( getSharedPtr< RelationalNode >(), send );
00139 }
00140 return( true );
00141 }
00142
00143 const RelationalNodeContainerPtr RelationalNode::getChildren( void ) const {
00144 return( m_children );
00145 }
00146
00147 const RelationalNodeContainerPtr RelationalNode::getParents( void ) const {
00148 return( m_parents );
00149 }
00150
00151 const RelationalNodePtr RelationalNode::getParent( int i ) const {
00152 if( i >= 0 && i < (int)m_parents->size() ){
00153 return( m_parents->getItem( i ) );
00154 }
00155 else{
00156 Error::warning( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00157 return( RelationalNodePtr() );
00158 }
00159 }
00160
00161 const RelationalNodePtr RelationalNode::getChild( unsigned int index ) const {
00162 if( index >= 0 && index < (int)m_children->size() ){
00163 return( m_children->getItem( index ) );
00164 }
00165 else{
00166 Error::warning( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00167 return( RelationalNodePtr() );
00168 }
00169 }
00170
00171 const RelationalNodePtr RelationalNode::getChild( const string name ) const {
00172 if( m_name == name ){
00173 return( getSharedPtr< RelationalNode >() );
00174 }
00175 else{
00176 for( unsigned int i = 0; i < m_children->size(); i++ ){
00177 RelationalNodePtr ptr = m_children->getItem( i )->getChild( name );
00178 if( ptr ){
00179 return( ptr );
00180 }
00181 }
00182 return( RelationalNodePtr() );
00183 }
00184 }
00185
00186 const RelationalNodePtr RelationalNode::getChild( string name, RelationalNodeList & path ) const {
00187 path.push_back( getSharedPtr< RelationalNode >() );
00188
00189 if( m_name == name ){
00190 return( getSharedPtr< RelationalNode >() );
00191 }
00192 else{
00193 for( unsigned int i = 0; i < m_children->size(); i++ ){
00194 RelationalNodePtr child = m_children->getItem( i )->getChild( name, path );
00195 if( child ){
00196 return( child );
00197 }
00198 }
00199 path.pop_back();
00200 return( RelationalNodePtr() );
00201 }
00202 }
00203
00204 const RelationalNodePtr RelationalNode::getChild( const RelationalNodePtr model, RelationalNodeList & path ) const {
00205 path.push_back( getSharedPtr< RelationalNode >() );
00206
00207 if( getSharedPtr< RelationalNode >() == model ){
00208 return( model );
00209 }
00210 else{
00211 for( unsigned int i = 0; i < m_children->size(); i++ ){
00212 RelationalNodePtr child = m_children->getItem( i )->getChild( model, path );
00213 if( child ){
00214 return( child );
00215 }
00216 }
00217 path.pop_back();
00218 return( RelationalNodePtr() );
00219 }
00220 }
00221
00222 bool RelationalNode::hasParent( const RelationalNodePtr model ) const {
00223 unsigned int i;
00224 for( i = 0; i < m_parents->size(); i++ ){
00225 if( m_parents->getItem( i ) == model ){
00226 return( true );
00227 }
00228 }
00229 return( false );
00230 }
00231
00232 bool RelationalNode::hasChild( const RelationalNodePtr model ) const {
00233 unsigned int i;
00234 for( i = 0; i < m_children->size(); i++ ){
00235 if( m_children->getItem( i ) == model ){
00236 return( true );
00237 }
00238 }
00239 return( false );
00240 }
00241
00242 bool RelationalNode::removeParent( const RelationalNodePtr model, bool send ){
00243 unsigned int i;
00244 for( i = 0; i < m_parents->size(); i++ ){
00245 if( m_parents->getItem( i ) == model ){
00246 m_parents->removeProperty( i, send );
00247 if( model->hasChild( getSharedPtr< RelationalNode >() ) ){
00248 model->removeChild( getSharedPtr< RelationalNode >(), send );
00249 }
00250 return( true );
00251 }
00252 }
00253 return( false );
00254 }
00255
00256 bool RelationalNode::removeChild( const RelationalNodePtr model, bool send ){
00257 unsigned int i;
00258 for( i = 0; i < m_children->size(); i++ ){
00259 if( m_children->getItem( i ) == model ){
00260 m_children->removeProperty( i, send );
00261 if( model->hasParent( getSharedPtr< RelationalNode >() ) ){
00262 model->removeParent( getSharedPtr< RelationalNode >(), send );
00263 }
00264
00265 return( true );
00266 }
00267 }
00268 return( false );
00269 }
00270
00271 bool RelationalNode::removeChild( int i, bool send ){
00272 if( i >= 0 && i < (int)m_children->size() ){
00273 return( removeChild( m_children->getItem( i ), send ) );
00274 }
00275 else{
00276 Error::warning( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00277 return( false );
00278 }
00279 }
00280
00281 bool RelationalNode::removeParent( int i, bool send ){
00282 if( i >= 0 && i < (int)m_parents->size() ){
00283 RelationalNodePtr model = m_parents->getItem( i );
00284 m_parents->removeProperty( i, send );
00285 if( model->hasChild( getSharedPtr< RelationalNode >() ) ){
00286 model->removeChild( getSharedPtr< RelationalNode >(), send );
00287 }
00288 return( true );
00289 }
00290 else{
00291 Error::warning( Error::INDEX_OUT_OF_BOUNDS, __FILE__, __LINE__ );
00292 return( false );
00293 }
00294 }
00295
00296
00297 };