source: trunk/src/object.cc @ 187

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