source: trunk/src/object.cc @ 226

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