Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFrameAnimationMsgPack.cpp
More file actions
Latest commit
157 lines (136 loc) · 5.74 KB
/
Copy pathFrameAnimationMsgPack.cpp
File metadata and controls
157 lines (136 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include"FrameAnimationMsgPack.h"
#include"FrameAnimationData.h"
#include"DekiLogSystem.h"
#include"assets/AssetManager.h"
#include"SceneMessagePack.h"
#include<cstddef>
#include<cstdint>
#include<fstream>
#include<vector>
#ifdef DEKI_EDITOR
// Editor-only: save serializes through the generated reflection serializer.
#include<nlohmann/json.hpp>
#include"reflection/Serialization.h"
using json = nlohmann::json;
#endif
// FrameAnimationData is a DEKI_SERIALIZABLE struct, so the reflection codegen
// generates both the editor JSON Deki::Serialize<T> and the all-platforms
// DeserializeMsgPack (declared via generated/FrameAnimationData.gen.h, included
// by FrameAnimationData.h). Load and save go through those generated functions,
// so there is no hand-written per-field parsing here, on desktop or on device.
boolFrameAnimationMsgPackHelper::LoadAnimation(constchar* msgpack_path, FrameAnimationData* out_data)
{
if (!msgpack_path || !out_data)
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimation - null parameters");
returnfalse;
}
// Read file into buffer
std::ifstream file(msgpack_path, std::ios::binary | std::ios::ate);
if (!file.is_open())
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimation - failed to open: %s", msgpack_path);
returnfalse;
}
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<uint8_t> buffer(size);
if (!file.read(reinterpret_cast<char*>(buffer.data()), size))
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimation - failed to read file");
returnfalse;
}
returnLoadAnimationFromMemory(buffer.data(), static_cast<size_t>(size), out_data);
}
boolFrameAnimationMsgPackHelper::LoadAnimationFromMemory(constuint8_t* data, size_t size, FrameAnimationData* out_data)
{
if (!data || size == 0 || !out_data)
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimationFromMemory - invalid parameters");
returnfalse;
}
out_data->spritesheetGuid.clear();
out_data->animations.clear();
// Generated, reflection-driven MessagePack deserialize (full field-name keys).
// Identical path on desktop and embedded via SceneMsgPackParser.
Deki::SceneFormat::SceneMsgPackParser parser(data, size);
uint32_t mapSize = 0;
if (!parser.ReadMapSize(mapSize))
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimationFromMemory - root is not a MessagePack map");
returnfalse;
}
if (!DeserializeMsgPack(*out_data, parser, mapSize))
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::LoadAnimationFromMemory - deserialize failed");
returnfalse;
}
int totalFrames = 0;
for (constauto& anim : out_data->animations)
totalFrames += static_cast<int>(anim.frames.size());
DEKI_LOG_INTERNAL("FrameAnimationMsgPackHelper::LoadAnimation - loaded %d animations with %d total frames",
static_cast<int>(out_data->animations.size()), totalFrames);
returntrue;
}
#ifdef DEKI_EDITOR
boolFrameAnimationMsgPackHelper::SaveAnimation(constchar* msgpack_path, const FrameAnimationData* anim_data)
{
if (!msgpack_path || !anim_data)
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::SaveAnimation - null parameters");
returnfalse;
}
try
{
// Generated reflection serialize (full field-name keys) -> MessagePack.
// Mirrors the load path; nested sequences/frames are handled recursively.
json j = Deki::Serialize<FrameAnimationData>(*anim_data);
std::vector<uint8_t> msgpack_data = json::to_msgpack(j);
std::ofstream file(msgpack_path, std::ios::binary);
if (!file.is_open())
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::SaveAnimation - failed to open for writing: %s", msgpack_path);
returnfalse;
}
file.write(reinterpret_cast<constchar*>(msgpack_data.data()), msgpack_data.size());
int totalFrames = 0;
for (constauto& seq : anim_data->animations)
totalFrames += static_cast<int>(seq.frames.size());
DEKI_LOG_INTERNAL("FrameAnimationMsgPackHelper::SaveAnimation - saved %d animations with %d total frames (%zu bytes)",
static_cast<int>(anim_data->animations.size()), totalFrames, msgpack_data.size());
return file.good();
}
catch (const std::exception& e)
{
DEKI_LOG_ERROR("FrameAnimationMsgPackHelper::SaveAnimation - error: %s", e.what());
returnfalse;
}
}
#endif
// Self-register animation loader with AssetManager. The memLoader lets packed
// animations load straight from a .dpack on device (previously missing, so packed
// animations could only load as loose cache files).
namespace {
struct_AnimLoaderReg {
_AnimLoaderReg() {
auto loader = [](constchar* p) -> void* {
auto* data = newFrameAnimationData();
if (FrameAnimationMsgPackHelper::LoadAnimation(p, data))
return data;
delete data;
returnnullptr;
};
auto unloader = [](void* a) { deletestatic_cast<FrameAnimationData*>(a); };
auto memLoader = [](constuint8_t* d, size_t n) -> void* {
auto* data = newFrameAnimationData();
if (FrameAnimationMsgPackHelper::LoadAnimationFromMemory(d, n, data))
return data;
delete data;
returnnullptr;
};
Deki::AssetManager::RegisterLoader("FrameAnimationData", loader, unloader, memLoader);
Deki::AssetManager::RegisterLoader("Animation", loader, unloader, memLoader);
}
};
static _AnimLoaderReg s_animLoaderReg;
}