doc: add documentation

- add documentation for CKGlobals, VxMath (partly)
- Fix build issue in CKDefines, CKGlobals, VxMath.
- Bring libcmo exception in CKGlobals and VxMath for some illegal input.
This commit is contained in:
yyc12345 2024-08-21 17:57:35 +08:00
parent f7708c28e0
commit a7c1028926
7 changed files with 261 additions and 144 deletions

View File

@ -50,7 +50,7 @@ namespace LibCmo::CK2 {
/** /**
* @brief The identifier of Virtools file. * @brief The identifier of Virtools file.
*/ */
constexpr const CKCHAR CKNEMOFI[] = "Nemo Fi"; constexpr const CKCHAR CKNEMOFI[] = u8"Nemo Fi";
/** /**
* @brief Current Version of CK Engine (Day/Month/Year) * @brief Current Version of CK Engine (Day/Month/Year)
*/ */

View File

@ -23,41 +23,56 @@
namespace LibCmo::CK2 { namespace LibCmo::CK2 {
#pragma region Compression utilities #pragma region Compression Utilities
void* CKPackData(const void* Data, CKDWORD size, CKDWORD& NewSize, CKINT compressionlevel) { void* CKPackData(const void* Data, CKDWORD size, CKDWORD& NewSize, CKINT compressionlevel) {
uLong boundary = compressBound(static_cast<uLong>(size)); // check argument
CKBYTE* DestBuffer = new CKBYTE[boundary]; if (Data == nullptr && size != 0u)
throw LogicException("Data passed in CKPackData should not be nullptr.");
// get boundary and allocate buffer.
uLong boundary = compressBound(static_cast<uLong>(size));
std::unique_ptr<CKBYTE[]> DestBuffer(new CKBYTE[boundary]);
// do compress
uLongf _destLen = static_cast<uLongf>(boundary); uLongf _destLen = static_cast<uLongf>(boundary);
if (compress2( if (compress2(
reinterpret_cast<Bytef*>(DestBuffer), &_destLen, reinterpret_cast<Bytef*>(DestBuffer.get()), &_destLen,
static_cast<const Bytef*>(Data), static_cast<uLong>(size), static_cast<const Bytef*>(Data), static_cast<uLong>(size),
static_cast<int>(compressionlevel)) != Z_OK) { static_cast<int>(compressionlevel)) != Z_OK) {
NewSize = 0; // failed
delete[] DestBuffer; NewSize = 0u;
return nullptr; return nullptr;
} }
NewSize = static_cast<CKDWORD>(_destLen); NewSize = static_cast<CKDWORD>(_destLen);
return DestBuffer; return DestBuffer.release();
} }
void* CKUnPackData(CKDWORD DestSize, const void* SrcBuffer, CKDWORD SrcSize) { void* CKUnPackData(CKDWORD DestSize, const void* SrcBuffer, CKDWORD SrcSize) {
CKBYTE* DestBuffer = new CKBYTE[DestSize]; // check argument
if (SrcBuffer == nullptr && SrcSize != 0u)
throw LogicException("Data passed in CKUnPackData should not be nullptr.");
// allocate buffer
std::unique_ptr<CKBYTE[]> DestBuffer(new CKBYTE[DestSize]);
uLongf cache = DestSize; uLongf cache = DestSize;
if (uncompress( if (uncompress(
reinterpret_cast<Bytef*>(DestBuffer), &cache, reinterpret_cast<Bytef*>(DestBuffer.get()), &cache,
static_cast<const Bytef*>(SrcBuffer), static_cast<uLong>(SrcSize)) != Z_OK) { static_cast<const Bytef*>(SrcBuffer), static_cast<uLong>(SrcSize)) != Z_OK) {
delete[] DestBuffer;
return nullptr; return nullptr;
} }
return DestBuffer; return DestBuffer.release();
} }
CKDWORD CKComputeDataCRC(const void* data, CKDWORD size, CKDWORD PreviousCRC) { CKDWORD CKComputeDataCRC(const void* data, CKDWORD size, CKDWORD PreviousCRC) {
// check argument
if (data == nullptr && size != 0u)
throw LogicException("Data passed in CKComputeDataCRC should not be nullptr.");
// compute
return static_cast<CKDWORD>(adler32( return static_cast<CKDWORD>(adler32(
static_cast<uLong>(PreviousCRC), static_cast<uLong>(PreviousCRC),
static_cast<const Bytef*>(data), static_cast<const Bytef*>(data),
@ -69,41 +84,38 @@ namespace LibCmo::CK2 {
#pragma region String Utilities #pragma region String Utilities
bool CKStrEqual(CKSTRING str1, CKSTRING str2) { template<bool bCaseSenstive>
static bool InternalStrEqual(CKSTRING str1, CKSTRING str2) {
if (str1 == nullptr) { if (str1 == nullptr) {
if (str2 == nullptr) return true; if (str2 == nullptr) return true;
else return false; else return false;
} else { } else {
if (str2 == nullptr) return false; if (str2 == nullptr) return false;
else { else {
return std::strcmp( // do real compare
YYCC::EncodingHelper::ToOrdinary(str1), while (*str1 != u8'\0' && *str2 != u8'\0') {
YYCC::EncodingHelper::ToOrdinary(str2) // compare char
) == 0; if constexpr (bCaseSenstive) {
} if (*str1 != *str2) return false;
}
}
bool CKStrEqualI(CKSTRING str1, CKSTRING str2) {
if (str1 == nullptr) {
if (str2 == nullptr) return true;
else return false;
} else { } else {
if (str2 == nullptr) return false; if (std::tolower(*str1) != std::tolower(*str2)) return false;
else { }
// do real cmp // inc step
size_t i = 0;
while (str1[i] != u8'\0' && str2[i] != u8'\0') {
if (std::tolower(str1[i]) != std::tolower(str2[i])) return false;
++str1; ++str1;
++str2; ++str2;
} }
// !XOR the result, if both of them is zero, return true(1) // if both of them is zero, return true, otherwise false.
return !((str1[i] != u8'\0') ^ (str2[i] != u8'\0')); return *str1 == u8'\0' && *str2 == u8'\0';
} }
} }
} }
bool CKStrEqual(CKSTRING str1, CKSTRING str2) {
InternalStrEqual<true>(str1, str2);
}
bool CKStrEqualI(CKSTRING str1, CKSTRING str2) {
InternalStrEqual<false>(str1, str2);
}
bool CKStrEmpty(CKSTRING strl) { bool CKStrEmpty(CKSTRING strl) {
if (strl == nullptr) return true; if (strl == nullptr) return true;
@ -125,7 +137,8 @@ namespace LibCmo::CK2 {
void CKClassNeedNotificationFrom(CK_CLASSID listener, CK_CLASSID listenTo) { void CKClassNeedNotificationFrom(CK_CLASSID listener, CK_CLASSID listenTo) {
size_t idxListener, idxListenTo; size_t idxListener, idxListenTo;
if (!GetClassIdIndex(listener, idxListener) || !GetClassIdIndex(listenTo, idxListenTo)) return; if (!GetClassIdIndex(listener, idxListener) || !GetClassIdIndex(listenTo, idxListenTo))
throw LogicException("Invalid CK_CLASSID in argument.");
XContainer::NSXBitArray::Set(g_CKClassInfo[idxListener].ToBeNotify, static_cast<CKDWORD>(idxListenTo)); XContainer::NSXBitArray::Set(g_CKClassInfo[idxListener].ToBeNotify, static_cast<CKDWORD>(idxListenTo));
} }
@ -170,25 +183,25 @@ namespace LibCmo::CK2 {
const CKClassDesc* CKGetClassDesc(CK_CLASSID cid) { const CKClassDesc* CKGetClassDesc(CK_CLASSID cid) {
size_t intcid; size_t intcid;
if (!GetClassIdIndex(cid, intcid)) return nullptr; if (!GetClassIdIndex(cid, intcid))
throw LogicException("Invalid CK_CLASSID.");
return &g_CKClassInfo[intcid]; return &g_CKClassInfo[intcid];
} }
CKSTRING CKClassIDToString(CK_CLASSID cid) { CKSTRING CKClassIDToString(CK_CLASSID cid) {
const CKClassDesc* desc = CKGetClassDesc(cid); const CKClassDesc* desc = CKGetClassDesc(cid);
if (desc == nullptr) return u8"Undefined Type"; return desc->NameFct();
else return desc->NameFct();
} }
bool CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent) { bool CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent) {
size_t intchild, intparent; size_t intchild, intparent;
if (!GetClassIdIndex(child, intchild) || !GetClassIdIndex(parent, intparent)) return false; if (!GetClassIdIndex(child, intchild) || !GetClassIdIndex(parent, intparent))
throw LogicException("Invalid CK_CLASSID.");
return g_CKClassInfo[intchild].Parents[intparent]; return g_CKClassInfo[intchild].Parents[intparent];
} }
CK_CLASSID CKGetParentClassID(CK_CLASSID child) { CK_CLASSID CKGetParentClassID(CK_CLASSID child) {
const CKClassDesc* desc = CKGetClassDesc(child); const CKClassDesc* desc = CKGetClassDesc(child);
if (desc == nullptr) return CK_CLASSID::CKCID_OBJECT;
return desc->Parent; return desc->Parent;
} }
@ -207,7 +220,6 @@ namespace LibCmo::CK2 {
bool CKIsNeedNotify(CK_CLASSID listener, CK_CLASSID deletedObjCid) { bool CKIsNeedNotify(CK_CLASSID listener, CK_CLASSID deletedObjCid) {
const CKClassDesc* desc = CKGetClassDesc(listener); const CKClassDesc* desc = CKGetClassDesc(listener);
if (desc == nullptr) return false;
return XContainer::NSXBitArray::IsSet(desc->CommonToBeNotify, static_cast<CKDWORD>(deletedObjCid)); return XContainer::NSXBitArray::IsSet(desc->CommonToBeNotify, static_cast<CKDWORD>(deletedObjCid));
} }
@ -218,8 +230,6 @@ namespace LibCmo::CK2 {
if (!XContainer::NSXBitArray::IsSet(delObjCids, static_cast<CKDWORD>(i))) continue; if (!XContainer::NSXBitArray::IsSet(delObjCids, static_cast<CKDWORD>(i))) continue;
const CKClassDesc* desc = CKGetClassDesc(static_cast<CK_CLASSID>(i)); const CKClassDesc* desc = CKGetClassDesc(static_cast<CK_CLASSID>(i));
if (desc == nullptr) continue;
XContainer::NSXBitArray::Or(result, desc->ToNotify); XContainer::NSXBitArray::Or(result, desc->ToNotify);
} }
@ -236,7 +246,7 @@ namespace LibCmo::CK2 {
This relation is represented in ToBeNotify, a pure relation without any inhertance hierarchy. This relation is represented in ToBeNotify, a pure relation without any inhertance hierarchy.
Ok, now we assume A have children AA, B also have children BB. Ok, now we assume A have children AA, B also have children BB.
Because B is a businessman, so his children BB also is a bussinessman. Because B is a businessman, so his children BB also is a businessman.
B and BB have the same goods so A can buy his stuff from both of B and BB. B and BB have the same goods so A can buy his stuff from both of B and BB.
This is the first step executed by ComputeParentsNotifyTable(). This is the first step executed by ComputeParentsNotifyTable().
In this step, the function expand existing business relations to all possible business relations (expand to businessman's children) In this step, the function expand existing business relations to all possible business relations (expand to businessman's children)
@ -429,7 +439,7 @@ CKClassRegister(cid, parentCid, \
} }
CKERROR CKShutdown() { CKERROR CKShutdown() {
// free class indo // free class infos
g_CKClassInfo.clear(); g_CKClassInfo.clear();
return CKERROR::CKERR_OK; return CKERROR::CKERR_OK;

View File

@ -3,6 +3,7 @@
#include "CKTypes.hpp" #include "CKTypes.hpp"
#include "../XContainer/XTypes.hpp" #include "../XContainer/XTypes.hpp"
#include <functional> #include <functional>
#include <memory>
namespace LibCmo::CK2 { namespace LibCmo::CK2 {
@ -10,87 +11,106 @@ namespace LibCmo::CK2 {
/** /**
* @brief Compress a buffer * @brief Compress a buffer
* @param[in] Data A pointer to the buffer to coompress * @param[in] Data A pointer to the buffer to compress. nullptr is not allowed.
* @param[in] size Size of the source buffer. * @param[in] size Size of the source buffer.
* @param[out] NewSize A reference that will be filled with the size of the compressed buffer. 0 if failed. * @param[out] NewSize A reference that will be filled with the size of the compressed buffer. 0 if failed.
* @param[in] compressionlevel 0-9 * @param[in] compressionlevel 0-9 Greater level smaller result size.
* @return * @return
* A pointer to the compressed buffer. nullptr if failed. * A pointer to the compressed buffer. nullptr if failed.
* The return pointer should be freed by `delete[]` manually. * The return pointer should be freed by \c delete[] manually.
* @remark * @remarks
* The size of allocated return value may greater than the passed value of NewSize. * The size of allocated return value may greater than the passed value of NewSize.
* NewSize only indicate the size of the part storing useful data in return value. * NewSize only indicate the size of the part storing useful data in return value.
* @see CKUnPackData, CKComputeDataCRC * @exception LogicException Raised if given buffer is nullptr and size is not equal to zero.
* @see CKUnPackData(), CKComputeDataCRC()
*/ */
void* CKPackData(const void* Data, CKDWORD size, CKDWORD& NewSize, CKINT compressionlevel); void* CKPackData(const void* Data, CKDWORD size, CKDWORD& NewSize, CKINT compressionlevel);
/** /**
* @brief Decompress a buffer * @brief Decompress a buffer
* @param[in] DestSize Expected size of the decompressed buffer. * @param[in] DestSize Expected size of the decompressed buffer.
* @param[in] SrcBuffer Compressed buffer. * @param[in] SrcBuffer Compressed buffer. nullptr is not allowed.
* @param[in] SrcSize Size of the compressed buffer. * @param[in] SrcSize Size of the compressed buffer.
* @return * @return
* A pointer to the decompressed buffer or nullptr if there was a error. * A pointer to the decompressed buffer or nullptr if there was a error.
* The return pointer should be freed by `delete[]` manually. * The return pointer should be freed by \c delete[] manually.
* @see CKPackData, CKComputeDataCRC * @exception LogicException Raised if given buffer is nullptr and size is not equal to zero.
* @see CKPackData(), CKComputeDataCRC()
*/ */
void* CKUnPackData(CKDWORD DestSize, const void* SrcBuffer, CKDWORD SrcSize); void* CKUnPackData(CKDWORD DestSize, const void* SrcBuffer, CKDWORD SrcSize);
/** /**
* @brief Computes a CRC for a buffer. * @brief Computes a CRC for a buffer.
* @param[in] data A pointer to the buffer to create a CRC for. * @param[in] data A pointer to the buffer to create a CRC for. nullptr is not allowed.
* @param[in] size Size of the source buffer. * @param[in] size Size of the source buffer.
* @param[in] PreviousCRC * @param[in] PreviousCRC
* The first time a CRC is computed this value should be 0, * The first time a CRC is computed this value should be 0,
* but it can be use to compute a single CRC for a several buffers * but it can be use to compute a single CRC for a several buffers
* by using the currently computed CRC for previous buffers in this value. * by using the currently computed CRC for previous buffers in this value.
* @return CRC of the buffer. * @return CRC of the buffer.
* @see CKPackData, CKUnPackData * @exception LogicException Raised if given buffer is nullptr and size is not equal to zero.
* @see CKPackData(), CKUnPackData()
*/ */
CKDWORD CKComputeDataCRC(const void* data, CKDWORD size, CKDWORD PreviousCRC = 0); CKDWORD CKComputeDataCRC(const void* data, CKDWORD size, CKDWORD PreviousCRC = 0);
// ========== String Utilities ========== // ========== String Utilities ==========
/** /**
* @brief Check whether 2 string is equal. Case senstive. * @brief Check whether two string is equal. Case senstive.
* @param str1[in] String 1 * @param[in] str1 First string. nullptr is allowed but not suggested.
* @param str2[in] String 2 * @param[in] str2 Second string. nullptr is allowed but not suggested.
* @return True if 2 string is equal. * @return True if two string is equal, otherwise false.
* @see CKStrIEqual * @remarks
* nullptr string is not equal to any other string.
* However two nullptr string is equal.
* @see CKStrEqualI()
*/ */
bool CKStrEqual(CKSTRING str1, CKSTRING str2); bool CKStrEqual(CKSTRING str1, CKSTRING str2);
/** /**
* @brief Check whther 2 string is equal. Case insenstive. * @brief Check whther two string is equal. Case insenstive.
* @param str1 * @param[in] str1 First string. nullptr is allowed but not suggested.
* @param str2 * @param[in] str2 Second string. nullptr is allowed but not suggested.
* @return True if 2 string is equal. * @return True if two string is equal, otherwise false.
* @see CKStrEqual * @remarks
* nullptr string is not equal to any other string.
* However two nullptr string is equal.
* @see CKStrEqual()
*/ */
bool CKStrEqualI(CKSTRING str1, CKSTRING str2); bool CKStrEqualI(CKSTRING str1, CKSTRING str2);
/** /**
* @brief Check whether string is empty * @brief Check whether string is empty
* @param strl * @param[in] strl String for checking. nullptr is allowed but not suggested.
* @return True if string is empty. * @return True if string is empty, otherwise false.
* @remarks nullptr string is seen as empty string.
*/ */
bool CKStrEmpty(CKSTRING strl); bool CKStrEmpty(CKSTRING strl);
// ========== Class registration utilities ========== // ========== Class registration utilities ==========
/// @brief Function pointer which do extra stuff when registry this class.
using CKClassRegisterFct = std::function<void()>; using CKClassRegisterFct = std::function<void()>;
/// @brief Function pointer which create ObjImpls::CKObject pointer by given CKContext, CK_ID and name.
using CKClassCreationFct = std::function<ObjImpls::CKObject* (CKContext*, CK_ID, CKSTRING)>; using CKClassCreationFct = std::function<ObjImpls::CKObject* (CKContext*, CK_ID, CKSTRING)>;
/// @brief Function pointer which free given ObjImpls::CKObject pointer.
using CKClassReleaseFct = std::function<void(CKContext*, ObjImpls::CKObject*)>; using CKClassReleaseFct = std::function<void(CKContext*, ObjImpls::CKObject*)>;
/// @brief Function pointer which return the name of class.
using CKClassNameFct = std::function<CKSTRING()>; using CKClassNameFct = std::function<CKSTRING()>;
//using CKClassDependenciesFct = std::function<CKSTRING(CKINT, CKINT)>; //using CKClassDependenciesFct = std::function<CKSTRING(CKINT, CKINT)>;
//using CKClassDependenciesCountFct = std::function<CKINT(CKINT)>; //using CKClassDependenciesCountFct = std::function<CKINT(CKINT)>;
/**
* @brief The representation of a registered class.
*/
struct CKClassDesc { struct CKClassDesc {
// Variables used when building class hierarchy table
bool IsValid; /**< True if this CKClassDesc is a valid one. Because CK_CLASSID may not be consecutive. */ bool IsValid; /**< True if this CKClassDesc is a valid one. Because CK_CLASSID may not be consecutive. */
bool Done; bool Done; /**< Temporary variable indicating this item has been processed when creating table. */
// Initialized upon class registration
CK_CLASSID Self; // Variables initialized upon class registration
CK_CLASSID Parent; // Class Identifier of parent class CK_CLASSID Self; /**< Class identifier of self */
CKClassRegisterFct RegisterFct; // Pointer to Class Specific Registration function CK_CLASSID Parent; /**< Class identifier of parent class */
CKClassCreationFct CreationFct; // Pointer to Class instance creation function CKClassRegisterFct RegisterFct; /**< Function pointer which do extra stuff when registry this class. */
CKClassReleaseFct ReleaseFct; // Pointer to Class instance release function CKClassCreationFct CreationFct; /**< Function pointer which create ObjImpls::CKObject pointer by given CKContext, CK_ID and name. */
CKClassNameFct NameFct; // Pointer to Class name function CKClassReleaseFct ReleaseFct; /**< Function pointer which free given ObjImpls::CKObject pointer. */
CKClassNameFct NameFct; /**< Function pointer which return the name of class. */
//CKClassDependenciesFct DependsFct; // Pointer to Class dependencies function (Copy,delete,replace...) //CKClassDependenciesFct DependsFct; // Pointer to Class dependencies function (Copy,delete,replace...)
//CKClassDependenciesCountFct DependsCountFct; // Pointer to Class dependencies Count function (Copy,delete,replace...) //CKClassDependenciesCountFct DependsCountFct; // Pointer to Class dependencies Count function (Copy,delete,replace...)
@ -102,13 +122,13 @@ namespace LibCmo::CK2 {
//CKDWORD DefaultSaveDependencies; //CKDWORD DefaultSaveDependencies;
//CKGUID Parameter; // Associated parameter GUID //CKGUID Parameter; // Associated parameter GUID
// Initialized when building class hierarchy table // Variables initialized after building class hierarchy table
CKINT DerivationLevel; // O => CKObject , etc.. CKINT DerivationLevel; /**< How many parent level it has. 0 for CKObject, etc.. */
XContainer::XBitArray Parents; // Bit Mask of parents classes XContainer::XBitArray Parents; /**< Bit Mask of parents classes */
XContainer::XBitArray Children; // Bit Mask of children classes XContainer::XBitArray Children; /**< Bit Mask of children classes */
XContainer::XBitArray ToBeNotify; // User specified notify list, only for current class. If any deleted objects match class id in this XBitArray, notify the host of this XBitArray. XContainer::XBitArray ToBeNotify; /**< User specified notify list, only for current class. If any deleted objects match class id in this XBitArray, notify the host of this XBitArray. */
XContainer::XBitArray CommonToBeNotify; // Same as ToBeNotify, but merging all parents' notify list. XContainer::XBitArray CommonToBeNotify; /**< Same as ToBeNotify, but merging all parents' notify list. */
XContainer::XBitArray ToNotify; // The ClassID to notify when an object of this class is deleted (inverse of ToBeNotify) XContainer::XBitArray ToNotify; /**< The ClassID to notify when an object of this class is deleted (inverse of ToBeNotify) */
CKClassDesc() : CKClassDesc() :
IsValid(false), IsValid(false),
@ -123,39 +143,111 @@ namespace LibCmo::CK2 {
// ========== CKClass Registration ========== // ========== CKClass Registration ==========
/**
* @brief Order that first class id will be notified when deleting object whose class id is second argument
* @param[in] listener The id of class will be notified.
* @param[in] listenTo The id of class which first argument interested in.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
void CKClassNeedNotificationFrom(CK_CLASSID listener, CK_CLASSID listenTo); void CKClassNeedNotificationFrom(CK_CLASSID listener, CK_CLASSID listenTo);
/**
* @brief Get an usable class id for registration.
* @details This function is usually used by plugin to registering classes.
* Because all embedded Virtools classes has constant class id.
* @return An usable class id for registration.
*/
CK_CLASSID CKClassGetNewIdentifier(); CK_CLASSID CKClassGetNewIdentifier();
/**
* @brief Register a new class.
* @param[in] cid The id of this class.
* @param[in] parentCid The id of parent class.
* @param[in] regFct Pointer to class specific registration function which do extra stuff when registry this class.
* @param[in] createFct Pointer to class instance creation function
* @param[in] relFct Pointer to class instance release function
* @param[in] nameFct Pointer to class name function
*/
void CKClassRegister(CK_CLASSID cid, CK_CLASSID parentCid, void CKClassRegister(CK_CLASSID cid, CK_CLASSID parentCid,
CKClassRegisterFct regFct, CKClassCreationFct createFct, CKClassReleaseFct relFct, CKClassNameFct nameFct); CKClassRegisterFct regFct, CKClassCreationFct createFct, CKClassReleaseFct relFct, CKClassNameFct nameFct);
// ========== Class Hierarchy Management ========== // ========== Class Hierarchy Management ==========
/**
* @brief Get total count of registered classes.
* @return The total count of registered classes.
*/
CKDWORD CKGetClassCount(); CKDWORD CKGetClassCount();
/**
* @brief Get the class description struct by given class id.
* @param[in] cid Class id for fetching.
* @return The pointer to corresponding class description.
* We guaranteen that this pointer must not be nullptr.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
const CKClassDesc* CKGetClassDesc(CK_CLASSID cid); const CKClassDesc* CKGetClassDesc(CK_CLASSID cid);
/**
* @brief Get the name representation of given class id.
* @param[in] cid Class id for fetching.
* @return The name of given class id.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
CKSTRING CKClassIDToString(CK_CLASSID cid); CKSTRING CKClassIDToString(CK_CLASSID cid);
/**
* @brief Check whether first class is second class' child class.
* @param[in] child The id of first class assumed as child class.
* @param[in] parent The id of second class assumed as parent class.
* @return True if relation is satisfied, otherwise false.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
bool CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent); bool CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent);
/**
* @brief Get the parent class id of given class id.
* @param[in] child The id to class which need to find parent class.
* @return The parent class id.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
CK_CLASSID CKGetParentClassID(CK_CLASSID child); CK_CLASSID CKGetParentClassID(CK_CLASSID child);
/**
* @brief Get the cloest common parent of given two classes.
* @param[in] cid1 The id of first class finding common parent.
* @param[in] cid2 The id of second class finding common parent.
* @return The cloest common parent class id.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/
CK_CLASSID CKGetCommonParent(CK_CLASSID cid1, CK_CLASSID cid2); CK_CLASSID CKGetCommonParent(CK_CLASSID cid1, CK_CLASSID cid2);
/** /**
* @brief Check whether 'listener' need notified by the deletion of 'deletedObjCid' * @brief Check whether object whose class id is first argument, need to be notified when the objects whose class id is second argument, is deleting.
* @param listener * @param[in] listener The class id of checking whether need to be notified.
* @param deletedObjCid * @param[in] deletedObjCid The class id of deleting object.
* @return true if need notify * @return True if it need to be notified, otherwise false.
* @exception LogicException Raised if given CK_CLASSID is invalid.
*/ */
bool CKIsNeedNotify(CK_CLASSID listener, CK_CLASSID deletedObjCid); bool CKIsNeedNotify(CK_CLASSID listener, CK_CLASSID deletedObjCid); /**
/** /**
* @brief Get all object cid need to be notified when 'delObjCids' matched objects are deleting. * @brief Get all class ids need to be notified when objects whose class id included in \c delObjCids are deleting.
* @param delObjCids * @param[in] delObjCids The bit array representing class ids which need to be queried.
* @param cidCount * @return The queried bit array representing class ids need to be notified.
* @return * @exception LogicException Raised if given CK_CLASSID is invalid.
* @see CKIsNeedNotify()
*/ */
XContainer::XBitArray CKGetAllNotifyClassID(const XContainer::XBitArray& delObjCids); XContainer::XBitArray CKGetAllNotifyClassID(const XContainer::XBitArray& delObjCids);
// ========== Initializations functions ========== // ========== Initializations Functions ==========
/**
* @brief Initialize CK engine.
* @details You must call this function before anything.
* @return Error code about initializing.
* @see CKShutdown()
*/
CKERROR CKStartUp(); CKERROR CKStartUp();
/**
* @brief Shutdown CK engine.
* @details You must call this function after you have done all things.
* @return Error code about shutdown.
* @see CKStartUp()
*/
CKERROR CKShutdown(); CKERROR CKShutdown();
} }

View File

@ -20,7 +20,6 @@ namespace LibCmo::CK2::MgrImpls {
// get description first // get description first
const CKClassDesc* desc = CKGetClassDesc(cls); const CKClassDesc* desc = CKGetClassDesc(cls);
if (desc == nullptr) return nullptr;
// allocate a CK_ID first // allocate a CK_ID first
CKDWORD decided_off; CKDWORD decided_off;
@ -60,12 +59,7 @@ namespace LibCmo::CK2::MgrImpls {
void CKObjectManager::InternalDestroy(ObjImpls::CKObject* obj) { void CKObjectManager::InternalDestroy(ObjImpls::CKObject* obj) {
// find desc by classid // find desc by classid
// if really we can not find it, we only can delete it directly.
const CKClassDesc* desc = CKGetClassDesc(obj->GetClassID()); const CKClassDesc* desc = CKGetClassDesc(obj->GetClassID());
if (desc == nullptr) {
delete obj;
return;
}
// free it // free it
desc->ReleaseFct(m_Context, obj); desc->ReleaseFct(m_Context, obj);

View File

@ -97,7 +97,7 @@ namespace LibCmo {
/** /**
* @brief Reverse given enum flags like performing <TT>~(e)</TT> * @brief Reverse given enum flags like performing <TT>~(e)</TT>
* @tparam TEnum Enum type for processing. * @tparam TEnum Enum type for processing.
* @param[in] il The list of enum flags to be inversed. * @param[in] e The list of enum flags to be inversed.
* @return The inversed enum flag. * @return The inversed enum flag.
*/ */
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0> template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>

View File

@ -11,7 +11,8 @@ namespace LibCmo::VxMath {
} }
void VxCopyStructure(CKDWORD Count, void* Dst, CKDWORD OutStride, CKDWORD SizeSrc, const void* Src, CKDWORD InStride) { void VxCopyStructure(CKDWORD Count, void* Dst, CKDWORD OutStride, CKDWORD SizeSrc, const void* Src, CKDWORD InStride) {
if (Dst == nullptr || Src == nullptr) return; if ((Dst == nullptr || Src == nullptr) && Count != 0u)
throw LogicException("Source or destination buffer should not be nullptr.");
CKBYTE* cdst = static_cast<CKBYTE*>(Dst); CKBYTE* cdst = static_cast<CKBYTE*>(Dst);
const CKBYTE* csrc = static_cast<const CKBYTE*>(Src); const CKBYTE* csrc = static_cast<const CKBYTE*>(Src);
@ -27,8 +28,10 @@ namespace LibCmo::VxMath {
#pragma region Graphic Utilities #pragma region Graphic Utilities
void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst) { void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst) {
if (dst == nullptr || origin == nullptr) return; if (dst == nullptr || origin == nullptr)
if (!dst->IsValid() || !origin->IsValid()) return; throw LogicException("VxImageDescEx* should not be nullptr.");
if (!dst->IsValid() || !origin->IsValid())
throw LogicException("VxImageDescEx* should not be invalid.");
// if have same size, directly copy it // if have same size, directly copy it
if (dst->IsHWEqual(*origin)) { if (dst->IsHWEqual(*origin)) {
@ -48,8 +51,10 @@ namespace LibCmo::VxMath {
} }
void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst) { void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst) {
if (dst == nullptr || origin == nullptr) return; if (dst == nullptr || origin == nullptr)
if (!dst->IsValid() || !origin->IsValid()) return; throw LogicException("VxImageDescEx* should not be nullptr.");
if (!dst->IsValid() || !origin->IsValid())
throw LogicException("VxImageDescEx* should not be invalid.");
// if size is not matched, return // if size is not matched, return
if (!dst->IsHWEqual(*origin)) { if (!dst->IsHWEqual(*origin)) {
@ -99,7 +104,8 @@ namespace LibCmo::VxMath {
//} //}
void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE AlphaValue) { void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE AlphaValue) {
if (dst_desc == nullptr) return; if (dst_desc == nullptr || !dst_desc->IsValid())
throw LogicException("VxImageDescEx* should not be nullptr or invalid.");
CKDWORD* pixels = dst_desc->GetMutablePixels(); CKDWORD* pixels = dst_desc->GetMutablePixels();
CKDWORD pixelcount = dst_desc->GetPixelCount(); CKDWORD pixelcount = dst_desc->GetPixelCount();
@ -111,7 +117,10 @@ namespace LibCmo::VxMath {
} }
void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues) { void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues) {
if (dst_desc == nullptr) return; if (dst_desc == nullptr || !dst_desc->IsValid() || AlphaValues == nullptr)
throw LogicException("VxImageDescEx* should not be nullptr or invalid.");
if (AlphaValues == nullptr)
throw LogicException("Alpha channel buffer should not be nullptr.");
CKDWORD* pixels = dst_desc->GetMutablePixels(); CKDWORD* pixels = dst_desc->GetMutablePixels();
CKDWORD pixelcount = dst_desc->GetPixelCount(); CKDWORD pixelcount = dst_desc->GetPixelCount();

View File

@ -7,23 +7,27 @@ namespace LibCmo::VxMath {
/** /**
* @brief Fills a memory buffer with a source buffer pattern. * @brief Fills a memory buffer with a source buffer pattern.
* @param Count[in] Number of element to set in the destination buffer * @details This function can be used to initialized an array of structure when only some members should be modified.
* @param Dst[out] Destination buffer * @param[in] Count Number of element to set in the destination buffer
* @param Stride[in] Amount in bytes between each element in the destination buffer * @param[out] Dst Destination buffer
* @param SizeSrc[in] Size in bytes of an element int the Src buffer * @param[in] Stride Amount in bytes between each element in the destination buffer
* @param Src[in] Source buffer * @param[in] SizeSrc Size in bytes of an element int the Src buffer
* @remark This function can be used to initialized an array of structure when only some members should be modified. * @param[in] Src Source buffer
* @exception LogicException Raised if source or destination buffer is nullptr, and count is not zero.
* @remarks If given buffer is not sufficient to perform operations, it will cause undefined behavior.
*/ */
void VxFillStructure(CKDWORD Count, void* Dst, CKDWORD Stride, CKDWORD SizeSrc, const void* Src); void VxFillStructure(CKDWORD Count, void* Dst, CKDWORD Stride, CKDWORD SizeSrc, const void* Src);
/** /**
* @brief copies an array of elements between two memory buffers. * @brief copies an array of elements between two memory buffers.
* @param Count[in] Number of element to copy in the destination buffer * @details This function can be used to initialized an array of structure when only some members should be modified.
* @param Dst[out] Destination buffer * @param[in] Count Number of element to copy in the destination buffer
* @param OutStride[in] Amount in bytes between each element in the destination buffer * @param[out] Dst Destination buffer
* @param SizeSrc[in] Size in bytes of an element * @param[in] OutStride Amount in bytes between each element in the destination buffer
* @param Src[in] Source buffer. * @param[in] SizeSrc Size in bytes of an element
* @param InStride[in] Amount in bytes between each element in the source buffer * @param[in] Src Source buffer.
* @remark This function can be used to initialized an array of structure when only some members should be modified. * @param[in] InStride Amount in bytes between each element in the source buffer
* @exception LogicException Raised if source or destination buffer is nullptr, and count is not zero.
* @remarks If given buffer is not sufficient to perform operations, it will cause undefined behavior.
*/ */
void VxCopyStructure(CKDWORD Count, void* Dst, CKDWORD OutStride, CKDWORD SizeSrc, const void* Src, CKDWORD InStride); void VxCopyStructure(CKDWORD Count, void* Dst, CKDWORD OutStride, CKDWORD SizeSrc, const void* Src, CKDWORD InStride);
@ -31,55 +35,63 @@ namespace LibCmo::VxMath {
/** /**
* @brief Performs a blit between two images. This method can resize (shrink or grow) images. * @brief Performs a blit between two images. This method can resize (shrink or grow) images.
* @remark The source image must be in a 32 bit ARGB8888 per pixel format. * @param[out] dst The destination image.
* @param dest[out] The dest image. * @param[in] origin The origin image.
* @param origin[in] The origin image. * @remarks The source image must be in a 32 bit ARGB8888 per pixel format.
* @exception LogicException Raised if given image description is nullptr or invalid.
*/ */
void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst); void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst);
/** /**
* @brief Performs a blit between two images. This method can inverts the destination image. * @brief Performs a blit between two images. This method can inverts the destination image.
* @remark * @param[out] dst The destination image.
+ The source image must be in a 32 bit ARGB8888 per pixel format. * @param[in] origin The origin image.
+ This function usually used in the covertion between texture coordinate * @remarks
system and UV coordinate system. * \li The source image must be in a 32 bit ARGB8888 per pixel format.
* @param dest[out] The dest image. * \li This function usually used in the covertion between texture coordinate system and UV coordinate system.
* @param origin[in] The origin image. * @exception LogicException Raised if given image description is nullptr or invalid.
*/ */
void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst); void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst);
/** /**
* @brief Counts number of bits to representing a value in dwMask * @brief Get the total count of set(1) bit in given value.
* @param[in] dwMask The value for counting.
* @return The total count of set(1) bit.
*/ */
CKDWORD VxGetBitCount(CKDWORD dwMask); CKDWORD VxGetBitCount(CKDWORD dwMask);
/** /**
* @brief Counts number of bits to shift to acces a non zero value in dwMask. * @brief Get the offset in bit to first set(1) bit when performing right shift.
* @param[in] dwMask The value for fetching offset.
* @return The offset in bit to first set(1) bit.
* If there is no set(1) bit in given value, return 0 instead.
*/ */
CKDWORD VxGetBitShift(CKDWORD dwMask); CKDWORD VxGetBitShift(CKDWORD dwMask);
///** // /**
// * @brief scale the integer to a new range. // * @brief Scale the integer to a new range.
// * @param val The int need to be scale // * @param[in] val The int need to be scale
// * @param srcBitCount The bit count which source integer consumed. // * @param[in] srcBitCount The bit count which source integer consumed.
// * @param dstBitCount The bit count which dest integer consumed. // * @param[in] dstBitCount The bit count which dest integer consumed.
// * @remark This function usually used in image color factor assign with mask. // * @remarks This function usually used in image color factor assign with mask.
// * @return The result integer. // * @return The result integer.
//*/ //*/
//CKDWORD VxScaleFactor(CKDWORD val, CKDWORD srcBitCount, CKDWORD dstBitCount); //CKDWORD VxScaleFactor(CKDWORD val, CKDWORD srcBitCount, CKDWORD dstBitCount);
/** /**
* @brief Sets the alpha component of an image. * @brief Sets the alpha component of an image.
* @remark The source image must be in a 32 bit ARGB8888 per pixel format. * @param[in] dst_desc A pointer to a structure describing the destination image format.
* @param dst_desc[in] A pointer to a structure describing the destination image format. * @param[in] AlphaValue A CKBYTE value containing the alpha value to set to the whole image
* @param AlphaValue[in] A CKBYTE value containing the alpha value to set to the whole image * @remarks The source image must be in a 32 bit ARGB8888 per pixel format.
* @remark If the destination image does not have alpha information the function returns immediatly. * @exception LogicException Raised if given image description is nullptr or invalid.
*/ */
void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE AlphaValue); void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE AlphaValue);
/** /**
* @brief Sets the alpha component of an image. * @brief Sets the alpha component of an image.
* @remark The source image must be in a 32 bit ARGB8888 per pixel format. * @param[in] dst_desc A pointer to a structure describing the destination image format.
* @param dst_desc[in] A pointer to a structure describing the destination image format. * @param[in] AlphaValues A BYTE array containing the alpha values for each pixel. This array should be allocated to Width * Height bytes.
* @param AlphaValues[in] A BYTE array containing the alpha values for each pixel. This array should be allocated to Width*Height bytes. * @remarks
* @remark If the destination image does not have alpha information the function returns immediatly. * \li The source image must be in a 32 bit ARGB8888 per pixel format.
* \li If given alpha channel buffer do not have correct length, it will cause undefined behavior.
* @exception LogicException Raised if given image description or alpha channel buffer is nullptr or invalid.
*/ */
void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues); void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues);