aboutsummaryrefslogtreecommitdiff
path: root/zencore
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2022-03-23 14:03:01 +0100
committerPer Larsson <[email protected]>2022-03-23 14:03:01 +0100
commita1c5a93627fefa2db6dd3ae620e112ba46065f78 (patch)
tree90ae9bf52a10c1ecfcdd85c47fc89ceb22795162 /zencore
parentMap derived data references. (diff)
parentAdded route '/prj/list' for retrieving project info. (diff)
downloadzen-a1c5a93627fefa2db6dd3ae620e112ba46065f78.tar.xz
zen-a1c5a93627fefa2db6dd3ae620e112ba46065f78.zip
Merge branch 'main' into ddcref
Diffstat (limited to 'zencore')
-rw-r--r--zencore/compactbinary.cpp11
-rw-r--r--zencore/filesystem.cpp2
-rw-r--r--zencore/include/zencore/compactbinary.h11
-rw-r--r--zencore/include/zencore/iobuffer.h3
-rw-r--r--zencore/include/zencore/refcount.h5
-rw-r--r--zencore/include/zencore/workthreadpool.h46
-rw-r--r--zencore/include/zencore/zencore.h15
-rw-r--r--zencore/iobuffer.cpp2
-rw-r--r--zencore/thread.cpp6
-rw-r--r--zencore/workthreadpool.cpp77
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