Add core::any
This commit is contained in:
parent
ee2854b3fe
commit
01f44fef80
|
|
@ -14,6 +14,7 @@
|
|||
<ClInclude Include="..\..\src\kiwano\base\Director.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\base\win32\ComPtr.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\base\win32\helper.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\any.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\basic_json.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\function.hpp" />
|
||||
<ClInclude Include="..\..\src\kiwano\core\core.h" />
|
||||
|
|
|
|||
|
|
@ -294,6 +294,9 @@
|
|||
<ClInclude Include="..\..\src\kiwano\utils\FileSystem.h">
|
||||
<Filter>utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\core\any.hpp">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\kiwano\ui\Button.cpp">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,374 @@
|
|||
// Copyright (c) 2018-2019 Kiwano - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
||||
inline namespace core
|
||||
{
|
||||
|
||||
class any
|
||||
{
|
||||
public:
|
||||
any() : storage_{}
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
typename _Ty,
|
||||
typename _Decayed = typename std::decay<_Ty>::type,
|
||||
typename = typename std::enable_if<std::is_copy_constructible<_Decayed>::value>::type
|
||||
>
|
||||
any(_Ty&& val) : storage_{}
|
||||
{
|
||||
emplace<_Decayed>(std::forward<_Ty&&>(val));
|
||||
}
|
||||
|
||||
template <
|
||||
typename _Ty,
|
||||
typename _Decayed = typename std::decay<_Ty>::type,
|
||||
typename... _Args
|
||||
>
|
||||
any(_Args&&... args) : storage_{}
|
||||
{
|
||||
emplace<_Decayed>(std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
any(const any& rhs) : storage_{}
|
||||
{
|
||||
if (rhs.has_value())
|
||||
{
|
||||
typeinfo() = rhs.typeinfo();
|
||||
storage_.is_small_ = rhs.storage_.is_small_;
|
||||
|
||||
if (rhs.has_small_type())
|
||||
{
|
||||
small_rtti() = rhs.small_rtti();
|
||||
small_rtti().copy(small_data(), rhs.small_data());
|
||||
}
|
||||
else
|
||||
{
|
||||
big_rtti() = rhs.big_rtti();
|
||||
big_data() = big_rtti().copy(rhs.big_data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
any(any&& rhs) noexcept : storage_{}
|
||||
{
|
||||
move_from(std::move(rhs));
|
||||
}
|
||||
|
||||
~any()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
inline const type_info& type() const noexcept
|
||||
{
|
||||
const type_info* const info = typeinfo();
|
||||
if (info)
|
||||
{
|
||||
return *info;
|
||||
}
|
||||
return typeid(void);
|
||||
}
|
||||
|
||||
inline bool has_value() const noexcept
|
||||
{
|
||||
return typeinfo() != nullptr;
|
||||
}
|
||||
|
||||
template <typename _Decayed, typename... _Args>
|
||||
void emplace(_Args&&... args)
|
||||
{
|
||||
reset();
|
||||
store<_Decayed>(decayed_is_small<_Decayed>{}, std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
void swap(any& rhs) noexcept
|
||||
{
|
||||
any old = static_cast<any&&>(rhs);
|
||||
rhs = static_cast<any&&>(*this);
|
||||
*this = static_cast<any&&>(old);
|
||||
}
|
||||
|
||||
inline void reset() noexcept
|
||||
{
|
||||
tidy();
|
||||
}
|
||||
|
||||
any& operator=(const any& rhs)
|
||||
{
|
||||
*this = any(rhs);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
any& operator=(any&& rhs) noexcept
|
||||
{
|
||||
reset();
|
||||
move_from(std::move(rhs));
|
||||
return (*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
const type_info*& typeinfo()
|
||||
{
|
||||
return storage_.small_.info_;
|
||||
}
|
||||
|
||||
const type_info* typeinfo() const
|
||||
{
|
||||
return storage_.small_.info_;
|
||||
}
|
||||
|
||||
template <typename _Decayed, typename... _Args>
|
||||
void store(std::true_type, _Args&&... args)
|
||||
{
|
||||
storage_.is_small_ = true;
|
||||
typeinfo() = &typeid(_Decayed);
|
||||
small_rtti() = small_storage_rtti::make<_Decayed>();
|
||||
|
||||
::new (small_data()) _Decayed(std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename _Decayed, typename... _Args>
|
||||
void store(std::false_type, _Args&&... args)
|
||||
{
|
||||
storage_.is_small_ = false;
|
||||
typeinfo() = &typeid(_Decayed);
|
||||
big_rtti() = big_storage_rtti::make<_Decayed>();
|
||||
|
||||
big_data() = ::new _Decayed(std::forward<_Args>(args)...);
|
||||
}
|
||||
|
||||
void tidy() noexcept
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
if (has_small_type())
|
||||
{
|
||||
small_rtti().destroy(small_data());
|
||||
}
|
||||
else
|
||||
{
|
||||
big_rtti().destroy(big_data());
|
||||
big_data() = nullptr;
|
||||
}
|
||||
typeinfo() = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void move_from(any&& rhs) noexcept
|
||||
{
|
||||
if (rhs.has_value())
|
||||
{
|
||||
typeinfo() = rhs.typeinfo();
|
||||
storage_.is_small_ = rhs.storage_.is_small_;
|
||||
|
||||
if (rhs.has_small_type())
|
||||
{
|
||||
small_rtti() = rhs.small_rtti();
|
||||
small_rtti().move(small_data(), rhs.small_data());
|
||||
}
|
||||
else
|
||||
{
|
||||
big_rtti() = rhs.big_rtti();
|
||||
big_data() = rhs.big_data();
|
||||
}
|
||||
rhs.typeinfo() = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline void* small_data()
|
||||
{
|
||||
return storage_.small_.buffer_;
|
||||
}
|
||||
|
||||
inline const void* small_data() const
|
||||
{
|
||||
return storage_.small_.buffer_;
|
||||
}
|
||||
|
||||
inline void*& big_data()
|
||||
{
|
||||
return storage_.big_.ptr_;
|
||||
}
|
||||
|
||||
inline void* big_data() const
|
||||
{
|
||||
return storage_.big_.ptr_;
|
||||
}
|
||||
|
||||
inline bool has_small_type() const
|
||||
{
|
||||
return storage_.is_small_;
|
||||
}
|
||||
|
||||
protected:
|
||||
static const auto ANY_SPACE_SIZE = 16U;
|
||||
|
||||
template <typename _Ty>
|
||||
struct decayed_is_small : public std::bool_constant<sizeof(_Ty) <= ANY_SPACE_SIZE>
|
||||
{
|
||||
};
|
||||
|
||||
struct big_storage_rtti
|
||||
{
|
||||
using destroy_func = void(void*);
|
||||
using copy_func = void*(const void*);
|
||||
|
||||
big_storage_rtti()
|
||||
{
|
||||
destroy = nullptr;
|
||||
copy = nullptr;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static inline big_storage_rtti make()
|
||||
{
|
||||
big_storage_rtti rtti;
|
||||
rtti.destroy = &big_storage_rtti::destroy_impl<_Ty>;
|
||||
rtti.copy = &big_storage_rtti::copy_impl<_Ty>;
|
||||
return rtti;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static void destroy_impl(void* const ptr) noexcept
|
||||
{
|
||||
::delete static_cast<_Ty*>(ptr);
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static void* copy_impl(void* const ptr) noexcept
|
||||
{
|
||||
return ::new _Ty(*static_cast<_Ty*>(ptr));
|
||||
}
|
||||
|
||||
destroy_func* destroy;
|
||||
copy_func* copy;
|
||||
};
|
||||
|
||||
struct small_storage_rtti
|
||||
{
|
||||
using destroy_func = void(void*);
|
||||
using copy_func = void* (void*, const void*);
|
||||
using move_func = void*(void*, const void*);
|
||||
|
||||
small_storage_rtti()
|
||||
{
|
||||
destroy = nullptr;
|
||||
copy = nullptr;
|
||||
move = nullptr;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static inline small_storage_rtti make()
|
||||
{
|
||||
small_storage_rtti rtti;
|
||||
rtti.destroy = &small_storage_rtti::destroy_impl<_Ty>;
|
||||
rtti.copy = &small_storage_rtti::copy_impl<_Ty>;
|
||||
rtti.move = &small_storage_rtti::move_impl<_Ty>;
|
||||
return rtti;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static void destroy_impl(void* const ptr) noexcept
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
_Ty& obj = *(static_cast<_Ty* const>(ptr));
|
||||
obj.~_Ty();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static void* copy_impl(void* const target, const void* const ptr) noexcept
|
||||
{
|
||||
return ::new (static_cast<_Ty*>(target)) _Ty(*static_cast<const _Ty*>(ptr));
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
static void* move_impl(void* const target, const void* const ptr) noexcept
|
||||
{
|
||||
return ::new (static_cast<_Ty*>(target)) _Ty(std::move(*static_cast<const _Ty*>(ptr)));
|
||||
}
|
||||
|
||||
destroy_func* destroy;
|
||||
copy_func* copy;
|
||||
move_func* move;
|
||||
};
|
||||
|
||||
protected:
|
||||
inline small_storage_rtti& small_rtti()
|
||||
{
|
||||
return storage_.small_.rtti_;
|
||||
}
|
||||
|
||||
inline const small_storage_rtti& small_rtti() const
|
||||
{
|
||||
return storage_.small_.rtti_;
|
||||
}
|
||||
|
||||
inline big_storage_rtti& big_rtti()
|
||||
{
|
||||
return storage_.big_.rtti_;
|
||||
}
|
||||
|
||||
inline const big_storage_rtti& big_rtti() const
|
||||
{
|
||||
return storage_.big_.rtti_;
|
||||
}
|
||||
|
||||
protected:
|
||||
struct small_storage
|
||||
{
|
||||
const type_info* info_;
|
||||
small_storage_rtti rtti_;
|
||||
char buffer_[ANY_SPACE_SIZE];
|
||||
};
|
||||
|
||||
struct big_storage
|
||||
{
|
||||
const type_info* info_;
|
||||
big_storage_rtti rtti_;
|
||||
void* ptr_;
|
||||
};
|
||||
|
||||
struct storage
|
||||
{
|
||||
bool is_small_;
|
||||
union
|
||||
{
|
||||
small_storage small_;
|
||||
big_storage big_;
|
||||
};
|
||||
};
|
||||
|
||||
storage storage_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,12 +21,14 @@
|
|||
#include <fstream>
|
||||
|
||||
#include <kiwano/utils/ResourceCache.h>
|
||||
#include <kiwano/utils/FileSystem.h>
|
||||
#include <kiwano/base/Logger.h>
|
||||
#include <kiwano/2d/Frame.h>
|
||||
#include <kiwano/2d/FrameSequence.h>
|
||||
#include <kiwano/renderer/GifImage.h>
|
||||
#include <kiwano/renderer/FontCollection.h>
|
||||
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
namespace __resource_cache_01
|
||||
|
|
@ -59,13 +61,20 @@ namespace kiwano
|
|||
|
||||
bool ResourceCache::LoadFromJsonFile(String const& file_path)
|
||||
{
|
||||
if (!FileSystem::GetInstance()->IsFileExists(file_path))
|
||||
{
|
||||
KGE_WARNING_LOG(L"ResourceCache::LoadFromJsonFile failed: File not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Json json_data;
|
||||
std::wifstream ifs;
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
|
||||
try
|
||||
{
|
||||
ifs.open(file_path.c_str());
|
||||
String full_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
|
||||
ifs.open(full_path.c_str());
|
||||
ifs >> json_data;
|
||||
ifs.close();
|
||||
}
|
||||
|
|
@ -112,14 +121,20 @@ namespace kiwano
|
|||
|
||||
bool ResourceCache::LoadFromXmlFile(String const& file_path)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (!FileSystem::GetInstance()->IsFileExists(file_path))
|
||||
{
|
||||
KGE_WARNING_LOG(L"ResourceCache::LoadFromXmlFile failed: File not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
std::wifstream ifs;
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
|
||||
try
|
||||
{
|
||||
ifs.open(file_path.c_str());
|
||||
String full_path = FileSystem::GetInstance()->GetFullPathForFile(file_path);
|
||||
ifs.open(full_path.c_str());
|
||||
|
||||
StringStream ss;
|
||||
ss << ifs.rdbuf();
|
||||
|
|
@ -192,7 +207,7 @@ namespace kiwano
|
|||
{
|
||||
if (frame)
|
||||
{
|
||||
cache_.insert(std::make_pair(id, frame));
|
||||
object_cache_.insert(std::make_pair(id, frame));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -268,7 +283,7 @@ namespace kiwano
|
|||
{
|
||||
if (frames)
|
||||
{
|
||||
cache_.insert(std::make_pair(id, frames));
|
||||
object_cache_.insert(std::make_pair(id, frames));
|
||||
return frames->GetFrames().size();
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -278,7 +293,7 @@ namespace kiwano
|
|||
{
|
||||
if (obj)
|
||||
{
|
||||
cache_.insert(std::make_pair(id, obj));
|
||||
object_cache_.insert(std::make_pair(id, obj));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -340,14 +355,14 @@ namespace kiwano
|
|||
return FontCollection();
|
||||
}
|
||||
|
||||
void ResourceCache::Delete(String const & id)
|
||||
void ResourceCache::Remove(String const & id)
|
||||
{
|
||||
cache_.erase(id);
|
||||
object_cache_.erase(id);
|
||||
}
|
||||
|
||||
void ResourceCache::Clear()
|
||||
{
|
||||
cache_.clear();
|
||||
object_cache_.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/macros.h>
|
||||
#include <kiwano/base/Resource.h>
|
||||
#include <kiwano/2d/include-forwards.h>
|
||||
#include <kiwano/renderer/GifImage.h>
|
||||
|
|
@ -87,7 +86,7 @@ namespace kiwano
|
|||
FontCollection GetFontCollection(String const& id) const;
|
||||
|
||||
// 删除指定资源
|
||||
void Delete(String const& id);
|
||||
void Remove(String const& id);
|
||||
|
||||
// 清空所有资源
|
||||
void Clear();
|
||||
|
|
@ -95,8 +94,8 @@ namespace kiwano
|
|||
template<typename _Ty>
|
||||
_Ty* Get(String const& id) const
|
||||
{
|
||||
auto iter = cache_.find(id);
|
||||
if (iter == cache_.end())
|
||||
auto iter = object_cache_.find(id);
|
||||
if (iter == object_cache_.end())
|
||||
return nullptr;
|
||||
return dynamic_cast<_Ty*>((*iter).second.get());
|
||||
}
|
||||
|
|
@ -107,9 +106,8 @@ namespace kiwano
|
|||
virtual ~ResourceCache();
|
||||
|
||||
protected:
|
||||
UnorderedMap<String, ObjectBasePtr> cache_;
|
||||
|
||||
UnorderedMap<String, GifImage> gif_cache_;
|
||||
UnorderedMap<String, FontCollection> font_collection_cache_;
|
||||
UnorderedMap<String, ObjectBasePtr> object_cache_;
|
||||
UnorderedMap<String, GifImage> gif_cache_;
|
||||
UnorderedMap<String, FontCollection> font_collection_cache_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue