Blame synfig-core/src/synfig/rendering/resource.h

813345
/* === S Y N F I G ========================================================= */
813345
/*!	\file synfig/rendering/resource.h
813345
**	\brief Resource Header
813345
**
813345
**	$Id$
813345
**
813345
**	\legal
813345
**	......... ... 2015 Ivan Mahonin
813345
**
813345
**	This package is free software; you can redistribute it and/or
813345
**	modify it under the terms of the GNU General Public License as
813345
**	published by the Free Software Foundation; either version 2 of
813345
**	the License, or (at your option) any later version.
813345
**
813345
**	This package is distributed in the hope that it will be useful,
813345
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
813345
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
813345
**	General Public License for more details.
813345
**	\endlegal
813345
*/
813345
/* ========================================================================= */
813345
813345
/* === S T A R T =========================================================== */
813345
813345
#ifndef __SYNFIG_RENDERING_RESOURCE_H
813345
#define __SYNFIG_RENDERING_RESOURCE_H
813345
813345
/* === H E A D E R S ======================================================= */
813345
813345
#include <vector></vector>
813345
813345
#include <etl handle=""></etl>
Rodolfo Ribeiro Gomes 7a962f
#include <mutex></mutex>
813345
813345
/* === M A C R O S ========================================================= */
813345
813345
/* === T Y P E D E F S ===================================================== */
813345
813345
/* === C L A S S E S & S T R U C T S ======================================= */
813345
813345
namespace synfig
813345
{
813345
namespace rendering
813345
{
813345
813345
// TODO: move to ::synfig or to ::etl
813345
class Resource: public etl::shared_object
813345
{
813345
public:
371bd9
	typedef unsigned long long Id;
371bd9
371bd9
private:
371bd9
	static Id last_id;
371bd9
371bd9
public:
813345
	typedef etl::handle<resource> Handle;</resource>
813345
	typedef std::vector<handle> List;</handle>
813345
813345
	class Storage: public etl::virtual_shared_object
813345
	{
813345
	public:
813345
		typedef etl::handle<storage> Handle;</storage>
813345
813345
	private:
Rodolfo Ribeiro Gomes 9b0489
		mutable std::atomic<int> refcount;</int>
813345
813345
		friend class Resource;
813345
813345
		List resources;
813345
813345
		static const List blank;
813345
813345
	public:
813345
		Storage();
813345
		~Storage();
813345
813345
		virtual void ref() const;
813345
		virtual bool unref_inactive() const;
813345
		virtual bool unref() const;
813345
		virtual int count() const;
813345
	};
813345
813345
private:
371bd9
	const Id id;
813345
	mutable Storage::Handle alternatives;
Rodolfo Ribeiro Gomes 7a962f
	mutable std::mutex get_alternative_mtx;
813345
813345
public:
371bd9
	Resource(): id(++last_id) { }
371bd9
371bd9
	Id get_id() const { return id; }
371bd9
813345
	const List& get_alternatives() const
813345
		{ return alternatives ? alternatives->resources : Storage::blank; }
813345
813345
	void set_alternative(Handle other) const;
813345
	void unset_alternative() const;
813345
813345
	template<typename t=""></typename>
813345
	etl::handle<t> find_alternative() const</t>
813345
	{
3124d5
		const List &resources = get_alternatives();
813345
		for(List::const_iterator i = resources.begin(); i != resources.end(); ++i)
813345
			if (etl::handle<t> alternative = etl::handle<t>::cast_dynamic(*i))</t></t>
813345
				return alternative;
813345
		return etl::handle<t>();</t>
813345
	}
813345
813345
	template<typename t=""></typename>
813345
	etl::handle<t> get_alternative() const</t>
813345
	{
Rodolfo Ribeiro Gomes 7a962f
		std::lock_guard<std::mutex> lock(get_alternative_mtx);</std::mutex>
813345
		etl::handle<t> alternative = find_alternative<t>();</t></t>
813345
		if (!alternative)
813345
		{
813345
			alternative = new T(*this);
813345
			set_alterntive(alternative);
813345
		}
813345
		return alternative;
813345
	}
813345
};
813345
813345
} /* end namespace rendering */
813345
} /* end namespace synfig */
813345
813345
/* -- E N D ----------------------------------------------------------------- */
813345
813345
#endif