ResLoader supports loading from JSON files
This commit is contained in:
parent
4768c340a6
commit
c523a138d4
|
|
@ -49,6 +49,7 @@ namespace kiwano
|
||||||
KGE_DECLARE_SMART_PTR(Scene);
|
KGE_DECLARE_SMART_PTR(Scene);
|
||||||
KGE_DECLARE_SMART_PTR(Layer);
|
KGE_DECLARE_SMART_PTR(Layer);
|
||||||
KGE_DECLARE_SMART_PTR(Sprite);
|
KGE_DECLARE_SMART_PTR(Sprite);
|
||||||
|
KGE_DECLARE_SMART_PTR(GifImage);
|
||||||
KGE_DECLARE_SMART_PTR(Text);
|
KGE_DECLARE_SMART_PTR(Text);
|
||||||
KGE_DECLARE_SMART_PTR(Canvas);
|
KGE_DECLARE_SMART_PTR(Canvas);
|
||||||
KGE_DECLARE_SMART_PTR(GeometryNode);
|
KGE_DECLARE_SMART_PTR(GeometryNode);
|
||||||
|
|
|
||||||
|
|
@ -2467,10 +2467,34 @@ namespace kiwano
|
||||||
public:
|
public:
|
||||||
// implicitly convert functions
|
// implicitly convert functions
|
||||||
|
|
||||||
template <typename _Ty>
|
inline operator boolean_type () const
|
||||||
inline operator _Ty() const
|
|
||||||
{
|
{
|
||||||
return get<_Ty>();
|
return as_bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator integer_type () const
|
||||||
|
{
|
||||||
|
return as_int();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator float_type () const
|
||||||
|
{
|
||||||
|
return as_float();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator const array_type& () const
|
||||||
|
{
|
||||||
|
return as_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator const string_type& () const
|
||||||
|
{
|
||||||
|
return as_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator const object_type& () const
|
||||||
|
{
|
||||||
|
return as_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -19,40 +19,107 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include "ResLoader.h"
|
#include "ResLoader.h"
|
||||||
#include "../platform/modules.h"
|
#include "../base/logs.h"
|
||||||
#include "../2d/Image.h"
|
#include "../2d/Image.h"
|
||||||
#include "../2d/Frames.h"
|
#include "../2d/Frames.h"
|
||||||
|
#include "../2d/GifImage.h"
|
||||||
|
#include "FileUtil.h"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
Resource LocateRes(Resource const& res, List<String> const& paths)
|
void LoadJsonData09(Json const& json_data, ResLoader* loader)
|
||||||
{
|
{
|
||||||
if (res.IsFileType())
|
String path;
|
||||||
|
if (json_data.count(L"path"))
|
||||||
{
|
{
|
||||||
String file_name = res.GetFileName();
|
path = json_data[L"path"];
|
||||||
for (const auto& path : paths)
|
}
|
||||||
|
|
||||||
|
if (json_data.count(L"images"))
|
||||||
|
{
|
||||||
|
for (const auto& image : json_data[L"images"])
|
||||||
{
|
{
|
||||||
if (modules::Shlwapi::Get().PathFileExistsW((path + file_name).c_str()))
|
String file = image[L"file"];
|
||||||
{
|
String id = image.count(L"id") ? image[L"id"] : file;
|
||||||
return Resource{ path + file_name };
|
|
||||||
}
|
if (image.count(L"type") && image[L"type"].as_string() == L"gif")
|
||||||
|
loader->AddGifImage(id, Resource(path + file));
|
||||||
|
else
|
||||||
|
loader->AddImage(id, Resource(path + file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
|
/*if (json_data.count(L"sounds"))
|
||||||
|
{
|
||||||
|
for (const auto& sound : json_data[L"sounds"])
|
||||||
|
{
|
||||||
|
loader->AddObj();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResLoader::LoadFromJsonFile(String const& file_path)
|
||||||
|
{
|
||||||
|
Json json_data;
|
||||||
|
std::wifstream ifs;
|
||||||
|
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ifs.open(file_path.c_str());
|
||||||
|
ifs >> json_data;
|
||||||
|
ifs.close();
|
||||||
|
}
|
||||||
|
catch (std::wifstream::failure& e)
|
||||||
|
{
|
||||||
|
String msg(e.what());
|
||||||
|
KGE_WARNING_LOG(L"ResLoader::LoadFromJsonFile failed: Cannot open file. (%s)", msg.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (json_exception& e)
|
||||||
|
{
|
||||||
|
String msg(e.what());
|
||||||
|
KGE_WARNING_LOG(L"ResLoader::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", msg.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return LoadFromJson(json_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResLoader::LoadFromJson(Json const& json_data)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String version = json_data[L"version"];
|
||||||
|
if (version.empty() || version == L"0.9")
|
||||||
|
{
|
||||||
|
LoadJsonData09(json_data, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("unknown JSON data version");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
String msg(e.what());
|
||||||
|
KGE_WARNING_LOG(L"ResLoader::LoadFromJson failed: JSON data is invalid. (%s)", msg.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ResLoader::AddImage(String const& id, Resource const& image)
|
bool ResLoader::AddImage(String const& id, Resource const& image)
|
||||||
{
|
{
|
||||||
ImagePtr ptr = new (std::nothrow) Image;
|
ImagePtr ptr = new (std::nothrow) Image;
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
if (ptr->Load(LocateRes(image, search_paths_)))
|
if (ptr->Load(image))
|
||||||
{
|
{
|
||||||
res_.insert(std::make_pair(id, ptr));
|
return AddImage(id, ptr);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -68,6 +135,29 @@ namespace kiwano
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResLoader::AddGifImage(String const& id, Resource const& image)
|
||||||
|
{
|
||||||
|
GifImagePtr ptr = new (std::nothrow) GifImage;
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
if (ptr->Load(image))
|
||||||
|
{
|
||||||
|
return AddGifImage(id, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResLoader::AddGifImage(String const& id, GifImagePtr image)
|
||||||
|
{
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
res_.insert(std::make_pair(id, image));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
size_t ResLoader::AddFrames(String const& id, Array<Resource> const& images)
|
size_t ResLoader::AddFrames(String const& id, Array<Resource> const& images)
|
||||||
{
|
{
|
||||||
if (images.empty())
|
if (images.empty())
|
||||||
|
|
@ -81,7 +171,7 @@ namespace kiwano
|
||||||
ImagePtr ptr = new (std::nothrow) Image;
|
ImagePtr ptr = new (std::nothrow) Image;
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
if (ptr->Load(LocateRes(image, search_paths_)))
|
if (ptr->Load(image))
|
||||||
{
|
{
|
||||||
image_arr.push_back(ptr);
|
image_arr.push_back(ptr);
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +210,7 @@ namespace kiwano
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ImagePtr raw = new (std::nothrow) Image;
|
ImagePtr raw = new (std::nothrow) Image;
|
||||||
if (!raw || !raw->Load(LocateRes(image, search_paths_)))
|
if (!raw || !raw->Load(image))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
float raw_width = raw->GetSourceWidth();
|
float raw_width = raw->GetSourceWidth();
|
||||||
|
|
@ -156,7 +246,7 @@ namespace kiwano
|
||||||
size_t ResLoader::AddFrames(String const & id, Resource const & image, Array<Rect> const & crop_rects)
|
size_t ResLoader::AddFrames(String const & id, Resource const & image, Array<Rect> const & crop_rects)
|
||||||
{
|
{
|
||||||
ImagePtr raw = new (std::nothrow) Image;
|
ImagePtr raw = new (std::nothrow) Image;
|
||||||
if (!raw || !raw->Load(LocateRes(image, search_paths_)))
|
if (!raw || !raw->Load(image))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Array<ImagePtr> image_arr;
|
Array<ImagePtr> image_arr;
|
||||||
|
|
@ -206,6 +296,11 @@ namespace kiwano
|
||||||
return Get<Image>(id);
|
return Get<Image>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GifImagePtr ResLoader::GetGifImage(String const& id) const
|
||||||
|
{
|
||||||
|
return Get<GifImage>(id);
|
||||||
|
}
|
||||||
|
|
||||||
FramesPtr ResLoader::GetFrames(String const & id) const
|
FramesPtr ResLoader::GetFrames(String const & id) const
|
||||||
{
|
{
|
||||||
return Get<Frames>(id);
|
return Get<Frames>(id);
|
||||||
|
|
@ -226,26 +321,4 @@ namespace kiwano
|
||||||
res_.clear();
|
res_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResLoader::AddSearchPath(String const & path)
|
|
||||||
{
|
|
||||||
String tmp = path;
|
|
||||||
size_t pos = 0;
|
|
||||||
while ((pos = tmp.find(L"/", pos)) != String::npos)
|
|
||||||
{
|
|
||||||
tmp.replace(pos, 1, L"\\");
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmp.at(tmp.length() - 1) != L'\\')
|
|
||||||
{
|
|
||||||
tmp.append(L"\\");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto iter = std::find(search_paths_.cbegin(), search_paths_.cend(), tmp);
|
|
||||||
if (iter == search_paths_.cend())
|
|
||||||
{
|
|
||||||
search_paths_.push_front(tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../macros.h"
|
#include "../macros.h"
|
||||||
#include "../common/helper.h"
|
#include "../common/helper.h"
|
||||||
|
#include "../common/Json.h"
|
||||||
#include "../base/Resource.h"
|
#include "../base/Resource.h"
|
||||||
#include "../2d/include-forwards.h"
|
#include "../2d/include-forwards.h"
|
||||||
|
|
||||||
|
|
@ -29,12 +30,24 @@ namespace kiwano
|
||||||
class KGE_API ResLoader
|
class KGE_API ResLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// 从 JSON 文件加载资源信息
|
||||||
|
bool LoadFromJsonFile(String const& file_path);
|
||||||
|
|
||||||
|
// 从 JSON 加载资源信息
|
||||||
|
bool LoadFromJson(Json const& json_data);
|
||||||
|
|
||||||
// 添加图片
|
// 添加图片
|
||||||
bool AddImage(String const& id, Resource const& image);
|
bool AddImage(String const& id, Resource const& image);
|
||||||
|
|
||||||
// 添加图片
|
// 添加图片
|
||||||
bool AddImage(String const& id, ImagePtr image);
|
bool AddImage(String const& id, ImagePtr image);
|
||||||
|
|
||||||
|
// 添加 GIF 图片
|
||||||
|
bool AddGifImage(String const& id, Resource const& image);
|
||||||
|
|
||||||
|
// 添加 GIF 图片
|
||||||
|
bool AddGifImage(String const& id, GifImagePtr image);
|
||||||
|
|
||||||
// 添加帧集合
|
// 添加帧集合
|
||||||
size_t AddFrames(String const& id, Array<Resource> const& images);
|
size_t AddFrames(String const& id, Array<Resource> const& images);
|
||||||
|
|
||||||
|
|
@ -57,6 +70,8 @@ namespace kiwano
|
||||||
|
|
||||||
ImagePtr GetImage(String const& id) const;
|
ImagePtr GetImage(String const& id) const;
|
||||||
|
|
||||||
|
GifImagePtr GetGifImage(String const& id) const;
|
||||||
|
|
||||||
FramesPtr GetFrames(String const& id) const;
|
FramesPtr GetFrames(String const& id) const;
|
||||||
|
|
||||||
ObjectPtr GetObj(String const& id) const;
|
ObjectPtr GetObj(String const& id) const;
|
||||||
|
|
@ -67,11 +82,6 @@ namespace kiwano
|
||||||
// 销毁所有资源
|
// 销毁所有资源
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
// Ìí¼Ó×ÊÔ´ËÑË÷·¾¶
|
|
||||||
void AddSearchPath(
|
|
||||||
String const& path
|
|
||||||
);
|
|
||||||
|
|
||||||
template<typename _Ty>
|
template<typename _Ty>
|
||||||
_Ty* Get(String const& id) const
|
_Ty* Get(String const& id) const
|
||||||
{
|
{
|
||||||
|
|
@ -83,6 +93,5 @@ namespace kiwano
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UnorderedMap<String, ObjectPtr> res_;
|
UnorderedMap<String, ObjectPtr> res_;
|
||||||
List<String> search_paths_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,15 +7,15 @@ class Demo1
|
||||||
: public Scene
|
: public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ScenePtr Create()
|
static ScenePtr Create(ResLoader* loader)
|
||||||
{
|
{
|
||||||
return new Demo1;
|
return new Demo1(loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
Demo1()
|
Demo1(ResLoader* loader)
|
||||||
{
|
{
|
||||||
// 创建人物图片
|
// 获取人物图片
|
||||||
ImagePtr man_image = new Image(L"res/man.png");
|
ImagePtr man_image = loader->GetImage(L"man");
|
||||||
|
|
||||||
// 缓动方程
|
// 缓动方程
|
||||||
auto ease_functions = {
|
auto ease_functions = {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class Demo2
|
||||||
: public Scene
|
: public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ScenePtr Create()
|
static ScenePtr Create(ResLoader* loader)
|
||||||
{
|
{
|
||||||
return new Demo2;
|
return new Demo2;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class Demo3
|
||||||
TextPtr state_text; // 播放状态文字
|
TextPtr state_text; // 播放状态文字
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ScenePtr Create()
|
static ScenePtr Create(ResLoader* loader)
|
||||||
{
|
{
|
||||||
return new Demo3;
|
return new Demo3;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ class Demo4
|
||||||
: public Scene
|
: public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ScenePtr Create()
|
static ScenePtr Create(ResLoader* loader)
|
||||||
{
|
{
|
||||||
return new Demo4;
|
return new Demo4;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Demo5
|
||||||
: public Scene
|
: public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static ScenePtr Create()
|
static ScenePtr Create(ResLoader* loader)
|
||||||
{
|
{
|
||||||
return new Demo5;
|
return new Demo5;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,9 @@
|
||||||
<Project>{ff7f943d-a89c-4e6c-97cf-84f7d8ff8edf}</Project>
|
<Project>{ff7f943d-a89c-4e6c-97cf-84f7d8ff8edf}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="res\res.json" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,7 @@
|
||||||
<ClInclude Include="Demo4.h" />
|
<ClInclude Include="Demo4.h" />
|
||||||
<ClInclude Include="Demo5.h" />
|
<ClInclude Include="Demo5.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="res\res.json" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -11,7 +11,7 @@ namespace
|
||||||
struct Demo
|
struct Demo
|
||||||
{
|
{
|
||||||
String title;
|
String title;
|
||||||
ScenePtr(*Create)();
|
ScenePtr(*Create)(ResLoader*);
|
||||||
};
|
};
|
||||||
|
|
||||||
Demo s_Demos[] = {
|
Demo s_Demos[] = {
|
||||||
|
|
@ -28,6 +28,8 @@ namespace
|
||||||
class DemoApp
|
class DemoApp
|
||||||
: public Application
|
: public Application
|
||||||
{
|
{
|
||||||
|
ResLoader loader_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DemoApp()
|
DemoApp()
|
||||||
{
|
{
|
||||||
|
|
@ -43,6 +45,10 @@ public:
|
||||||
|
|
||||||
void OnStart() override
|
void OnStart() override
|
||||||
{
|
{
|
||||||
|
// 从 JSON 文件中加载资源
|
||||||
|
loader_.LoadFromJsonFile(L"res/res.json");
|
||||||
|
|
||||||
|
// 切换到第一个场景
|
||||||
ChangeDemoScene(0);
|
ChangeDemoScene(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,7 +61,7 @@ public:
|
||||||
String title = s_Demos[index].title;
|
String title = s_Demos[index].title;
|
||||||
Window::Instance()->SetTitle(L"KiwanoʾÀý³ÌÐò - " + title);
|
Window::Instance()->SetTitle(L"KiwanoʾÀý³ÌÐò - " + title);
|
||||||
|
|
||||||
ScenePtr scene = s_Demos[index].Create();
|
ScenePtr scene = s_Demos[index].Create(&loader_);
|
||||||
EnterScene(scene);
|
EnterScene(scene);
|
||||||
|
|
||||||
// Ìí¼Ó°´¼ü¼àÌý
|
// Ìí¼Ó°´¼ü¼àÌý
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"version": "0.9",
|
||||||
|
"path": "./res/",
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"id": "man",
|
||||||
|
"file": "man.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "monster",
|
||||||
|
"file": "akushu.png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "forest_bg",
|
||||||
|
"file": "spring_forest.jpg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "tiger",
|
||||||
|
"file": "tiger.png",
|
||||||
|
"rows": 3,
|
||||||
|
"cols": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "Kusanagi",
|
||||||
|
"file": "Kusanagi.gif",
|
||||||
|
"type": "gif"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sounds": [
|
||||||
|
{
|
||||||
|
"id": "bg_music",
|
||||||
|
"file": "splash.mp3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue