Blame synfig-core/src/synfig/value.cpp

Carlos Lopez a09598
/* === S Y N F I G ========================================================= */
Carlos Lopez a09598
/*!	\file value.cpp
Carlos Lopez a09598
**	\brief Template Header
Carlos Lopez a09598
**
Carlos Lopez a09598
**	$Id$
Carlos Lopez a09598
**
Carlos Lopez a09598
**	\legal
Carlos Lopez a09598
**	Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
Carlos Lopez a09598
**	Copyright (c) 2007, 2008 Chris Moore
Carlos Lopez 42fd7a
**  Copyright (c) 2011 Carlos Lรณpez
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is free software; you can redistribute it and/or
Carlos Lopez a09598
**	modify it under the terms of the GNU General Public License as
Carlos Lopez a09598
**	published by the Free Software Foundation; either version 2 of
Carlos Lopez a09598
**	the License, or (at your option) any later version.
Carlos Lopez a09598
**
Carlos Lopez a09598
**	This package is distributed in the hope that it will be useful,
Carlos Lopez a09598
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
Carlos Lopez a09598
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Carlos Lopez a09598
**	General Public License for more details.
Carlos Lopez a09598
**	\endlegal
Carlos Lopez a09598
*/
Carlos Lopez a09598
/* ========================================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === H E A D E R S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
#ifdef USING_PCH
Carlos Lopez a09598
#	include "pch.h"
Carlos Lopez a09598
#else
Carlos Lopez a09598
#ifdef HAVE_CONFIG_H
Carlos Lopez a09598
#	include <config.h></config.h>
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
#include "value.h"
Carlos Lopez a09598
#include "general.h"
bw 94d8a6
#include <synfig localization.h=""></synfig>
Carlos Lopez a09598
#include <etl stringf=""></etl>
Carlos Lopez a09598
#include "canvas.h"
Diego Barrios Romero 07d34c
#include "valuenodes/valuenode_bone.h"
Carlos Lopez a09598
#include "gradient.h"
Nikita Kitaev dc5e35
#include "bone.h"
Nikita Kitaev dc5e35
#include "matrix.h"
Nikita Kitaev dc5e35
#include "boneweightpair.h"
990d18
#include "transformation.h"
Carlos Lopez a09598
Carlos Lopez a09598
Carlos Lopez a09598
Carlos Lopez a09598
#include "vector.h"
Carlos Lopez a09598
#include "time.h"
Carlos Lopez a09598
#include "segment.h"
Carlos Lopez a09598
#include "color.h"
Carlos Lopez a09598
Carlos Lopez a09598
#endif
Carlos Lopez a09598
Carlos Lopez a09598
using namespace synfig;
Carlos Lopez a09598
using namespace std;
Carlos Lopez a09598
using namespace etl;
Carlos Lopez a09598
Carlos Lopez a09598
/* === M A C R O S ========================================================= */
Carlos Lopez a09598
Nikita Kitaev dc5e35
#define TRY_FIX_FOR_BUG_27
Nikita Kitaev dc5e35
Carlos Lopez a09598
/* === G L O B A L S ======================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === P R O C E D U R E S ================================================= */
Carlos Lopez a09598
Carlos Lopez a09598
/* === M E T H O D S ======================================================= */
Carlos Lopez a09598
204555
ValueBase::ValueBase():
Rodolfo Ribeiro Gomes 3b90f0
	type(&type_nil),data(nullptr),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED)
a255a5
{
9bfc3b
#ifdef INITIALIZE_TYPE_BEFORE_USE
a255a5
	type->initialize();
a255a5
#endif
a255a5
}
Carlos Lopez a09598
204555
ValueBase::ValueBase(Type &x):
Rodolfo Ribeiro Gomes 3b90f0
	type(&type_nil),data(nullptr),ref_count(0),loop_(0),static_(0),interpolation_(INTERPOLATION_UNDEFINED)
Carlos Lopez a09598
{
9bfc3b
#ifdef INITIALIZE_TYPE_BEFORE_USE
e00af6
	type->initialize();
a255a5
#endif
204555
	create(x);
Carlos Lopez a09598
}
Carlos Lopez a09598
Rodolfo Ribeiro Gomes 288b11
ValueBase::ValueBase(const ValueBase& x)
Rodolfo Ribeiro Gomes 288b11
	: ValueBase(*x.type)
