X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftags%2Fstable%2Fsrc%2Fsynfig%2Fvalue.h;fp=synfig-core%2Ftags%2Fstable%2Fsrc%2Fsynfig%2Fvalue.h;h=228eab19b0f92fd6470e7e4af34d9dc7bb33af1b;hb=d3408370fc3297609b3aa8d4ff7edf1f238df251;hp=0000000000000000000000000000000000000000;hpb=9f067badc4463e2ad6363dfe9b8c4fc28b0ec503;p=synfig.git diff --git a/synfig-core/tags/stable/src/synfig/value.h b/synfig-core/tags/stable/src/synfig/value.h new file mode 100644 index 0000000..228eab1 --- /dev/null +++ b/synfig-core/tags/stable/src/synfig/value.h @@ -0,0 +1,461 @@ +/* === S Y N F I G ========================================================= */ +/*! \file value.h +** \brief Template Header +** +** $Id$ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +*/ +/* ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __SYNFIG_VALUE_H +#define __SYNFIG_VALUE_H + +/* === H E A D E R S ======================================================= */ + +//#include "vector.h" +//#include "time.h" +#include "segment.h" +//#include "color.h" +#include "string.h" +#include +#include +#include +#include +#include "general.h" +//#include "gradient.h" +#include "blinepoint.h" +#include "exception.h" + +#ifdef USE_HALF_TYPE +#include +#endif + +#ifndef SYNFIG_NO_ANGLE +#include "angle.h" +#endif + +#include + +/* === M A C R O S ========================================================= */ + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +namespace synfig { + +class Canvas; +class Vector; +class Time; +class Segment; +class Gradient; +class BLinePoint; +class Color; + +/*! \class ValueBase +** \todo writeme +*/ +class ValueBase +{ + /* + -- ** -- T Y P E S ----------------------------------------------------------- + */ + +public: + + //! \writeme + enum Type + { + TYPE_NIL=0, //!< Represents an empty value + + TYPE_BOOL, + TYPE_INTEGER, + TYPE_ANGLE, //!< Angle + + // All types after this point are larger than 32 bits + + TYPE_TIME, //!< Time + TYPE_REAL, //!< Real + + // All types after this point are larger than 64 bits + + TYPE_VECTOR, //!< Vector + TYPE_COLOR, //!< Color + TYPE_SEGMENT, //!< Segment + TYPE_BLINEPOINT, //!< BLinePoint + + // All types after this point require construction/destruction + + TYPE_LIST, //!< List + TYPE_CANVAS, //!< Canvas + TYPE_STRING, //!< String + TYPE_GRADIENT, //!< Color Gradient + + TYPE_END //!< Not a valid type, used for sanity checks + }; + +private: + + typedef std::vector list_type; + + /* + -- ** -- D A T A ------------------------------------------------------------- + */ + +protected: + + Type type; + void *data; + etl::reference_counter ref_count; + bool loop_; + + /* + -- ** -- C O N S T R U C T O R S ----------------------------------- + */ + +public: + + //! \writeme + ValueBase(); + + //! \writeme + template + ValueBase(const T &x, bool loop_=false): + type(TYPE_NIL),data(0),ref_count(0),loop_(loop_) + { set(x); } + + //! \writeme + ValueBase(Type x); + + //! \writeme + ~ValueBase(); + + /* + -- ** -- O P E R A T O R S --------------------------------------------------- + */ + +public: + + //! \writeme + template ValueBase& operator=(const T& x) + { set(x); return *this; } + + //! \writeme + ValueBase& operator=(const ValueBase& x); + + //! \writeme + bool operator==(const ValueBase& rhs)const; + + //! \writeme + bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); } + + //! Constant index operator for when value is of type TYPE_LIST + const ValueBase &operator[](int index)const + { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; } + + /* + -- ** -- M E M B E R F U N C T I O N S ------------------------------------- + */ + +public: + + //! \writeme + void clear(); + + //! \writeme + bool get_loop()const { return loop_; } + + //! \writeme + void set_loop(bool x) { loop_=x; } + + //! \writeme + bool empty()const; + + //! \writeme + Type get_contained_type()const; + + //! Returns true if the contained value is defined and valid. + bool is_valid()const; + + //! Returns a string containing the name of the type + String type_name()const { return type_name(type); } + + //! Returns the type of the contained value + const Type & get_type()const { return type; } + + //! Checks the type of the parameter against itself. Returns true if they are of the same type. + template bool + same_as(const T &x)const + { + const Type testtype(get_type(x)); + + if(testtype==type)return true; + if( (type==TYPE_REAL || type==TYPE_TIME) && + (testtype==TYPE_REAL || testtype==TYPE_TIME) ) + return true; + return false; + } + + + // === GET MEMBERS ======================================================== + template + const T &get(const T& x)const + { + assert(is_valid() && same_as(x)); + return *static_cast(data); + } + float get(const float &)const { return get(Real()); } + etl::loose_handle get(const etl::handle&)const + { return get(etl::loose_handle()); } + etl::loose_handle get(Canvas*)const + { return get(etl::loose_handle()); } + const char* get(const char*)const; + const list_type& get_list()const { return get(list_type()); } + // ======================================================================== + + + + // === PUT MEMBERS ======================================================== + template + void put(T* x)const + { + assert(same_as(*x)); + *x=*static_cast(data); + } + void put(float* x)const { *x=get(Real()); } + void put(char** x)const; + // ======================================================================== + + + + // === SET MEMBERS ======================================================== + template void set(const T& x) { _set(x); } + void set(const float &x) { _set(Real(x)); } + void set(const list_type &x); + void set(const char* x); + void set(Canvas*x); + void set(etl::loose_handle x); + void set(etl::handle x); + template void set(const std::vector &x) + { _set(list_type(x.begin(),x.end())); } + template void set(const std::list &x) + { _set(list_type(x.begin(),x.end())); } + // ======================================================================== + + + /* + -- ** -- S T A T I C F U N C T I O N S ------------------------------------- + */ + +public: + + //! Returns a string containing the name of the given Type + static String type_name(Type id); + + //! Returns a the corresponding Type of the described type + static Type ident_type(const String &str); + + + // === GET TYPE MEMBERS =================================================== + static const Type get_type(bool) { return TYPE_BOOL; } + static const Type get_type(int) { return TYPE_INTEGER; } + static const Type get_type(const Time&) { return TYPE_TIME; } + static const Type get_type(const Real&) { return TYPE_REAL; } + static const Type get_type(const float&) { return TYPE_REAL; } + static const Type get_type(const Vector&) { return TYPE_VECTOR; } + static const Type get_type(const Color&) { return TYPE_COLOR; } + static const Type get_type(const Segment&) { return TYPE_SEGMENT; } + static const Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; } + static const Type get_type(const String&) { return TYPE_STRING; } + static const Type get_type(const Gradient&) { return TYPE_GRADIENT; } + static const Type get_type(Canvas*) { return TYPE_CANVAS; } + static const Type get_type(const etl::handle&) + { return TYPE_CANVAS; } + static const Type get_type(const etl::loose_handle&) + { return TYPE_CANVAS; } + static const Type get_type(const list_type&) { return TYPE_LIST; } + template static const Type get_type(const std::vector &x) + { return TYPE_LIST; } + template static const Type get_type(const std::list &x) + { return TYPE_LIST; } + // ======================================================================== + + + /* + -- ** -- C A S T O P E R A T O R S ----------------------------------------- + */ + +public: + + operator const list_type&()const { return get_list(); } + //operator const Color&()const { return get(Color()); } + //operator const Real&()const { return get(Real()); } + //operator const Time&()const { return get(Time()); } + + operator const Vector&()const { return get(Vector()); } + operator const BLinePoint&()const { return get(BLinePoint()); } + //operator const int&()const { return get(int()); } + //operator const String&()const { return get(String()); } + //operator const char *()const { return get(String()).c_str(); } + operator const Segment&()const { return get(Segment()); } + + + /* + -- ** -- O T H E R ----------------------------------------------------------- + */ + +public: + +#ifdef USE_HALF_TYPE + half get(const half &)const { return get(Real()); } + void put(half*x)const { *x=get(Real()); } + void set(const half &x) { _set(Real(x)); } + static const Type get_type(const half&) { return TYPE_REAL; } + operator half()const { return get(Real()); } +#endif + +#ifndef SYNFIG_NO_ANGLE + operator const Angle&()const { return get(Angle()); } + static const Type get_type(const Angle&) { return TYPE_ANGLE; } +#endif + + template + operator std::list()const + { + assert(type==TYPE_LIST); + std::list ret(get_list().begin(),get_list().end()); + return ret; + } + template + operator std::vector()const + { + assert(type==TYPE_LIST); + std::vector ret(get_list().begin(),get_list().end()); + return ret; + } + + +private: + + template void + _set(const T& x) + { + const Type newtype(get_type(x)); + + assert(newtype!=TYPE_NIL); + + if(newtype==type) + { + if(ref_count.unique()) + { + *reinterpret_cast(data)=x; + return; + } + } + + clear(); + + type=newtype; + ref_count.reset(); + data=new T(x); + } +}; // END of class ValueBase + + +/*! \class Value +** \todo writeme +*/ +template +class Value : public ValueBase +{ +public: + Value(const T &x):ValueBase(x) + { + } + + Value(const ValueBase &x):ValueBase(x) + { + if(!x.same_as(T())) + throw Exception::BadType("Value(ValueBase): Type Mismatch"); + } + + Value() + { + } + + T get()const { return ValueBase::get(T()); } + + void put(T* x)const { ValueBase::put(x); } + + void set(const T& x) { ValueBase::operator=(x); } + + Value& operator=(const T& x) { set(x); return *this; } + + Value& operator=(const Value& x) { return ValueBase::operator=(x); } + + Value& operator=(const ValueBase& x) + { + if(!x.same_as(T())) + throw Exception::BadType("Value(ValueBase): Type Mismatch"); + return ValueBase::operator=(x); + } + +}; // END of class Value + +/* +template <> +class Value< std::list > : public ValueBase +{ +public: + Value(const T &x):ValueBase(x) + { + } + Value(const ValueBase &x):ValueBase(x) + { + if(!x.same_as(T())) + throw Exception::BadType("Value(ValueBase): Type Mismatch"); + } + Value() + { + } + + T get()const { return ValueBase::get(T()); } + + void put(T* x)const { ValueBase::put(x); } + + void set(const T& x) { ValueBase::operator=(x); } + + Value& operator=(const T& x) { set(x); return *this; } + + Value& operator=(const Value& x) { return ValueBase::operator=(x); } + + Value& operator=(const ValueBase& x) + { + if(!x.same_as(T())) + throw Exception::BadType("Value(ValueBase): Type Mismatch"); + return ValueBase::operator=(x); + } + +}; // END of class Value +*/ + +}; // END of namespace synfig + +/* === E N D =============================================================== */ + +#endif