synfig-core  1.0.3
type.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
21 /* ========================================================================= */
22 
23 /* === S T A R T =========================================================== */
24 
25 #ifndef __SYNFIG_TYPE_H
26 #define __SYNFIG_TYPE_H
27 
28 /* === H E A D E R S ======================================================= */
29 
30 #include <cassert>
31 #include <vector>
32 #include <map>
33 #include <typeinfo>
34 #include "string.h"
35 #include "general.h"
36 
37 /* === M A C R O S ========================================================= */
38 
39 //#define INITIALIZE_TYPE_BEFORE_USE
40 
41 /* === T Y P E D E F S ===================================================== */
42 
43 /* === C L A S S E S & S T R U C T S ======================================= */
44 
45 namespace synfig {
46  class Type;
47 
48  template<typename T>
49  class TypeAlias {
50  public:
51  typedef T AliasedType;
53  TypeAlias(Type &type): type(type) { }
54  };
55 }
56 
57 #include "real.h"
58 #include "string.h"
59 #include "angle.h"
60 #include <ETL/handle>
61 
62 namespace synfig {
63 
64 class Time;
65 class Color;
66 struct Segment;
67 class BLinePoint;
68 class Matrix;
69 class BoneWeightPair;
70 class WidthPoint;
71 class DashItem;
72 class ValueBase;
73 class Canvas;
74 class Vector;
75 class Gradient;
76 class Bone;
77 class ValueNode_Bone;
78 class Transformation;
79 template<typename T> class WeightedValue;
80 
81 namespace types_namespace
82 {
83 #define SYNFIG_DECLARE_TYPE_ALIAS(T) \
84  TypeAlias< T > get_type_alias(T const&);
85 #define SYNFIG_IMPLEMENT_TYPE_ALIAS(T, Class) \
86  TypeAlias< T > get_type_alias(T const&) { return TypeAlias< T >(Class::instance); }
87 
97  SYNFIG_DECLARE_TYPE_ALIAS(BLinePoint)
99  SYNFIG_DECLARE_TYPE_ALIAS(BoneWeightPair)
100  SYNFIG_DECLARE_TYPE_ALIAS(WidthPoint)
101  SYNFIG_DECLARE_TYPE_ALIAS(DashItem)
102  SYNFIG_DECLARE_TYPE_ALIAS(std::vector<ValueBase>)
103  SYNFIG_DECLARE_TYPE_ALIAS(etl::loose_handle<Canvas>)
104  SYNFIG_DECLARE_TYPE_ALIAS(etl::handle<Canvas>)
107  SYNFIG_DECLARE_TYPE_ALIAS(const char*)
108  SYNFIG_DECLARE_TYPE_ALIAS(Gradient)
110  SYNFIG_DECLARE_TYPE_ALIAS(etl::handle<ValueNode_Bone>)
111  SYNFIG_DECLARE_TYPE_ALIAS(etl::loose_handle<ValueNode_Bone>)
112  SYNFIG_DECLARE_TYPE_ALIAS(ValueNode_Bone*)
113  SYNFIG_DECLARE_TYPE_ALIAS(Transformation)
114 
115  template<typename T>
116  TypeAlias< WeightedValue<T> > get_type_alias(WeightedValue<T> const&);
117  template<typename T1, typename T2>
118  TypeAlias< std::pair<T1, T2> > get_type_alias(std::pair<T1, T2> const&);
119 } // namespace types_namespace
120 } // namespace synfig
121 
122 namespace synfig {
123 
124 extern Type &type_nil;
125 
126 typedef unsigned int TypeId;
127 
132 {
133 public:
134  typedef void* InternalPointer;
135 
146  };
147 
148  typedef InternalPointer (*CreateFunc) ();
149  typedef void (*DestroyFunc) (const InternalPointer);
150  typedef void (*CopyFunc) (const InternalPointer dest, const InternalPointer src);
151  typedef bool (*CompareFunc) (const InternalPointer, const InternalPointer);
152  typedef InternalPointer (*BinaryFunc) (const InternalPointer, const InternalPointer);
153  typedef String (*ToStringFunc) (const InternalPointer);
154 
155  template<typename T>
157  {
158  public:
159  typedef void (*SetFunc) (InternalPointer dest, const T &src);
160  typedef void (*PutFunc) (T &dest, const InternalPointer src);
161  typedef const T& (*GetFunc) (const InternalPointer);
162  private:
163  GenericFuncs() { }
164  };
165 
167  {
168  public:
169  template<typename Inner>
170  static InternalPointer create()
171  { return new Inner(); }
172  template<typename Inner>
173  static void destroy(const InternalPointer x)
174  { return delete (Inner*)x; }
175  template<typename Inner, typename Outer>
176  static void set(InternalPointer dest, const Outer &src)
177  { *(Inner*)dest = src; }
178  template<typename Inner, typename Outer>
179  static void put(Outer &dest, const InternalPointer src)
180  { dest = static_cast<const Outer&>(*(Inner*)src); }
181  template<typename Inner, typename Outer>
182  static const Outer& get(const InternalPointer x)
183  { return static_cast<const Outer&>(*(Inner*)x); }
184  template<typename Inner>
185  static void copy(InternalPointer dest, const InternalPointer src)
186  { *(Inner*)dest = *(Inner*)src; }
187  template<typename Inner>
188  static bool compare(InternalPointer a, const InternalPointer b)
189  { return *(Inner*)a == *(Inner*)b; }
190  template<typename Inner, String (*Func)(const Inner&)>
191  static String to_string(const InternalPointer x)
192  { return Func(*(const Inner*)x); }
193  private:
194  DefaultFuncs() { }
195  };
196 
197  struct Description
198  {
200  TypeId return_type;
201  TypeId type_a;
202  TypeId type_b;
203 
204  Description(OperationType operation_type = TYPE_NONE, TypeId return_type = 0, TypeId type_a = 0, TypeId type_b = 0):
205  operation_type(operation_type), return_type(return_type), type_a(type_a), type_b(type_b) { }
206 
207  bool operator < (const Description &other) const
208  {
209  return operation_type < other.operation_type ? true
210  : other.operation_type < operation_type ? false
211  : return_type < other.return_type ? true
212  : other.return_type < return_type ? false
213  : type_a < other.type_a ? true
214  : other.type_a < type_a ? false
215  : type_b < other.type_b;
216  }
217 
218  bool operator > (const Description &other) const { return other < *this; }
219  bool operator != (const Description &other) const { return *this < other || other < *this; }
220  bool operator == (const Description &other) const { return !(*this != other); }
221 
222  inline static Description get_create(TypeId type)
223  { return Description(TYPE_CREATE, type); }
224  inline static Description get_destroy(TypeId type)
225  { return Description(TYPE_DESTROY, 0, type); }
226  inline static Description get_set(TypeId type)
227  { return Description(TYPE_SET, 0, type); }
228  inline static Description get_put(TypeId type)
229  { return Description(TYPE_PUT, 0, 0, type); }
230  inline static Description get_get(TypeId type)
231  { return Description(TYPE_GET, 0, type); }
232  inline static Description get_copy(TypeId type_a, TypeId type_b)
233  { return Description(TYPE_COPY, 0, type_a, type_b); }
234  inline static Description get_copy(TypeId type)
235  { return get_compare(type, type); }
236  inline static Description get_compare(TypeId type_a, TypeId type_b)
237  { return Description(TYPE_COPY, 0, type_a, type_b); }
238  inline static Description get_compare(TypeId type)
239  { return get_compare(type, type); }
240  inline static Description get_to_string(TypeId type)
241  { return Description(TYPE_TO_STRING, 0, type); }
242  inline static Description get_binary(OperationType operation_type, TypeId return_type, TypeId type_a, TypeId type_b)
243  { return Description(operation_type, return_type, type_a, type_b); }
244  };
245 
246 private:
247  Operation() { }
248 }; // END of class Operation
249 
250 
254 class Type
255 {
256 public:
257  enum { NIL = 0 };
259 
260  struct Description
261  {
265  std::vector<String> aliases;
266  };
267 
268 private:
269  class OperationBookBase
270  {
271  protected:
272  static OperationBookBase *first, *last;
273  OperationBookBase *previous, *next;
274  bool initialized;
275 
276  OperationBookBase(const OperationBookBase &): previous(NULL), next(NULL), initialized(false) { }
277  OperationBookBase& operator= (const OperationBookBase &) { return *this; }
278 
279  OperationBookBase();
280 
281  public:
282  virtual void remove_type(TypeId identifier) = 0;
283  virtual void set_alias(OperationBookBase *alias) = 0;
284  virtual ~OperationBookBase();
285 
286  static void remove_type_from_all_books(TypeId identifier);
287 
288  void initialize();
289  void deinitialize();
290  static void initialize_all();
291  static void deinitialize_all();
292  };
293 
294  template<typename T>
295  class OperationBook : public OperationBookBase
296  {
297  public:
298  typedef std::pair<Type*, T> Entry;
299  typedef std::map<Operation::Description, Entry> Map;
300 
301  static OperationBook instance;
302 
303  private:
304  Map map;
305  Map *map_alias;
306 
307  OperationBook(): map_alias(&map) { }
308 
309  public:
310  inline Map& get_map()
311  {
312 #ifdef INITIALIZE_TYPE_BEFORE_USE
313  if (!OperationBookBase::initialized) OperationBookBase::initialize_all();
314 #endif
315  return *map_alias;
316  }
317 
318  inline const Map& get_map() const
319  {
320 #ifdef INITIALIZE_TYPE_BEFORE_USE
321  if (!OperationBookBase::initialized) OperationBookBase::initialize_all();
322 #endif
323  return *map_alias;
324  }
325 
326  virtual void set_alias(OperationBookBase *alias)
327  {
328  map_alias = alias == NULL ? &map : ((OperationBook<T>*)alias)->map_alias;
329  if (map_alias != &map)
330  {
331  map_alias->insert(map.begin(), map.end());
332  map.clear();
333  }
334  }
335 
336  virtual void remove_type(TypeId identifier)
337  {
338  Map &map = get_map();
339  for(typename Map::iterator i = map.begin(); i != map.end();)
340  if (i->second.first->identifier == identifier)
341  map.erase(i++); else ++i;
342  }
343 
344  ~OperationBook() {
345  while(!map.empty())
346  map.begin()->second.first->deinitialize();
347  }
348  };
349 
350  static Type *first, *last;
351  static TypeId last_identifier;
352 
353  static struct StaticData {
354  std::vector<Type*> typesById;
355  std::map<String, Type*> typesByName;
356  ~StaticData() { deinitialize_all(); }
357  } staticData;
358 
359  Type *previous, *next;
360  bool initialized;
361  TypeId private_identifier;
362  Description private_description;
363 
364  Type *clone_prev, *clone_next;
365 
366 public:
367  const TypeId &identifier;
369 
370 protected:
371  explicit Type(TypeId);
372  Type();
373 
374 private:
375  // lock default copy constructor
376  Type(const Type &):
377  previous(NULL), next(NULL),
378  initialized(false),
379  private_identifier(0),
380  clone_prev(NULL),
381  clone_next(NULL),
382  identifier(private_identifier),
383  description(private_description)
384  { assert(false); }
385  // lock default assignment
386  Type& operator= (const Type &) { assert(false); return *this; }
387 
388  void register_type();
389  void unregister_type();
390 
391 private:
392  template<typename T>
393  void register_operation(const Operation::Description &description, T func)
394  {
395  typedef typename OperationBook<T>::Entry Entry;
396  typedef typename OperationBook<T>::Map Map;
397  Map &map = OperationBook<T>::instance.get_map();
398  assert(!map.count(description) || map[description].first == this);
399  map[description] = Entry(this, func);
400  }
401 
402 protected:
403  virtual void initialize_vfunc(Description &description)
404  {
405  description.version = "0.0";
406  }
407 
408  virtual void deinitialize_vfunc(Description & /* description */) { }
409 
410 public:
411  virtual ~Type();
412 
413  void initialize();
414  void deinitialize();
415 
416  inline bool operator== (const Type &other) { return private_identifier == other.private_identifier; }
417  inline bool operator!= (const Type &other) { return private_identifier != other.private_identifier; }
418 
419  static void initialize_all();
420  static void deinitialize_all();
421 
422  inline Type* get_next() const { return next; }
423  inline static Type* get_first() { return first; }
424 
425  template<typename T>
426  static T get_operation(const Operation::Description &description)
427  {
428  typedef typename OperationBook<T>::Map Map;
429  const Map &map = OperationBook<T>::instance.get_map();
430  typename Map::const_iterator i = map.find(description);
431  return i == map.end() ? NULL : i->second.second;
432  }
433 
434  template<typename T>
435  static T get_operation_by_type(const Operation::Description &description, T)
436  { return get_operation<T>(description); }
437 
438  template<typename T>
439  inline static Type& get_type()
440  {
441  return types_namespace::get_type_alias(T()).type;
442  }
443 
444  template<typename T>
445  inline static const TypeId& get_type_id()
446  { return get_type<T>().identifier; }
447 
448  template<typename T>
449  inline static Type& get_type_by_pointer(const T *)
450  { return get_type<T>(); }
451 
452  template<typename T>
453  inline static Type& get_type_by_reference(const T &)
454  { return get_type<T>(); }
455 
456  static Type* try_get_type_by_id(TypeId id)
457  { return id < staticData.typesById.size() ? staticData.typesById[id] : NULL; }
458 
459  static Type* try_get_type_by_name(const String &name)
460  {
461  std::map<String, Type*>::const_iterator i = staticData.typesByName.find(name);
462  return i == staticData.typesByName.end() ? NULL : i->second;
463  }
464 
465  static Type& get_type_by_id(TypeId id)
466  { assert(try_get_type_by_id(id) != NULL); return *try_get_type_by_id(id); }
467 
468  static Type& get_type_by_name(const String &name)
469  { assert(try_get_type_by_name(name) != NULL); return *try_get_type_by_name(name); }
470 
471 private:
472  inline void register_create(TypeId type, Operation::CreateFunc func)
473  { register_operation(Operation::Description::get_create(type), func); }
474  inline void register_destroy(TypeId type, Operation::DestroyFunc func)
475  { register_operation(Operation::Description::get_destroy(type), func); }
476  template<typename T>
477  inline void register_set(TypeId type, typename Operation::GenericFuncs<T>::SetFunc func)
478  { register_operation(Operation::Description::get_set(type), func); }
479  template<typename T>
480  inline void register_put(TypeId type, typename Operation::GenericFuncs<T>::PutFunc func)
481  { register_operation(Operation::Description::get_put(type), func); }
482  template<typename T>
483  inline void register_get(TypeId type, typename Operation::GenericFuncs<T>::GetFunc func)
484  { register_operation(Operation::Description::get_get(type), func); }
485 
486 protected:
487  inline void register_copy(TypeId type_a, TypeId type_b, Operation::CopyFunc func)
488  { register_operation(Operation::Description::get_copy(type_a, type_b), func); }
489  inline void register_copy(TypeId type, Operation::CopyFunc func)
490  { register_operation(Operation::Description::get_copy(type), func); }
491  inline void register_compare(TypeId type_a, TypeId type_b, Operation::CompareFunc func)
492  { register_operation(Operation::Description::get_compare(type_a, type_b), func); }
493  inline void register_compare(TypeId type, Operation::CompareFunc func)
494  { register_operation(Operation::Description::get_compare(type), func); }
495  inline void register_to_string(TypeId type, Operation::ToStringFunc func)
496  { register_operation(Operation::Description::get_to_string(type), func); }
497  inline void register_binary(Operation::OperationType operation_type, TypeId type_return, TypeId type_a, TypeId type_b, Operation::BinaryFunc func)
498  { register_operation(Operation::Description::get_binary(operation_type, type_return, type_a, type_b), func); }
499  inline void register_binary(const Operation::Description &description, Operation::BinaryFunc func)
500  { register_operation(description, func); }
501 
502  inline void register_create(Operation::CreateFunc func)
503  { register_create(identifier, func); }
504  inline void register_destroy(Operation::DestroyFunc func)
505  { register_destroy(identifier, func); }
506  template<typename T>
507  inline void register_set(typename Operation::GenericFuncs<T>::SetFunc func)
508  { register_set(identifier, func); }
509  template<typename T>
510  inline void register_put(typename Operation::GenericFuncs<T>::PutFunc func)
511  { register_put(identifier, func); }
512  template<typename T>
513  inline void register_get(typename Operation::GenericFuncs<T>::GetFunc func)
514  { register_get(identifier, func); }
515  inline void register_copy(Operation::CopyFunc func)
516  { register_copy(identifier, func); }
517  inline void register_compare(Operation::CompareFunc func)
518  { register_compare(identifier, func); }
519  inline void register_to_string(Operation::ToStringFunc func)
520  { register_to_string(identifier, func); }
521 
522  // default register
523  inline void register_default(Operation::CreateFunc func)
524  { register_create(identifier, func); }
525  inline void register_default(Operation::DestroyFunc func)
526  { register_destroy(identifier, func); }
527  template<typename T>
528  inline void register_default(typename Operation::GenericFuncs<T>::SetFunc func)
529  { register_set<T>(identifier, func); }
530  template<typename T>
531  inline void register_default(typename Operation::GenericFuncs<T>::PutFunc func)
532  { register_put<T>(identifier, func); }
533  template<typename T>
534  inline void register_default(typename Operation::GenericFuncs<T>::GetFunc func)
535  { register_get<T>(identifier, func); }
536  inline void register_default(Operation::CopyFunc func)
537  { register_copy(identifier, func); }
538  inline void register_default(Operation::CompareFunc func)
539  { register_compare(identifier, func); }
540  inline void register_default(Operation::ToStringFunc func)
541  { register_to_string(identifier, func); }
542 
543  template<typename Inner, typename Outer, String (*Func)(const Inner&)>
544  inline void register_all()
545  {
546  register_default(Operation::DefaultFuncs::create<Inner>);
547  register_default(Operation::DefaultFuncs::destroy<Inner>);
548  register_default<Outer>(Operation::DefaultFuncs::set<Inner, Outer>);
549  register_default<Outer>(Operation::DefaultFuncs::put<Inner, Outer>);
550  register_default<Outer>(Operation::DefaultFuncs::get<Inner, Outer>);
551  register_default(Operation::DefaultFuncs::copy<Inner>);
552  register_default(Operation::DefaultFuncs::compare<Inner>);
553  register_default(Operation::DefaultFuncs::to_string<Inner, Func>);
554  }
555 
556  template<typename Inner, typename Outer, String (*Func)(const Inner&)>
557  inline void register_all_but_compare()
558  {
559  register_default(Operation::DefaultFuncs::create<Inner>);
560  register_default(Operation::DefaultFuncs::destroy<Inner>);
561  register_default<Outer>(Operation::DefaultFuncs::set<Inner, Outer>);
562  register_default<Outer>(Operation::DefaultFuncs::put<Inner, Outer>);
563  register_default<Outer>(Operation::DefaultFuncs::get<Inner, Outer>);
564  register_default(Operation::DefaultFuncs::copy<Inner>);
565  register_default(Operation::DefaultFuncs::to_string<Inner, Func>);
566  }
567 
568  template<typename Inner, typename Outer>
569  inline void register_alias()
570  {
571  register_default<Outer>(Operation::DefaultFuncs::set<Inner, Outer>);
572  register_default<Outer>(Operation::DefaultFuncs::put<Inner, Outer>);
573  register_default<Outer>(Operation::DefaultFuncs::get<Inner, Outer>);
574  }
575 
576  template<typename Outer, String (*Func)(const Outer&)>
577  inline void register_all()
578  { register_all<Outer, Outer, Func>(); }
579  template<typename Outer, String (*Func)(const Outer&)>
580  inline void register_all_but_compare()
581  { register_all_but_compare<Outer, Outer, Func>(); }
582 
583 private:
584  template<typename T>
585  static String _value_to_string(const T &alias, const typename T::AliasedType &x)
586  {
587  if (alias.type.identifier == NIL) {
588  Operation::ToStringFunc to_string_func =
589  Type::get_operation<Operation::ToStringFunc>(
590  Operation::Description::get_to_string(alias.type.identifier) );
591  return to_string_func(NULL);
592  }
593 
594  typedef typename T::AliasedType TT;
595 
596  Operation::CreateFunc create_func =
597  Type::get_operation<Operation::CreateFunc>(
598  Operation::Description::get_create(alias.type.identifier) );
599  typename Operation::GenericFuncs<TT>::SetFunc set_func =
600  Type::get_operation<typename Operation::GenericFuncs<TT>::SetFunc>(
601  Operation::Description::get_set(alias.type.identifier) );
602  Operation::ToStringFunc to_string_func =
603  Type::get_operation<Operation::ToStringFunc>(
604  Operation::Description::get_to_string(alias.type.identifier) );
605  Operation::DestroyFunc destroy_func =
606  Type::get_operation<Operation::DestroyFunc>(
607  Operation::Description::get_destroy(alias.type.identifier) );
608  assert(create_func != NULL);
609  assert(set_func != NULL);
610  assert(to_string_func != NULL);
611  assert(destroy_func != NULL);
612 
613  InternalPointer data = create_func();
614  set_func(data, x);
615  String res = to_string_func(data);
616  destroy_func(data);
617  return res;
618  }
619 
620 public:
621  template<typename T>
622  static String value_to_string(const T &x)
623  { return _value_to_string(types_namespace::get_type_alias(x), x); }
624 
625 public:
626  static bool subsys_init() {
627  initialize_all();
628  return true;
629  }
630 
631  static bool subsys_stop() {
632  deinitialize_all();
633  return true;
634  }
635 }; // END of class Type
636 
637 
638 template<typename T>
639 Type::OperationBook<T> Type::OperationBook<T>::instance;
640 
641 }; // END of namespace synfig
642 
643 /* === E N D =============================================================== */
644 
645 #endif