Rodolfo Ribeiro Gomes 288b11
{
Rodolfo Ribeiro Gomes 288b11
	if(data != x.data)
Rodolfo Ribeiro Gomes 288b11
	{
Rodolfo Ribeiro Gomes 288b11
		Operation::CopyFunc copy_func =
Rodolfo Ribeiro Gomes 288b11
			Type::get_operation<operation::copyfunc>(</operation::copyfunc>
Rodolfo Ribeiro Gomes 288b11
				Operation::Description::get_copy(type->identifier, type->identifier) );
Rodolfo Ribeiro Gomes 288b11
		if (copy_func)
Rodolfo Ribeiro Gomes 288b11
		{
Rodolfo Ribeiro Gomes 288b11
			copy_func(data, x.data);
Rodolfo Ribeiro Gomes 288b11
		}
Rodolfo Ribeiro Gomes 288b11
		else
Rodolfo Ribeiro Gomes 288b11
		{
Rodolfo Ribeiro Gomes 288b11
			data = x.data;
Rodolfo Ribeiro Gomes 288b11
			ref_count = x.ref_count;
Rodolfo Ribeiro Gomes 288b11
		}
Rodolfo Ribeiro Gomes 288b11
	}
Rodolfo Ribeiro Gomes 288b11
Rodolfo Ribeiro Gomes 288b11
	loop_ = x.loop_;
Rodolfo Ribeiro Gomes 288b11
	static_ = x.static_;
Rodolfo Ribeiro Gomes 288b11
	interpolation_ = x.interpolation_;
Rodolfo Ribeiro Gomes 288b11
}
Rodolfo Ribeiro Gomes 288b11
Rodolfo Ribeiro Gomes 6b433d
ValueBase::ValueBase(ValueBase&& x) noexcept
Rodolfo Ribeiro Gomes 288b11
	: ValueBase()
