source: trunk/src/object.cc @ 105

Last change on this file since 105 was 105, checked in by epyon, 12 years ago
  • root object has virtual functions child_added, child_removed, called on add or remove
File size: 4.2 KB
Line 
1// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
2// http://chaosforge.org/
3//
4// This file is part of NV Libraries.
5// For conditions of distribution and use, see copyright notice in nv.hh
6
7#include "nv/object.hh"
8
9#include "nv/root.hh"
10#include "nv/types.hh"
11#include "nv/lua/lua_state.hh"
12#include "nv/uid.hh"
13
14using namespace nv;
15
16object::object()
17        : m_root( nullptr ), m_id(), m_name(), m_uid(0), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
18{
19//      m_uid = uid_store::get_free_uid();
20//      uid_store::register_object( this, m_uid );
21}
22
23object::object( root* aroot, const string& aid )
24        : m_root( aroot ), m_id(aid), m_name(), m_uid( 0 ), m_lua_index(-2), m_parent( nullptr ), m_children(), m_child_count(0)
25{
26        if ( m_root )
27        {
28                uid_store*  store = get_root()->get_uid_store();
29                lua::state* state = get_root()->get_lua_state();
30                if (store)
31                {
32                        m_uid = store->insert( this );
33                }
34                if (state)
35                {
36                        m_lua_index = state->register_object( this );
37                }
38        }
39
40}
41
42void object::add_child( object* child )
43{
44        if (child)
45        {
46                if (child->m_parent)
47                {
48                        child->detach();
49                }
50                child->m_parent = this;
51                m_children.push_back( child );
52                m_child_count++;
53                m_root->child_added( child );
54        }
55}
56
57void object::remove_child( object* child )
58{
59        if ( child->m_parent != this )
60        {
61                return; // signal error?
62        }
63        list::iterator it = std::find( m_children.begin(), m_children.end(), child );
64        if ( it != m_children.end() )
65        {
66                (*it)->m_parent = nullptr;
67                m_children.erase(it);
68                m_root->child_removed( child );
69        }       
70}
71
72void object::detach()
73{
74        if (m_parent)
75        {
76                m_parent->remove_child( this );
77        }
78}
79
80void object::change_parent( object* new_parent )
81{
82        if (m_parent) detach();
83        if (new_parent) new_parent->add_child( this );
84}
85
86void object::destroy_children()
87{
88        while ( !m_children.empty() )
89        {
90                delete m_children.front();
91        }
92}
93
94object::~object()
95{
96        if ( m_lua_index != lua::ref_none )
97        {
98                lua::state* state = get_root()->get_lua_state();
99                state->unregister_object( this );
100        }
101        if ( m_uid != 0 && m_root )
102        {
103                uid_store* store = get_root()->get_uid_store();
104                if (store) store->remove( m_uid );
105        }
106        detach();
107        destroy_children();
108}
109
110object* object::find( object* child, bool recursive /*= false */ )
111{
112        list::iterator it = std::find( m_children.begin(), m_children.end(), child );
113        if ( it != m_children.end() )
114        {
115                return *it;
116        }
117        if ( recursive )
118        {
119                for ( object* i : m_children )
120                {
121                        object* r = i->find( child, recursive );
122                        if (r) return r;
123                }
124        }
125        return nullptr;
126}
127
128object* object::find( uid child, bool recursive /*= false */ )
129{
130        for ( object* i : m_children )
131        {
132                if (i->m_uid == child) return i;
133        }
134        if ( recursive )
135        {
136                for ( object* i : m_children )
137                {
138                        object* r = i->find( child, recursive );
139                        if (r) return r;
140                }
141        }
142        return nullptr;
143}
144
145object* object::find( string child, bool recursive /*= false */ )
146{
147        for ( object* i : m_children )
148        {
149                if (i->m_id == child) return i;
150        }
151        if ( recursive )
152        {
153                for ( object* i : m_children )
154                {
155                        object* r = i->find( child, recursive );
156                        if (r) return r;
157                }
158        }
159        return nullptr;
160}
161
162bool object::move_to_top( object* child )
163{
164        list::iterator it = std::find( m_children.begin(), m_children.end(), child );
165        if ( it != m_children.end() )
166        {
167                m_children.erase( it );
168                m_children.push_back( child );
169                return true;
170        }       
171        return false;
172}
173
174bool object::move_to_bottom( object* child )
175{
176        list::iterator it = std::find( m_children.begin(), m_children.end(), child );
177        if ( it != m_children.end() )
178        {
179                m_children.erase( it );
180                m_children.push_front( child );
181                return true;
182        }       
183        return false;
184}
185
186void object::register_type( type_database* db )
187{
188        type_field fields[] = {
189                type_field("id",          &object::m_id),
190                type_field("uid",         &object::m_uid).flag( TF_READONLY ),
191                type_field("lua_index",   &object::m_lua_index).flag( TF_READONLY | TF_NOSERIALIZE ),
192                type_field("parent",      &object::m_parent).flag( TF_READONLY | TF_NOSERIALIZE ),
193                type_field("child_count", &object::m_child_count).flag( TF_READONLY ),
194                type_field("children"   , &object::m_children).flag( TF_READONLY ),
195        };
196        db->create_type<object>("object").fields(fields);
197}
Note: See TracBrowser for help on using the repository browser.