finish CKMesh writer

- fix some writing issue.
- create a internal object adder in CKFileWriter shared by AddObject and Ctor(copy Reader).
This commit is contained in:
yyc12345 2023-10-02 09:16:45 +08:00
parent 92f4271124
commit 9aa8b2b961
4 changed files with 35 additions and 30 deletions

View File

@ -240,7 +240,27 @@ namespace LibCmo::CK2 {
CKERROR Save(CKSTRING u8_filename); CKERROR Save(CKSTRING u8_filename);
protected: protected:
bool m_Done; /**
* @brief A helper function to check whether given file can be written.
* @param filename[in] The name of file to be wriiten
* @return CKERROR::CK_OK if can write.
*/
CKERROR PrepareFile(CKSTRING filename);
/**
* @brief Internal used Object Adder.
*
* This function is used by AddSavedObject() and Copy from reader constructor.
* This function accept a object pointer, and try adding them.
* And set m_IncludedFiles and m_ObjectsHashTable properly.
*
* @param obj The pointer to added object.
* @param flags The flag used when saving this object.
* @return True if success.
*/
bool InternalObjectAdder(ObjImpls::CKObject* obj, CKDWORD flags = CK_STATESAVE_ALL);
protected:
bool m_Done; /**< True if this writer is already written into file. A written CKFileWriter can no be written again. */
/** /**
* @brief True if this writer is not allowed to add objects. * @brief True if this writer is not allowed to add objects.
* @remark * @remark
@ -269,8 +289,6 @@ namespace LibCmo::CK2 {
XContainer::XBitArray m_AlreadySavedMask; /**< Field recording saved object id. If this object is saved, set m_AlreadySavedMask[id] to true. Also used to check whether object already is in save list. */ XContainer::XBitArray m_AlreadySavedMask; /**< Field recording saved object id. If this object is saved, set m_AlreadySavedMask[id] to true. Also used to check whether object already is in save list. */
CKFileInfo m_FileInfo; /**< Headers summary */ CKFileInfo m_FileInfo; /**< Headers summary */
CKERROR PrepareFile(CKSTRING filename);
CKContext* m_Ctx; CKContext* m_Ctx;
CKFileVisitor m_Visitor; CKFileVisitor m_Visitor;
}; };

View File

@ -244,35 +244,17 @@ namespace LibCmo::CK2 {
#pragma region Deep Assign #pragma region Deep Assign
// copy object and calc max id // call internal object adder one by one
CK_ID maxid = 0;
for (const auto& item : reader->GetFileObjects()) { for (const auto& item : reader->GetFileObjects()) {
CKFileObject obj; CKFileObject obj;
// skip if invalid // skip if invalid
if (item.ObjPtr == nullptr) continue; if (item.ObjPtr == nullptr) continue;
// set obj ptr // try add
obj.ObjPtr = item.ObjPtr; InternalObjectAdder(item.ObjPtr);
// set other data
obj.ObjectId = obj.ObjPtr->GetID();
obj.ObjectCid = obj.ObjPtr->GetClassID();
obj.Data = nullptr; // blank statechunk
obj.SaveFlags = CK_STATESAVE_ALL;
XContainer::NSXString::FromCKSTRING(obj.Name, obj.ObjPtr->GetName());
// update max id
maxid = std::max(maxid, obj.ObjectId);
// insert
m_FileObjects.emplace_back(std::move(obj));
} }
// set max id
m_SaveIDMax = maxid;
#pragma endregion #pragma endregion
} }
@ -280,8 +262,7 @@ namespace LibCmo::CK2 {
CKFileWriter::~CKFileWriter() {} CKFileWriter::~CKFileWriter() {}
bool CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) { bool LibCmo::CK2::CKFileWriter::InternalObjectAdder(ObjImpls::CKObject * obj, CKDWORD flags) {
if (m_Done || m_DisableAddingObject) return false;
if (obj == nullptr) return false; if (obj == nullptr) return false;
// check whether is saved. // check whether is saved.
@ -306,11 +287,19 @@ namespace LibCmo::CK2 {
return true; return true;
} }
bool CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) {
if (m_Done || m_DisableAddingObject) return false;
// call internal adder
return InternalObjectAdder(obj, flags);
}
bool CKFileWriter::AddSavedObjects(const XContainer::XObjectPointerArray& objarray, CKDWORD flags) { bool CKFileWriter::AddSavedObjects(const XContainer::XObjectPointerArray& objarray, CKDWORD flags) {
if (m_Done || m_DisableAddingObject) return false; if (m_Done || m_DisableAddingObject) return false;
bool ret = true; bool ret = true;
for (auto obj : objarray) { for (auto obj : objarray) {
// call AddSavedObject one by one
if (!AddSavedObject(obj, flags)) { if (!AddSavedObject(obj, flags)) {
ret = false; ret = false;
} }

View File

@ -130,7 +130,7 @@ namespace LibCmo::CK2::ObjImpls {
CKBYTE* rawbuf = static_cast<CKBYTE*>(buf.get()); CKBYTE* rawbuf = static_cast<CKBYTE*>(buf.get());
// reserve length data // reserve length data
CKDWORD* reservedBufSize = reinterpret_cast<CKDWORD*>(rawbuf); CKDWORD* reservedBufDwordSize = reinterpret_cast<CKDWORD*>(rawbuf);
rawbuf += CKSizeof(CKDWORD); rawbuf += CKSizeof(CKDWORD);
// write vertex position // write vertex position
@ -188,7 +188,7 @@ namespace LibCmo::CK2::ObjImpls {
CKDWORD realConsumedSize = rawbuf - static_cast<CKBYTE*>(buf.get()); CKDWORD realConsumedSize = rawbuf - static_cast<CKBYTE*>(buf.get());
// assign to reserved length field // assign to reserved length field
// length also include length indicator it self // length also include length indicator it self
*reservedBufSize = realConsumedSize; *reservedBufDwordSize = realConsumedSize / CKSizeof(CKDWORD);
// notify buffer real consumed size // notify buffer real consumed size
buf.get_deleter().SetConsumedSize(realConsumedSize); buf.get_deleter().SetConsumedSize(realConsumedSize);

View File

@ -324,8 +324,6 @@ namespace Unvirt::StructFormatter {
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\tColors\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD)); fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\tColors\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
PrintPointer(obj->GetVertexSpecularColors()); PrintPointer(obj->GetVertexSpecularColors());
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\tSpecularColors\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD)); fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\tSpecularColors\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKDWORD));
PrintPointer(obj->GetVertexWeights());
fprintf(stdout, "\t0x%" PRIxCKDWORD " bytes\tWeights\n", obj->GetVertexCount() * CKSizeof(LibCmo::CKFLOAT));
// face data // face data
fputs("== Face ==\n", stdout); fputs("== Face ==\n", stdout);