diff --git a/kiwano-audio/kiwano-audio.vcxproj b/kiwano-audio/kiwano-audio.vcxproj
index c089a6f6..3824b049 100644
--- a/kiwano-audio/kiwano-audio.vcxproj
+++ b/kiwano-audio/kiwano-audio.vcxproj
@@ -103,23 +103,23 @@
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
diff --git a/kiwano-imgui/kiwano-imgui.vcxproj b/kiwano-imgui/kiwano-imgui.vcxproj
index 38d06357..23112941 100644
--- a/kiwano-imgui/kiwano-imgui.vcxproj
+++ b/kiwano-imgui/kiwano-imgui.vcxproj
@@ -112,23 +112,23 @@
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
diff --git a/kiwano-network/kiwano-network.vcxproj b/kiwano-network/kiwano-network.vcxproj
index 2264d27b..3e61c940 100644
--- a/kiwano-network/kiwano-network.vcxproj
+++ b/kiwano-network/kiwano-network.vcxproj
@@ -101,23 +101,23 @@
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\build\$(Configuration).$(Platform)\
- $(ProjectDir)\output\$(Configuration).$(Platform)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
- $(ProjectDir)\build\$(Configuration).$(Platform)\
- $(ProjectDir)\output\$(Configuration).$(Platform)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
false
diff --git a/kiwano/Kiwano.vcxproj b/kiwano/Kiwano.vcxproj
index 703a55bf..43717ce8 100644
--- a/kiwano/Kiwano.vcxproj
+++ b/kiwano/Kiwano.vcxproj
@@ -46,16 +46,16 @@
-
-
+
+
-
-
+
+
-
+
@@ -214,23 +214,23 @@
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\build\$(Configuration).$(Platform)\
- $(ProjectDir)\output\$(Configuration).$(Platform)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
true
- $(ProjectDir)\output\$(Configuration).$(Platform)\
- $(ProjectDir)\build\$(Configuration).$(Platform)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
false
- $(ProjectDir)\build\$(Configuration).$(Platform)\
- $(ProjectDir)\output\$(Configuration).$(Platform)\
+ $(ProjectDir)\build\$(Configuration).$(Platform).$(PlatformToolset)\
+ $(ProjectDir)\output\$(Configuration).$(Platform).$(PlatformToolset)\
false
diff --git a/kiwano/Kiwano.vcxproj.filters b/kiwano/Kiwano.vcxproj.filters
index d8e38d42..f354a062 100644
--- a/kiwano/Kiwano.vcxproj.filters
+++ b/kiwano/Kiwano.vcxproj.filters
@@ -108,12 +108,6 @@
2d
-
- common
-
-
- common
-
common
@@ -126,15 +120,9 @@
common
-
- common
-
common
-
- common
-
base
@@ -234,9 +222,6 @@
utils
-
- common
-
base
@@ -264,6 +249,21 @@
2d
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
+
+ common
+
diff --git a/kiwano/base/AsyncTask.h b/kiwano/base/AsyncTask.h
index eeae9f3c..0d23d240 100644
--- a/kiwano/base/AsyncTask.h
+++ b/kiwano/base/AsyncTask.h
@@ -20,7 +20,7 @@
#pragma once
#include "Object.h"
-#include "../common/closure.hpp"
+#include "../common/Closure.hpp"
#include
#include
diff --git a/kiwano/base/RefCounter.hpp b/kiwano/base/RefCounter.hpp
index ef29ca3a..56baf7b5 100644
--- a/kiwano/base/RefCounter.hpp
+++ b/kiwano/base/RefCounter.hpp
@@ -20,7 +20,7 @@
#pragma once
#include "../macros.h"
-#include "../common/noncopyable.hpp"
+#include "../common/Noncopyable.hpp"
namespace kiwano
{
diff --git a/kiwano/base/time.h b/kiwano/base/time.h
index 3b6c9c49..67e19bdf 100644
--- a/kiwano/base/time.h
+++ b/kiwano/base/time.h
@@ -20,7 +20,7 @@
#pragma once
#include "../macros.h"
-#include "../common/String.h"
+#include "../common/String.hpp"
#include
#include
diff --git a/kiwano/common/Array.h b/kiwano/common/Array.hpp
similarity index 100%
rename from kiwano/common/Array.h
rename to kiwano/common/Array.hpp
diff --git a/kiwano/common/Closure.hpp b/kiwano/common/Closure.hpp
new file mode 100644
index 00000000..9763ecab
--- /dev/null
+++ b/kiwano/common/Closure.hpp
@@ -0,0 +1,343 @@
+// Copyright (c) 2016-2018 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
+
+namespace kiwano
+{
+ //
+ // Closure is a light weight std::function<>-like class
+ //
+
+ namespace __closure_detail
+ {
+ //
+ // is_callable
+ //
+
+ namespace __callable_detail
+ {
+ template
+ struct helper
+ {
+ template static int test(...);
+
+ template struct class_mem;
+ template static char test(class_mem<_Uty, &_Uty::operator()>*);
+
+ template struct class_const_mem;
+ template static char test(class_const_mem<_Uty, &_Uty::operator()>*);
+
+ template<
+ typename _Uty,
+ typename _Uret = typename std::decay().operator()(std::declval<_Args>()...))>::type,
+ typename = typename std::enable_if::value>::type>
+ static char test(int);
+
+ static constexpr bool value = sizeof(test<_Ty>(0)) == sizeof(char);
+ };
+ }
+
+ template
+ struct is_callable
+ : public std::bool_constant<__callable_detail::helper<_Ty, _Ret, _Args...>::value>
+ {
+ };
+
+ //
+ // Callable
+ //
+
+ template
+ class Callable
+ {
+ public:
+ virtual ~Callable() {}
+
+ virtual void AddRef() = 0;
+ virtual void Release() = 0;
+ virtual _Ret Invoke(_Args... args) const = 0;
+ };
+
+ template
+ class RefCountCallable
+ : public Callable<_Ret, _Args...>
+ {
+ public:
+ RefCountCallable() : ref_count_(0) {}
+
+ virtual void AddRef() override
+ {
+ ++ref_count_;
+ }
+
+ virtual void Release() override
+ {
+ --ref_count_;
+ if (ref_count_ <= 0)
+ {
+ delete this;
+ }
+ }
+
+ private:
+ int ref_count_;
+ };
+
+ template
+ class ProxyCallable
+ : public RefCountCallable<_Ret, _Args...>
+ {
+ public:
+ ProxyCallable(_Ty&& val)
+ : callee_(std::move(val))
+ {
+ }
+
+ virtual _Ret Invoke(_Args... args) const override
+ {
+ return callee_(std::forward<_Args>(args)...);
+ }
+
+ static inline Callable<_Ret, _Args...>* Make(_Ty&& val)
+ {
+ return new (std::nothrow) ProxyCallable<_Ty, _Ret, _Args...>(std::move(val));
+ }
+
+ private:
+ _Ty callee_;
+ };
+
+ template
+ class ProxyMemCallable
+ : public RefCountCallable<_Ret, _Args...>
+ {
+ public:
+ typedef _Ret(_Ty::* _FuncType)(_Args...);
+
+ virtual _Ret Invoke(_Args... args) const override
+ {
+ return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...);
+ }
+
+ static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func)
+ {
+ return new (std::nothrow) ProxyMemCallable<_Ty, _Ret, _Args...>(ptr, func);
+ }
+
+ protected:
+ ProxyMemCallable(void* ptr, _FuncType func)
+ : ptr_(ptr)
+ , func_(func)
+ {
+ }
+
+ protected:
+ void* ptr_;
+ _FuncType func_;
+ };
+
+ template
+ class ProxyConstMemCallable
+ : public RefCountCallable<_Ret, _Args...>
+ {
+ public:
+ typedef _Ret(_Ty::* _FuncType)(_Args...) const;
+
+ virtual _Ret Invoke(_Args... args) const override
+ {
+ return (static_cast<_Ty*>(ptr_)->*func_)(std::forward<_Args>(args)...);
+ }
+
+ static inline Callable<_Ret, _Args...>* Make(void* ptr, _FuncType func)
+ {
+ return new (std::nothrow) ProxyConstMemCallable<_Ty, _Ret, _Args...>(ptr, func);
+ }
+
+ protected:
+ ProxyConstMemCallable(void* ptr, _FuncType func)
+ : ptr_(ptr)
+ , func_(func)
+ {
+ }
+
+ protected:
+ void* ptr_;
+ _FuncType func_;
+ };
+ }
+
+ //
+ // exceptions
+ //
+ class bad_function_call : public std::exception
+ {
+ public:
+ bad_function_call() {}
+
+ virtual const char* what() const override
+ {
+ return "bad function call";
+ }
+ };
+
+
+ //
+ // Closure details
+ //
+ template
+ class Closure;
+
+ template
+ class Closure<_Ret(_Args...)>
+ {
+ public:
+ Closure()
+ : callable_(nullptr)
+ {
+ }
+
+ Closure(std::nullptr_t)
+ : callable_(nullptr)
+ {
+ }
+
+ Closure(const Closure& rhs)
+ : callable_(rhs.callable_)
+ {
+ if (callable_) callable_->AddRef();
+ }
+
+ Closure(Closure&& rhs)
+ : callable_(rhs.callable_)
+ {
+ rhs.callable_ = nullptr;
+ }
+
+ Closure(_Ret(*func)(_Args...))
+ {
+ callable_ = __closure_detail::ProxyCallable<_Ret(*)(_Args...), _Ret, _Args...>::Make(std::move(func));
+ if (callable_) callable_->AddRef();
+ }
+
+ template<
+ typename _Ty,
+ typename = typename std::enable_if<__closure_detail::is_callable<_Ty, _Ret, _Args...>::value, int>::type>
+ Closure(_Ty val)
+ {
+ callable_ = __closure_detail::ProxyCallable<_Ty, _Ret, _Args...>::Make(std::move(val));
+ if (callable_) callable_->AddRef();
+ }
+
+ template::value || std::is_base_of<_Ty, _Uty>::value, int>::type>
+ Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...))
+ {
+ callable_ = __closure_detail::ProxyMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func);
+ if (callable_) callable_->AddRef();
+ }
+
+ template::value || std::is_base_of<_Ty, _Uty>::value, int>::type>
+ Closure(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const)
+ {
+ callable_ = __closure_detail::ProxyConstMemCallable<_Ty, _Ret, _Args...>::Make(ptr, func);
+ if (callable_) callable_->AddRef();
+ }
+
+ ~Closure()
+ {
+ tidy();
+ }
+
+ inline void swap(const Closure& rhs)
+ {
+ std::swap(callable_, rhs.callable_);
+ }
+
+ inline _Ret operator()(_Args... args) const
+ {
+ if (!callable_)
+ throw bad_function_call();
+ return callable_->Invoke(std::forward<_Args>(args)...);
+ }
+
+ inline operator bool() const
+ {
+ return !!callable_;
+ }
+
+ inline Closure& operator=(const Closure& rhs)
+ {
+ tidy();
+ callable_ = rhs.callable_;
+ if (callable_) callable_->AddRef();
+ return (*this);
+ }
+
+ inline Closure& operator=(Closure&& rhs)
+ {
+ tidy();
+ callable_ = rhs.callable_;
+ rhs.callable_ = nullptr;
+ return (*this);
+ }
+
+ private:
+ inline void tidy()
+ {
+ if (callable_)
+ {
+ callable_->Release();
+ callable_ = nullptr;
+ }
+ }
+
+ private:
+ __closure_detail::Callable<_Ret, _Args...>* callable_;
+ };
+
+ template::value || std::is_base_of<_Ty, _Uty>::value, int
+ >::type,
+ typename _Ret,
+ typename... _Args>
+ inline Closure<_Ret(_Args...)> MakeClosure(_Uty* ptr, _Ret(_Ty::* func)(_Args...))
+ {
+ return Closure<_Ret(_Args...)>(ptr, func);
+ }
+
+ template::value || std::is_base_of<_Ty, _Uty>::value, int
+ >::type,
+ typename _Ret,
+ typename... _Args>
+ inline Closure<_Ret(_Args...)> MakeClosure(_Uty* ptr, _Ret(_Ty::* func)(_Args...) const)
+ {
+ return Closure<_Ret(_Args...)>(ptr, func);
+ }
+}
diff --git a/kiwano/common/Json.h b/kiwano/common/Json.hpp
similarity index 100%
rename from kiwano/common/Json.h
rename to kiwano/common/Json.hpp
diff --git a/kiwano/common/Noncopyable.hpp b/kiwano/common/Noncopyable.hpp
new file mode 100644
index 00000000..e6278f6e
--- /dev/null
+++ b/kiwano/common/Noncopyable.hpp
@@ -0,0 +1,35 @@
+// Copyright (c) 2016-2018 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
+
+namespace kiwano
+{
+ class Noncopyable
+ {
+ protected:
+ Noncopyable() = default;
+
+ private:
+ Noncopyable(const Noncopyable&) = delete;
+
+ Noncopyable& operator=(const Noncopyable&) = delete;
+ };
+}
diff --git a/kiwano/common/String.h b/kiwano/common/String.hpp
similarity index 100%
rename from kiwano/common/String.h
rename to kiwano/common/String.hpp
diff --git a/kiwano/common/helper.h b/kiwano/common/helper.h
index d4384f7e..400f0fdb 100644
--- a/kiwano/common/helper.h
+++ b/kiwano/common/helper.h
@@ -19,8 +19,8 @@
// THE SOFTWARE.
#pragma once
-#include "Array.h"
-#include "String.h"
+#include "Array.hpp"
+#include "String.hpp"
#include
#include