You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

177 lines
5.7 KiB

/**
* @file IObject.h
* @brief Object system types and interfaces.
* @copyright VisionLabs LLC
* @date 25.06.2014
* */
#pragma once
#include "IRefCounted.h"
#include "Types.h"
namespace fsdk {
/**
* @addtogroup CoreGroup SDK core interfaces
* @brief Common interfaces and macros shared across all SDK objects.
* @{
* */
struct ISettingsProvider;
/**
* @brief Archive interface.
* @details Archives abstract data storage and IO operations.
*
* @note IArchive is not derived from IRefCounted and does not force any lifetime control. It is up to user to
* implement it.
*
* @note SDK ojects that use IArchive for serialization purposes do call only write() (during saving) or only
* read() (during loading) but never both during the same process unless otherwise is explicitly stated.
*
* @note During saving or loading SDK objects are free to write or read their data in chunks; e.g. there may be
* several sequential calls to write() in scope of a single serialization request. Any IArchive implementation
* should be aware of this.
* */
struct IArchive {
/**
* @brief Write bytes to archive.
* @param [in] data pointer to memory to write.
* @param [in] size data size.
* @return true if succeeded, false otherwise.
* */
virtual bool write(const void* data, size_t size) = 0;
/**
* @brief Read bytes from archive.
* @param [in] data pointer to memory to read to.
* @param [in] size data size.
* @return true if succeeded, false otherwise.
* */
virtual bool read(void* data, size_t size) = 0;
/**
* @brief Set size hint.
* @param [in] hint size hint.
* */
virtual void setSizeHint(size_t hint) { ((void)hint); }
virtual ~IArchive() = default;
};
/**
* @brief Serializable object interface.
* @details Provides common functions for all serializable objects.
* */
struct ISerializableObject : IRefCounted {
/**
* @brief Serialization nerror codes.
* */
enum class Error : uint32_t {
Ok, //!< Ok
Size, //!< Not enough space
Signature, //!< Invalid signature
ArchiveRead, //!< Error during archive reading,
InputArchive, //!< Input archive is nullptr
ArchiveWrite, //!< Error during archive writing,
};
/**
* @brief Serialization flags.
* @details These flags control advanced options and should not be set to anything else from Default in
* normal conditions.
* @note The same set of flags should be specified for both save() and load().
* */
enum Flags {
/** @brief Default serialization mode. */
Default = 0,
/**
* @brief Omit object signature.
* @details Helps to save space if there are several objects of the same type coming in a stream or
* where type is known for sure.
* @note This effectively disables signature check on loading. This may cause undefined results in
* case of mismatched input data.
* */
NoSignature = 1
};
/**
* @brief Estimate size of this object binary data.
* @param [inout] sizer sizer object to append result to.
* @param [in] flags [optional] serialization flags @see Flags.
* */
virtual void getSize(Sizer& sizer, uint32_t flags = Default) const noexcept = 0;
/**
* @brief Load object from archive.
* @param [in] archive archive to read from.
* @param [in] flags [optional] serialization flags @see Flags.
* @return Result with error code specified by ISerializableObject::SerializationError.
* @note This method pass exceptions from user defined IArchive, but doesnt throw its own
* @see Result and ISerializableObject::SerializationError.
* */
virtual Result<Error> load(IArchive* archive, uint32_t flags = Default) = 0;
/**
* @brief Save object to archive.
* @param [in] archive archive to write to.
* @param [in] flags [optional] serialization flags @see Flags.
* @return Result with error code specified by ISerializableObject::SerializationError.
* @note This method pass exceptions from user defined IArchive, but doesnt throw its own
* @see Result and ISerializableObject::SerializationError.
* */
virtual Result<Error> save(IArchive* archive, uint32_t flags = Default) const = 0;
};
/**
* @brief Specialized for ISerializableObject::SerializationError.
* */
template<>
struct ErrorTraits<ISerializableObject::Error> {
static bool isOk(ISerializableObject::Error error) noexcept {
return error == ISerializableObject::Error::Ok;
}
static const char* toString (ISerializableObject::Error error) noexcept {
switch(error) {
case ISerializableObject::Error::Ok : return "Ok";
case ISerializableObject::Error::Size: return "Size error";
case ISerializableObject::Error::Signature: return "Signature error";
case ISerializableObject::Error::ArchiveRead: return "Error during archive reading";
case ISerializableObject::Error::InputArchive: return "Input archive is nullptr";
case ISerializableObject::Error::ArchiveWrite: return "Error during archive writing";
default: return "Unknown error";
}
}
};
/**
* @brief Data storage object interface helper.
* */
struct IDataStorageObject : ISerializableObject {
/**
* @brief Clear object data.
* @note This does not necessarily mean deallocation; it is defined by implementation how to manage
* data memory.
* */
virtual void clear() noexcept = 0;
/**
* @brief Get parent object (one that has created this).
* @note Any returned interfaces will have their reference count incremented by one, so be sure to
* call release() on the returned pointer(s) before they are freed or else you will have a memory
* leak.
* @return pointer to the parent object.
* */
virtual IRefCounted* getParentObject() const noexcept = 0;
};
/** @} */
}