Metadataを扱う

メタデータは、Atomsの基本的な構成要素の1つです。これらは、基本のデータタイプをラップし、基本オブジェクトAtomsCore :: Metadataを継承します。

基本的なMetadataクラスには、複製、コピー、直列化などの機能があります。

これらはAtoms内で使用できる基本的なメタデータタイプです。

  • BoolMetadata
  • BoolArrayMetadata
  • IntMetadata
  • IntArrayMetadata
  • DoubleMetadata
  • DoubleArrayMetadata
  • Vector3Metadata
  • Vector3ArrayMetadata
  • EulerMetadata
  • EulerArrayMetadata
  • QuaternionMetadata
  • QuaternionArrayMetadata
  • MatrixMetadata
  • MatrixArrayMetadata
  • CurveMetadata
  • CurveArrayetadata
  • MeshMetadata
  • MeshArrayMetadata
  • ImageMetadata
  • PoseMetadata
  • SkeletonMetadata

これらはコンテナのメタデータタイプです。

  • MapMetadata
  • ArrayMetadata

メタデータの作成

各タイプのコンストラクタを使用してメタデータを作成することも、Metadata Factoryを使用することもできます。すべてのメタデータタイプには、固有のtypeIdがあり、メタデータをMetadata Factory内に登録するために使用されます。
Serialization Codeは、このファクトリに依存しています。

AtomsCore::IntMetadata intMeta(5);
AtomsCore::DoubleMetadata doubleMeta(654.4);

AtomsCore::MetadataFactory& factory = AtomsCore::MetadataFactory::instance();
AtomsPtr<AtomsCore::Metadata> data = factory.createMetadata(AtomsCore::Vector3Metadata::staticTypeId());

MapMetada

MapMetadataは、メタデータ用のマップコンテナです。同時に、異なるメタデータタイプを保存できます。キーとして文字列を使用します。
MapMetadata内に、データを挿入するには、addEntry関数を使用します。この関数は、入力メタデータを複製したり、入力スマートポインタを直接格納したりして、リファレンスカウンタを増やすことができます。

AtomsCore::MapMetadata mapMeta;
// Insert element cloning the data
mapMeta.addEnetry("myKey1", &AtomsCore::IntMetadata(4));

AtomsPtr<AtomsCore::DoubleMetadata> doubleMeta(new AtomsCore::DoubleMetadata(5.7));
// Insert element cloning the data
mapMeta.addEntry("myKey2", std::static_pointer_cast<AtomsCore::Metadata>(doubleMeta), true);

AtomsPtr<AtomsCore::Vector3Metadata> vecMeta(new AtomsCore::Vector3Metadata(AtomsCore::Vector3(1,0,0));
// Insert element without cloning, copying the smart pointer and increasing the reference counter
mapMeta.addEntry("myKey3", std::static_pointer_cast<AtomsCore::Metadata>(vecMeta), false);

マップからエントリを取得する場合は、getEntryまたはgetTypedEntry関数を使用します。

AtomsPtr<AtomsCore::Vector3Metadata> vecData = mapMeta.getTypedEntry<AtomsCore::Vector3Metadata>("myKey3");
AtomsPtr<Metadata> intData = mapMeta.getEntry("myKey1");

ArrayMetadata

ArrayMetadataは、MapMetadataに似ていますが、マップではなくベクトルにメタデータを格納します。

新しいMetadata Typeを作成する

新しいMetadata Typeを作成するには、基本のMetadataクラスを継承し、新しいタイプをMetadata Factoryに登録する必要があります。

#include <AtomsCore/Metadata/MetadataImpl.h>

class FooData
{
public:
	float a;
	double b;
	char c;
};

typedef AtomsCore::MetadataImpl<FooData> FooMetadata;
template<> bool AtomsCore::MetadataImpl<FooData>::serialise(Archive& outStream) const;
template<> bool AtomsCore::MetadataImpl<FooData>::deserialise(Archive& inStream);
template<> size_t MetadataImpl<FooData>::memSize() const;
template<> void AtomsCore::MetadataImpl<FooData>::toString(std::stringstream& inStream) const;
template class AtomsCore::MetadataImpl<FooData>;

template<> std::string AtomsCore::MetadataImpl<FooData>::staticTypeStr() { return "FooMetadata"; } //!< Bool metadata static type
template<> unsigned int AtomsCore::MetadataImpl<FooData>::staticTypeId() { return  9999999; } //!< This must be a unique id

template<> bool AtomsCore::MetadataImpl<FooData>::serialise(Archive& outStream) const
{
	if (outStream.size == 0)
	{
		outStream.resize(memSize());
	}
	// the type id must be the first data to serialise
	outStream << typeId();
	outStream << m_value.a;
	outStream << m_value.b;
	outStream << m_value.c;
}
template<> bool AtomsCore::MetadataImpl<FooData>::deserialise(Archive& inStream)
{
	unsigned int typeIdValue;
	inStream >> typeIdValue;
	if (typeIdValue != staticTypeId())
		return false;
	inStream >> m_value.a;
	inStream >> m_value.b;
	inStream >> m_value.c;
	return true;
}

template<> void AtomsCore::MetadataImpl<FooData>::toString(std::stringstream& inStream) const
{
	inStream << "FooData: a - " << m_value.a << " b - " << m_value.b << " c - " << m_value.c;
}

template<> size_t TypedArrayMetadata<FooData>::memSize() const
	{
		return sizeof(unsigned int) + sizeof(float) + sizeof(double) + sizeof(char); //typeid + a + b + c 
	}


template class AtomsCore::MetadataImpl<FooData>;

void registerFooMetadata()
{
	MetadataFactory& factory = MetadataFactory::instance();
	factory.registerMetadata(FooMetadata::staticTypeStr(), FooMetadata::staticTypeId(), &FooMetadata::creator);
	
}

Copyright © 2017, Toolchefs LTD.