diff options
| author | Stefan Boberg <[email protected]> | 2023-05-02 10:01:47 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-02 10:01:47 +0200 |
| commit | 075d17f8ada47e990fe94606c3d21df409223465 (patch) | |
| tree | e50549b766a2f3c354798a54ff73404217b4c9af /src/zencore/uid.cpp | |
| parent | fix: bundle shouldn't append content zip to zen (diff) | |
| download | zen-075d17f8ada47e990fe94606c3d21df409223465.tar.xz zen-075d17f8ada47e990fe94606c3d21df409223465.zip | |
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
Diffstat (limited to 'src/zencore/uid.cpp')
| -rw-r--r-- | src/zencore/uid.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
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 <zencore/uid.h> + +#include <zencore/endian.h> +#include <zencore/string.h> +#include <zencore/testing.h> + +#include <atomic> +#include <bit> +#include <chrono> +#include <random> +#include <set> +#include <unordered_map> + +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<uint8_t*>(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<const uint8_t*>(OidBits), sizeof(Oid::OidBits), OutString); +} + +StringBuilderBase& +Oid::ToString(StringBuilderBase& OutString) const +{ + String_t Str; + ToHexBytes(reinterpret_cast<const uint8_t*>(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<Oid> ids; + std::set<Oid> idset; + std::unordered_map<Oid, int, Oid::Hasher> 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 |