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:
		@ -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)
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
				
			|||||||
@ -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>
 | 
				
			||||||
 | 
				
			|||||||
@ -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();
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user