From 075d17f8ada47e990fe94606c3d21df409223465 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Tue, 2 May 2023 10:01:47 +0200 Subject: moved source directories into `/src` (#264) * moved source directories into `/src` * updated bundle.lua for new `src` path * moved some docs, icon * removed old test trees --- src/zencore/uid.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/zencore/uid.cpp (limited to 'src/zencore/uid.cpp') diff --git a/src/zencore/uid.cpp b/src/zencore/uid.cpp new file mode 100644 index 000000000..86cdfae3a --- /dev/null +++ b/src/zencore/uid.cpp @@ -0,0 +1,148 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace zen { + +////////////////////////////////////////////////////////////////////////// + +namespace detail { + static bool OidInitialised; + static uint32_t RunId; + static std::atomic_uint32_t Serial; +} // namespace detail + +////////////////////////////////////////////////////////////////////////// + +const Oid Oid::Zero = {{0u, 0u, 0u}}; +const Oid Oid::Max = {{~0u, ~0u, ~0u}}; + +void +Oid::Initialize() +{ + if (!detail::OidInitialised) + { + std::random_device Rng; + detail::RunId = Rng(); + detail::Serial = Rng(); + + detail::OidInitialised = true; + } +} + +const Oid& +Oid::Generate() +{ + if (!detail::OidInitialised) + { + Oid::Initialize(); + } + + const uint64_t kOffset = 1'609'459'200; // Seconds from 1970 -> 2021 + const uint64_t Time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) - kOffset; + + OidBits[0] = ToNetworkOrder(uint32_t(Time)); + OidBits[1] = ToNetworkOrder(uint32_t(++detail::Serial)); + OidBits[2] = detail::RunId; + + return *this; +} + +Oid +Oid::NewOid() +{ + return Oid().Generate(); +} + +Oid +Oid::FromHexString(const std::string_view String) +{ + ZEN_ASSERT(String.size() == 2 * sizeof(Oid::OidBits)); + + Oid Id; + + if (ParseHexBytes(String.data(), String.size(), reinterpret_cast(Id.OidBits))) + { + return Id; + } + else + { + return Oid::Zero; + } +} + +Oid +Oid::FromMemory(const void* Ptr) +{ + Oid Id; + memcpy(Id.OidBits, Ptr, sizeof Id); + return Id; +} + +void +Oid::ToString(char OutString[StringLength]) +{ + ToHexBytes(reinterpret_cast(OidBits), sizeof(Oid::OidBits), OutString); +} + +StringBuilderBase& +Oid::ToString(StringBuilderBase& OutString) const +{ + String_t Str; + ToHexBytes(reinterpret_cast(OidBits), sizeof(Oid::OidBits), Str); + + OutString.AppendRange(Str, &Str[StringLength]); + + return OutString; +} + +#if ZEN_WITH_TESTS + +TEST_CASE("Oid") +{ + SUBCASE("Basic") + { + Oid id1 = Oid::NewOid(); + ZEN_UNUSED(id1); + + std::vector ids; + std::set idset; + std::unordered_map idmap; + + const int Count = 1000; + + for (int i = 0; i < Count; ++i) + { + Oid id; + id.Generate(); + + ids.emplace_back(id); + idset.insert(id); + idmap.insert({id, i}); + } + + CHECK(ids.size() == Count); + CHECK(idset.size() == Count); // All ids should be unique + CHECK(idmap.size() == Count); // Ditto + } +} + +void +uid_forcelink() +{ +} + +#endif + +} // namespace zen -- cgit v1.2.3