/
Working with metadatas

Working with metadatas

Metadatas are one of the basic entities in Atoms. They wrap basic data types and inherit the basic object AtomsCore::Metadata.

The basic Metadata class has functions to clone, copy, serialize etc.

These are the basic metadata type that can be used inside Atoms:

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

These are container metadata types:

  • MapMetadata
  • ArrayMetadata

Creating metadatas

You can create metadatas using the constructor of each type or you can use the metadata factory. Every metadata type has a unique typeId, it's used to register the metadata inside the metadata factory. Since the serialization code relies on this factory.

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

The MapMetadata is a map container for metadatas. It can store different metadata types at the same time. It uses strings as keys.

To insert data inside a MapMetadata use the addEntry function. This function can clone the input metadata or store directly the input smart pointer, increasing the reference counter.

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);

To get an entry from the map, use the getEntry or getTypedEntry function

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

ArrayMetadata

The array metadata is similar to the MapMetadata but it stores metadata in a vector rather than a map.

Creating a new metadata type

To create a new metadata type you must inherit the base Metadata class and register the new type in the 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);
	
}

Related content

Working with metadatas with Python
Working with metadatas with Python
More like this
Metadata
More like this
Runtime Attribute Access
Runtime Attribute Access
Read with this
Working with metadata (AtomsUnreal)
Working with metadata (AtomsUnreal)
More like this
Parsing atoms objects
Parsing atoms objects
Read with this
Serialization
More like this

Copyright © 2017, Toolchefs LTD.