Rodolfo Ribeiro Gomes 288b11
{
Rodolfo Ribeiro Gomes 288b11
	swap(*this, x);
Rodolfo Ribeiro Gomes 288b11
}
Rodolfo Ribeiro Gomes 288b11
Carlos Lopez a09598
ValueBase::~ValueBase()
Carlos Lopez a09598
{
Carlos Lopez a09598
	clear();
Carlos Lopez a09598
}
Carlos Lopez a09598
Rodolfo Ribeiro Gomes 288b11
ValueBase&
Rodolfo Ribeiro Gomes 288b11
ValueBase::operator=(ValueBase x)
Rodolfo Ribeiro Gomes 288b11
{
Rodolfo Ribeiro Gomes 288b11
	swap(*this, x);
Rodolfo Ribeiro Gomes 288b11
	return *this;
Rodolfo Ribeiro Gomes 288b11
}
Rodolfo Ribeiro Gomes 288b11
Carlos Lopez a09598
#ifdef _DEBUG
Carlos Lopez a09598
String
Carlos Lopez a09598
ValueBase::get_string() const
Carlos Lopez a09598
{
204555
	Operation::ToStringFunc func =
204555
		Type::get_operation<operation::tostringfunc>(</operation::tostringfunc>
204555
			Operation::Description::get_to_string(type->identifier) );
204555
	return func == NULL ? "Invalid type" : func(data);
Carlos Lopez a09598
}
Carlos Lopez a09598
#endif	// _DEBUG
Carlos Lopez a09598
204555
bool
204555
ValueBase::is_valid()const
Carlos Lopez a09598
{
204555
	return type != &type_nil && ref_count;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
204555
ValueBase::create(Type &type)
Carlos Lopez a09598
{
9bfc3b
#ifdef INITIALIZE_TYPE_BEFORE_USE
e00af6
	type.initialize();
a255a5
#endif
204555
	if (type == type_nil) { clear(); return; }
204555
	Operation::CreateFunc func =
204555
		Type::get_operation<operation::createfunc>(</operation::createfunc>
204555
			Operation::Description::get_create(type.identifier) );
204555
	assert(func != NULL);
Carlos Lopez a09598
	clear();
204555
	this->type = &type;
204555
	data = func();
204555
	ref_count.reset();
Carlos Lopez a09598
}
Carlos Lopez a09598
7f43d7
void
4c1d21
ValueBase::copy(const ValueBase& x)
4c1d21
{
204555
	Operation::CopyFunc func =
204555
		Type::get_operation<operation::copyfunc>(</operation::copyfunc>
204555
			Operation::Description::get_copy(type->identifier, x.type->identifier));
Rodolfo Ribeiro Gomes 3b90f0
	if (func)
4c1d21
	{
204555
		if (!ref_count.unique()) create();
204555
		func(data, x.data);
204555
	}
204555
	else
204555
	{
204555
		Operation::CopyFunc func =
204555
			Type::get_operation<operation::copyfunc>(</operation::copyfunc>
204555
				Operation::Description::get_copy(x.type->identifier, x.type->identifier));
Rodolfo Ribeiro Gomes 3b90f0
		if (func)
204555
		{
204555
			if (!ref_count.unique()) create(*x.type);
204555
			func(data, x.data);
204555
		}
4c1d21
	}
4c1d21
	copy_properties_of(x);
4c1d21
}
4c1d21
4c1d21
void
7f43d7
ValueBase::copy_properties_of(const ValueBase& x)
7f43d7
{
7f43d7
	loop_=x.loop_;
7f43d7
	static_=x.static_;
7f43d7
	interpolation_=x.interpolation_;
7f43d7
}
7f43d7
Carlos Lopez a09598
bool
Carlos Lopez a09598
ValueBase::empty()const
Carlos Lopez a09598
{
204555
	return !is_valid() || (type == &type_list ? get_list().empty() : false);
Carlos Lopez a09598
}
Carlos Lopez a09598
204555
Type&
Carlos Lopez a09598
ValueBase::get_contained_type()const
Carlos Lopez a09598
{
204555
	if (type != &type_list || empty())
204555
		return type_nil;
Carlos Lopez a09598
	return get_list().front().get_type();
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
void
Carlos Lopez a09598
ValueBase::clear()
Carlos Lopez a09598
{
Carlos Lopez a09598
	if(ref_count.unique() && data)
Carlos Lopez a09598
	{
204555
		Operation::DestroyFunc func =
204555
			Type::get_operation<operation::destroyfunc>(</operation::destroyfunc>
204555
				Operation::Description::get_destroy(type->identifier) );
204555
		assert(func != NULL);
204555
		func(data);
Carlos Lopez a09598
	}
Carlos Lopez a09598
	ref_count.detach();
Rodolfo Ribeiro Gomes 3b90f0
	data=nullptr;
204555
	type=&type_nil;
Carlos Lopez a09598
}
Carlos Lopez a09598
204555
Type&
Carlos Lopez a09598
ValueBase::ident_type(const String &str)
Carlos Lopez a09598
{
204555
	Type *type = Type::try_get_type_by_name(str);
Rodolfo Ribeiro Gomes 3b90f0
	return type ? *type : type_nil;
Carlos Lopez a09598
}
Carlos Lopez a09598
Carlos Lopez a09598
bool
Carlos Lopez a09598
ValueBase::operator==(const ValueBase& rhs)const
Carlos Lopez a09598
{
5ccd0a
	Operation::EqualFunc func =
5ccd0a
		Type::get_operation<operation::equalfunc>(</operation::equalfunc>
5ccd0a
			Operation::Description::get_equal(type->identifier, rhs.type->identifier) );
Rodolfo Ribeiro Gomes 3b90f0
	return !func ? false : func(data, rhs.data);
5ccd0a
}
5ccd0a
5ccd0a
bool
5ccd0a
ValueBase::operator<(const ValueBase& rhs)const
5ccd0a
{
5ccd0a
	Operation::LessFunc func =
5ccd0a
		Type::get_operation<operation::lessfunc>(</operation::lessfunc>
5ccd0a
			Operation::Description::get_less(type->identifier, rhs.type->identifier) );
Rodolfo Ribeiro Gomes 3b90f0
	return !func ? false : func(data, rhs.data);
Carlos Lopez a09598
}