diff options
| author | Per Larsson <[email protected]> | 2022-03-23 14:03:01 +0100 |
|---|---|---|
| committer | Per Larsson <[email protected]> | 2022-03-23 14:03:01 +0100 |
| commit | a1c5a93627fefa2db6dd3ae620e112ba46065f78 (patch) | |
| tree | 90ae9bf52a10c1ecfcdd85c47fc89ceb22795162 /zencore | |
| parent | Map derived data references. (diff) | |
| parent | Added route '/prj/list' for retrieving project info. (diff) | |
| download | zen-a1c5a93627fefa2db6dd3ae620e112ba46065f78.tar.xz zen-a1c5a93627fefa2db6dd3ae620e112ba46065f78.zip | |
Merge branch 'main' into ddcref
Diffstat (limited to 'zencore')
| -rw-r--r-- | zencore/compactbinary.cpp | 11 | ||||
| -rw-r--r-- | zencore/filesystem.cpp | 2 | ||||
| -rw-r--r-- | zencore/include/zencore/compactbinary.h | 11 | ||||
| -rw-r--r-- | zencore/include/zencore/iobuffer.h | 3 | ||||
| -rw-r--r-- | zencore/include/zencore/refcount.h | 5 | ||||
| -rw-r--r-- | zencore/include/zencore/workthreadpool.h | 46 | ||||
| -rw-r--r-- | zencore/include/zencore/zencore.h | 15 | ||||
| -rw-r--r-- | zencore/iobuffer.cpp | 2 | ||||
| -rw-r--r-- | zencore/thread.cpp | 6 | ||||
| -rw-r--r-- | zencore/workthreadpool.cpp | 77 |
10 files changed, 159 insertions, 19 deletions
diff --git a/zencore/compactbinary.cpp b/zencore/compactbinary.cpp index 7cc6db68a..cb628af4b 100644 --- a/zencore/compactbinary.cpp +++ b/zencore/compactbinary.cpp @@ -54,7 +54,7 @@ GetPlatformToDateTimeBiasInSeconds() #if ZEN_PLATFORM_WINDOWS const uint64_t PlatformEpochYear = 1601; #else - const uint64_t PlatformEpochYear = 1970; + const uint64_t PlatformEpochYear = 1970; #endif const uint64_t DateTimeEpochYear = 1; return uint64_t(double(PlatformEpochYear - DateTimeEpochYear) * 365.2425) * 86400; @@ -71,7 +71,7 @@ DateTime::Now() GetSystemTimeAsFileTime(&SysTime); return DateTime{(EpochBias * SecsTo100nsTicks) + (uint64_t(SysTime.dwHighDateTime) << 32) | SysTime.dwLowDateTime}; #else - int64_t SecondsSinceUnixEpoch = time(nullptr); + int64_t SecondsSinceUnixEpoch = time(nullptr); return DateTime{(EpochBias + SecondsSinceUnixEpoch) * SecsTo100nsTicks}; #endif } @@ -1701,6 +1701,13 @@ CompactBinaryToJson(const CbObjectView& Object, StringBuilderBase& Builder) Writer.WriteField(Object.AsFieldView()); } +void +CompactBinaryToJson(const CbArrayView& Array, StringBuilderBase& Builder) +{ + CbJsonWriter Writer(Builder); + Writer.WriteField(Array.AsFieldView()); +} + ////////////////////////////////////////////////////////////////////////// #if ZEN_WITH_TESTS diff --git a/zencore/filesystem.cpp b/zencore/filesystem.cpp index 79563190c..041abaf1d 100644 --- a/zencore/filesystem.cpp +++ b/zencore/filesystem.cpp @@ -707,7 +707,7 @@ ScanFile(std::filesystem::path Path, const uint64_t ChunkSize, std::function<voi ProcessFunc(ReadBuffer.data(), dwBytesRead); } #else - int Fd = open(Path.c_str(), O_RDONLY | O_CLOEXEC); + int Fd = open(Path.c_str(), O_RDONLY | O_CLOEXEC); if (Fd < 0) { return false; diff --git a/zencore/include/zencore/compactbinary.h b/zencore/include/zencore/compactbinary.h index 66fa3065d..8985144dd 100644 --- a/zencore/include/zencore/compactbinary.h +++ b/zencore/include/zencore/compactbinary.h @@ -870,6 +870,11 @@ private: }; /** + * Serialize a compact binary array to JSON. + */ +ZENCORE_API void CompactBinaryToJson(const CbArrayView& Object, StringBuilderBase& Builder); + +/** * Array of CbField that have no names. * * Accessing a field of the array requires iteration. Access by index is not provided because the @@ -941,6 +946,12 @@ public: /** Returns a view of the array, including the type and name when present. */ using CbFieldView::GetView; + StringBuilderBase& ToJson(StringBuilderBase& Builder) const + { + CompactBinaryToJson(*this, Builder); + return Builder; + } + private: friend inline CbFieldViewIterator begin(const CbArrayView& Array) { return Array.CreateViewIterator(); } friend inline CbFieldViewIterator end(const CbArrayView&) { return CbFieldViewIterator(); } diff --git a/zencore/include/zencore/iobuffer.h b/zencore/include/zencore/iobuffer.h index 449236127..bc8cfdc0f 100644 --- a/zencore/include/zencore/iobuffer.h +++ b/zencore/include/zencore/iobuffer.h @@ -70,7 +70,6 @@ ToString(ZenContentType ContentType) return "png"sv; case ZenContentType::kIcon: return "icon"sv; - } } @@ -349,7 +348,7 @@ public: /** Create a buffer which references a sequence of bytes inside another buffer */ - ZENCORE_API IoBuffer(const IoBuffer& OuterBuffer, size_t Offset, size_t SizeBytes=~0ull); + ZENCORE_API IoBuffer(const IoBuffer& OuterBuffer, size_t Offset, size_t SizeBytes = ~0ull); /** Create a buffer which references a range of bytes which we assume will live * for the entire life time. diff --git a/zencore/include/zencore/refcount.h b/zencore/include/zencore/refcount.h index 7befbb338..32c282600 100644 --- a/zencore/include/zencore/refcount.h +++ b/zencore/include/zencore/refcount.h @@ -135,9 +135,8 @@ public: inline ~Ref() { m_Ref && m_Ref->Release(); } template<typename DerivedType> - requires DerivedFrom<DerivedType, T> inline Ref(const Ref<DerivedType>& Rhs) : Ref(Rhs.m_Ref) - { - } + requires DerivedFrom<DerivedType, T> + inline Ref(const Ref<DerivedType>& Rhs) : Ref(Rhs.m_Ref) {} [[nodiscard]] inline bool IsNull() const { return m_Ref == nullptr; } inline explicit operator bool() const { return m_Ref != nullptr; } diff --git a/zencore/include/zencore/workthreadpool.h b/zencore/include/zencore/workthreadpool.h new file mode 100644 index 000000000..834339d50 --- /dev/null +++ b/zencore/include/zencore/workthreadpool.h @@ -0,0 +1,46 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/zencore.h> + +#include <zencore/blockingqueue.h> +#include <zencore/refcount.h> + +#include <exception> +#include <functional> +#include <system_error> +#include <thread> +#include <vector> + +namespace zen { + +struct IWork : public RefCounted +{ + virtual void Execute() = 0; + + inline std::exception_ptr GetException() { return m_Exception; } + +private: + std::exception_ptr m_Exception; + + friend class WorkerThreadPool; +}; + +class WorkerThreadPool +{ +public: + WorkerThreadPool(int InThreadCount); + ~WorkerThreadPool(); + + void ScheduleWork(Ref<IWork> Work); + void ScheduleWork(std::function<void()>&& Work); + + void WorkerThreadFunction(); + +private: + std::vector<std::thread> m_WorkerThreads; + BlockingQueue<Ref<IWork>> m_WorkQueue; +}; + +} // namespace zen diff --git a/zencore/include/zencore/zencore.h b/zencore/include/zencore/zencore.h index 60ebd0f5f..1e5689d87 100644 --- a/zencore/include/zencore/zencore.h +++ b/zencore/include/zencore/zencore.h @@ -154,7 +154,7 @@ concept DerivedFrom = std::derived_from<D, B>; template<class T> concept Integral = std::is_integral_v<T>; template<class T> -concept SignedIntegral = Integral<T>&& std::is_signed_v<T>; +concept SignedIntegral = Integral<T> && std::is_signed_v<T>; template<class T> concept UnsignedIntegral = Integral<T> && !std::is_signed_v<T>; template<class F, class... A> @@ -163,7 +163,7 @@ concept Invocable = requires(F&& f, A&&... a) std::invoke(std::forward<F>(f), std::forward<A>(a)...); }; template<class D, class B> -concept DerivedFrom = std::is_base_of_v<B, D>&& std::is_convertible_v<const volatile D*, const volatile B*>; +concept DerivedFrom = std::is_base_of_v<B, D> && std::is_convertible_v<const volatile D*, const volatile B*>; #endif #if defined(__cpp_lib_ranges) @@ -240,12 +240,13 @@ static_assert(sizeof(wchar_t) == 2, "wchar_t is expected to be two bytes in size # define ZEN_DEBUG_SECTION ZEN_CODE_SECTION(".zcold") #endif -namespace zen { -class AssertException : public std::logic_error +namespace zen { -public: - AssertException(const char* Msg) : std::logic_error(Msg) {} -}; + class AssertException : public std::logic_error + { + public: + AssertException(const char* Msg) : std::logic_error(Msg) {} + }; } // namespace zen diff --git a/zencore/iobuffer.cpp b/zencore/iobuffer.cpp index 57abbfb48..e2aaa3169 100644 --- a/zencore/iobuffer.cpp +++ b/zencore/iobuffer.cpp @@ -513,7 +513,7 @@ IoBufferBuilder::MakeFromTemporaryFile(const std::filesystem::path& FileName) Handle = DataFile.Detach(); #else - int Fd = open(FileName.native().c_str(), O_RDONLY); + int Fd = open(FileName.native().c_str(), O_RDONLY); if (Fd < 0) { return {}; diff --git a/zencore/thread.cpp b/zencore/thread.cpp index c2ecc8d72..77b75bae3 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -180,7 +180,7 @@ Event::Set() #if ZEN_PLATFORM_WINDOWS SetEvent(m_EventHandle); #else - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = (EventInner*)m_EventHandle; { std::unique_lock Lock(Inner->Mutex); Inner->bSet = true; @@ -334,7 +334,7 @@ NamedEvent::Close() #if ZEN_PLATFORM_WINDOWS CloseHandle(m_EventHandle); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC - int Fd = int(intptr_t(m_EventHandle) & 0xffff'ffff); + int Fd = int(intptr_t(m_EventHandle) & 0xffff'ffff); if (flock(Fd, LOCK_EX | LOCK_NB) == 0) { @@ -599,7 +599,7 @@ ProcessHandle::Terminate(int ExitCode) bSuccess = (WaitResult != WAIT_OBJECT_0); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC ZEN_UNUSED(ExitCode); - bSuccess = (kill(m_Pid, SIGKILL) == 0); + bSuccess = (kill(m_Pid, SIGKILL) == 0); #endif if (!bSuccess) diff --git a/zencore/workthreadpool.cpp b/zencore/workthreadpool.cpp new file mode 100644 index 000000000..3fd1d11a6 --- /dev/null +++ b/zencore/workthreadpool.cpp @@ -0,0 +1,77 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zencore/workthreadpool.h> + +#include <zencore/logging.h> + +namespace zen { + +namespace detail { + struct LambdaWork : IWork + { + LambdaWork(auto Work) : WorkFunction(Work) {} + virtual void Execute() override { WorkFunction(); } + + std::function<void()> WorkFunction; + }; +} // namespace detail + +WorkerThreadPool::WorkerThreadPool(int InThreadCount) +{ + for (int i = 0; i < InThreadCount; ++i) + { + m_WorkerThreads.emplace_back(&WorkerThreadPool::WorkerThreadFunction, this); + } +} + +WorkerThreadPool::~WorkerThreadPool() +{ + m_WorkQueue.CompleteAdding(); + + for (std::thread& Thread : m_WorkerThreads) + { + Thread.join(); + } + + m_WorkerThreads.clear(); +} + +void +WorkerThreadPool::ScheduleWork(Ref<IWork> Work) +{ + m_WorkQueue.Enqueue(std::move(Work)); +} + +void +WorkerThreadPool::ScheduleWork(std::function<void()>&& Work) +{ + m_WorkQueue.Enqueue(new detail::LambdaWork(Work)); +} + +void +WorkerThreadPool::WorkerThreadFunction() +{ + do + { + Ref<IWork> Work; + if (m_WorkQueue.WaitAndDequeue(Work)) + { + try + { + Work->Execute(); + } + catch (std::exception& e) + { + Work->m_Exception = std::current_exception(); + + ZEN_WARN("Caught exception in worker thread: {}", e.what()); + } + } + else + { + return; + } + } while (true); +} + +} // namespace zen
\ No newline at end of file |