Develop Biology
The language of life
Identifiable.h
Go to the documentation of this file.
1/*
2 * This file is a part of the Biology project by eons LLC.
3 * Biology (aka Develop Biology) is a framework for approaching software
4 * development from a natural sciences perspective.
5 *
6 * Copyright (C) 2021 Séon O'Shannon & eons LLC
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
25#include "bio/common/String.h"
27#include "Perspective.h"
28#include "Observer.h"
29#include "Wave.h"
31#include <cstring>
32
33namespace bio {
34namespace physical {
35
49template < typename DIMENSION >
51 virtual public Observer< Perspective< DIMENSION > >, //includes VirtualBase, so no need to re-inherit.
52 public physical::Class< Identifiable< DIMENSION > >
53{
54public:
55 typedef DIMENSION Id;
56 typedef std::vector< Id > Ids;
57
63
64
65
68 explicit Identifiable(Perspective< DIMENSION >* perspective = NULL)
69 :
70 physical::Class< Identifiable< DIMENSION > >(this),
72 m_name(NULL),
73 #endif
74 m_id(Perspective< DIMENSION >::InvalidId())
75 {
77 if (perspective)
78 {
80 }
81 }
82
87 explicit Identifiable(
88 Name name,
89 Perspective< DIMENSION >* perspective = NULL
90 )
91 :
92 physical::Class< Identifiable< DIMENSION > >(this),
94 m_name(NULL),
95 #endif
96 m_id(Perspective< DIMENSION >::InvalidId())
97 {
98 CloneIntoName(name);
99 if (perspective)
100 {
102 m_id = this->GetPerspective()->GetIdFromName(m_name);
103 this->MakeWave();
104 }
105 else
106 {
108 }
109 }
110
115 explicit Identifiable(
116 Id id,
117 Perspective< DIMENSION >* perspective = NULL
118 )
119 :
120 physical::Class< Identifiable< DIMENSION > >(this),
122 m_name(NULL),
123 #endif
124 m_id(Perspective< DIMENSION >::InvalidId())
125 {
126 if (perspective)
127 {
128 Observer< Perspective< DIMENSION > >::Initialize(perspective);
129 CloneIntoName(perspective->GetNameFromId(id));
130 this->MakeWave();
131 }
132 else
133 {
136 }
137 }
138
142 Identifiable(const Identifiable& other)
143 :
144 physical::Class< Identifiable< DIMENSION > >(this),
146 m_name(NULL),
147 #endif
148 m_id(other.m_id)
149 {
150 Observer< Perspective< DIMENSION > >::Initialize(other.GetPerspective());
151 CloneIntoName(other.GetName());
152 }
153
157 virtual ~Identifiable()
158 {
159 #if BIO_MEMORY_OPTIMIZE_LEVEL == 0
160 delete[] m_name;
161 #endif
162 }
163
167 virtual operator DIMENSION() const
168 {
169 return m_id;
170 }
171
176 virtual bool operator==(const Id id) const
177 {
178 if (!this->GetId())
179 {
180 return false;
181 }
182 if (!this->GetId() == id.m_t)
183 {
184 return false;
185 }
186 if (this->GetPerspective() && !this->IsNameInsensitive(this->GetPerspective()->GetNameFromId(id)))
187 {
188 return false;
189 }
190 return true;
191 }
192
198 virtual bool operator==(Name name) const
199 {
200 if (!GetName())
201 {
202 if (!name)
203 {
204 return true;
205 }
206 return false;
207 }
208 if (!name)
209 {
210 return false;
211 }
212 if (this->GetPerspective() && !this->IsId(this->GetPerspective()->GetIdWithoutCreation(name)))
213 {
214 return false;
215 }
216 return true;
217 }
218
223 virtual bool operator==(const Identifiable< DIMENSION >& other) const
224 {
225 return this->IsId(other.GetId()) && this->GetPerspective() == other.GetPerspective();
226 }
227
231 virtual Name GetName() const
232 {
233 #if BIO_MEMORY_OPTIMIZE_LEVEL == 0
234 return m_name;
235 #else
236 return BIO_SANITIZE_WITH_CACHE(this->GetPerspective(), RESULT->GetNameFromId(m_id), return "INVALID_NAME");
237 #endif
238 }
239
243 virtual Id GetId() const
244 {
245 return m_id;
246 }
247
253 virtual void SetName(Name name)
254 {
255 //TODO: should this check be after setting the name?
256 // if so, the constructors can be simplified.
257 if (!this->GetPerspective())
258 {
259 return;
260 }
261 CloneIntoName(name);
262
263 m_id = this->GetPerspective()->GetIdFromName(m_name);
264 }
265
271 virtual void SetId(Id id)
272 {
273 if (!this->GetPerspective())
274 {
275 return;
276 }
277 m_id = id;
278
279 CloneIntoName(this->GetPerspective()->GetNameFromId(m_id));
280 }
281
288 virtual bool IsName(Name name) const
289 {
290 return !strcmp(
291 name,
292 this->GetName());
293 }
294
299 virtual bool IsNameInsensitive(Name name) const
300 {
301 return !strcasecmp(
302 name,
303 this->GetName());
304 }
305
310 virtual bool IsId(Id id) const
311 {
312 return id == m_id;
313 }
314
319 virtual void SetPerspective(Perspective< DIMENSION >* perspective)
320 {
321 this->SetPerspective(perspective);
322
324 {
325 CloneIntoName(this->GetPerspective()->GetNameFromId(m_id));
326 }
328 {
329 m_id = this->GetPerspective()->GetIdFromName(GetName());
330 }
331 }
332
337 virtual void MakeWave(bool force = false)
338 {
339 if (!this->GetPerspective())
340 {
341 return;
342 }
343 if (force)
344 {
345 this->GetPerspective()->DisassociateType(m_id);
346 }
347 this->GetPerspective()->AssociateType(
348 m_id,
349 this
350 );
351 }
352
353 #if 0
354 //No need to compile these nops.
355
361 virtual Symmetry* Spin() const
362 {
363 return NULL;
364 }
365
372 virtual Code Reify(Symmetry* symmetry)
373 {
374 //nop
375 }
376 #endif
377
378protected:
383 virtual void InitializeImplementation(ByteStreams args)
384 {
385 if (args.size() == 2)
386 {
387 if (args[1].Is< Perspective< DIMENSION >* >())
388 {
389 Observer< Perspective< DIMENSION > >::Initialize(args[1]);
390 }
391 args.pop_back();
392 }
393 if (args.size() == 1)
394 {
395 if (args[0].Is(m_id))
396 {
397 m_id = args[0];
398 }
399 else if (args[0].Is(m_name))
400 {
401 CloneIntoName(args[0]);
402 }
403 }
404 }
405
406private:
407 #if BIO_MEMORY_OPTIMIZE_LEVEL == 0
408 Name m_name;
409 #endif
410
412
414 {
415 #if BIO_MEMORY_OPTIMIZE_LEVEL == 0
416 if (m_name)
417 {
418 delete[] m_name;
419 }
421 name,
422 m_name
423 );
424 #endif
425 }
426};
427
428} //physical namespace
429} //bio namespace
#define BIO_MEMORY_OPTIMIZE_LEVEL
#define BIO_SANITIZE_WITH_CACHE(test, success, failure)
void Initialize(ByteStreams args)
Definition: VirtualBase.cpp:40
Class(Identifiable< DIMENSION > *object, Symmetry *symmetry=NULL)
Definition: Class.h:46
void CloneIntoName(Name name)
Definition: Identifiable.h:413
BIO_DISAMBIGUATE_ALL_CLASS_METHODS(physical, Identifiable< DIMENSION >) explicit Identifiable(Perspective< DIMENSION > *perspective
std::vector< Id > Ids
Definition: Identifiable.h:56
virtual Perspective * GetPerspective() const
Definition: Observer.h:82
virtual void SetPerspective(Perspective *perspective)
Definition: Observer.h:74
virtual void InitializeImplementation(ByteStreams args)
Definition: Observer.h:92
virtual Symmetry * Spin() const
Definition: Wave.cpp:59
virtual Code Reify(Symmetry *symmetry)
Definition: Wave.cpp:64
void CloneInto(const char *source, const char *&target)
Definition: String.cpp:236
Definition: Cell.h:31
const char * Name
Definition: Types.h:46
std::vector< ByteStream > ByteStreams
Definition: Types.h:52