25 #ifndef __SYNFIG_TYPE_H
26 #define __SYNFIG_TYPE_H
79 template<
typename T>
class WeightedValue;
81 namespace types_namespace
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); }
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&);
169 template<
typename Inner>
171 {
return new Inner(); }
172 template<
typename Inner>
174 {
return delete (Inner*)x; }
175 template<
typename Inner,
typename Outer>
177 { *(Inner*)dest = src; }
178 template<
typename Inner,
typename Outer>
180 { dest =
static_cast<const Outer&
>(*(Inner*)src); }
181 template<
typename Inner,
typename Outer>
183 {
return static_cast<const Outer&
>(*(Inner*)x); }
184 template<
typename Inner>
186 { *(Inner*)dest = *(Inner*)src; }
187 template<
typename Inner>
189 {
return *(Inner*)a == *(Inner*)b; }
190 template<
typename Inner, String (*Func)(const Inner&)>
192 {
return Func(*(
const Inner*)x); }
205 operation_type(operation_type), return_type(return_type), type_a(type_a), type_b(type_b) { }
213 : type_a < other.
type_a ?
true
214 : other.
type_a < type_a ?
false
218 bool operator > (
const Description &other)
const {
return other < *
this; }
233 {
return Description(TYPE_COPY, 0, type_a, type_b); }
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); }
243 {
return Description(operation_type, return_type, type_a, type_b); }
269 class OperationBookBase
272 static OperationBookBase *first, *last;
273 OperationBookBase *previous, *next;
276 OperationBookBase(
const OperationBookBase &): previous(NULL), next(NULL), initialized(
false) { }
277 OperationBookBase& operator= (
const OperationBookBase &) {
return *
this; }
282 virtual void remove_type(TypeId identifier) = 0;
283 virtual void set_alias(OperationBookBase *alias) = 0;
284 virtual ~OperationBookBase();
286 static void remove_type_from_all_books(TypeId identifier);
290 static void initialize_all();
291 static void deinitialize_all();
295 class OperationBook :
public OperationBookBase
298 typedef std::pair<Type*, T> Entry;
299 typedef std::map<Operation::Description, Entry> Map;
301 static OperationBook instance;
307 OperationBook(): map_alias(&map) { }
310 inline Map& get_map()
312 #ifdef INITIALIZE_TYPE_BEFORE_USE
313 if (!OperationBookBase::initialized) OperationBookBase::initialize_all();
318 inline const Map& get_map()
const
320 #ifdef INITIALIZE_TYPE_BEFORE_USE
321 if (!OperationBookBase::initialized) OperationBookBase::initialize_all();
326 virtual void set_alias(OperationBookBase *alias)
328 map_alias = alias == NULL ? &map : ((OperationBook<T>*)alias)->map_alias;
329 if (map_alias != &map)
331 map_alias->insert(map.begin(), map.end());
336 virtual void remove_type(TypeId identifier)
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;
346 map.begin()->second.first->deinitialize();
350 static Type *first, *last;
351 static TypeId last_identifier;
353 static struct StaticData {
354 std::vector<Type*> typesById;
355 std::map<String, Type*> typesByName;
356 ~StaticData() { deinitialize_all(); }
359 Type *previous, *next;
361 TypeId private_identifier;
362 Description private_description;
364 Type *clone_prev, *clone_next;
371 explicit Type(TypeId);
377 previous(NULL), next(NULL),
379 private_identifier(0),
382 identifier(private_identifier),
383 description(private_description)
386 Type& operator= (
const Type &) { assert(
false);
return *
this; }
388 void register_type();
389 void unregister_type();
393 void register_operation(
const Operation::Description &description, T func)
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);
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; }
419 static void initialize_all();
420 static void deinitialize_all();
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;
436 {
return get_operation<T>(description); }
445 inline static const TypeId& get_type_id()
446 {
return get_type<T>().identifier; }
449 inline static Type& get_type_by_pointer(
const T *)
450 {
return get_type<T>(); }
453 inline static Type& get_type_by_reference(
const T &)
454 {
return get_type<T>(); }
456 static Type* try_get_type_by_id(TypeId
id)
457 {
return id < staticData.typesById.size() ? staticData.typesById[id] : NULL; }
461 std::map<String, Type*>::const_iterator i = staticData.typesByName.find(name);
462 return i == staticData.typesByName.end() ? NULL : i->second;
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); }
469 { assert(try_get_type_by_name(name) != NULL);
return *try_get_type_by_name(name); }
477 inline void register_set(TypeId type,
typename Operation::GenericFuncs<T>::SetFunc func)
480 inline void register_put(TypeId type,
typename Operation::GenericFuncs<T>::PutFunc func)
483 inline void register_get(TypeId type,
typename Operation::GenericFuncs<T>::GetFunc func)
500 { register_operation(description, func); }
524 { register_create(identifier, func); }
526 { register_destroy(identifier, func); }
529 { register_set<T>(identifier, func); }
532 { register_put<T>(identifier, func); }
535 { register_get<T>(identifier, func); }
537 { register_copy(identifier, func); }
539 { register_compare(identifier, func); }
541 { register_to_string(identifier, func); }
543 template<
typename Inner,
typename Outer, String (*Func)(const Inner&)>
544 inline void register_all()
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>);
556 template<
typename Inner,
typename Outer, String (*Func)(const Inner&)>
557 inline void register_all_but_compare()
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>);
568 template<
typename Inner,
typename Outer>
569 inline void register_alias()
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>);
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>(); }
585 static String _value_to_string(
const T &alias,
const typename T::AliasedType &x)
587 if (alias.type.identifier == NIL) {
589 Type::get_operation<Operation::ToStringFunc>(
591 return to_string_func(NULL);
594 typedef typename T::AliasedType TT;
597 Type::get_operation<Operation::CreateFunc>(
599 typename Operation::GenericFuncs<TT>::SetFunc set_func =
600 Type::get_operation<typename Operation::GenericFuncs<TT>::SetFunc>(
603 Type::get_operation<Operation::ToStringFunc>(
606 Type::get_operation<Operation::DestroyFunc>(
608 assert(create_func != NULL);
609 assert(set_func != NULL);
610 assert(to_string_func != NULL);
611 assert(destroy_func != NULL);
613 InternalPointer data = create_func();
615 String res = to_string_func(data);
622 static String value_to_string(
const T &x)
639 Type::OperationBook<T> Type::OperationBook<T>::instance;