Skip to content

Commit b62737a

Browse files
committed
Added basic TypeId runtime reflection
1 parent 3b87734 commit b62737a

File tree

14 files changed

+210
-37
lines changed

14 files changed

+210
-37
lines changed

Benchmarks/Lookups.bench.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void RunLookupsBenchmarks()
4444
}
4545
u64 i = 0;
4646
lookups.run("Array - Binary Search", [&data, &i] {
47-
ankerl::nanobench::doNotOptimizeAway(data.FindSortedEqual(i));
47+
ankerl::nanobench::doNotOptimizeAway(data.FindSorted(i));
4848
++i;
4949
});
5050
}
@@ -76,7 +76,7 @@ void RunLookupsBenchmarks()
7676
}
7777
u64 i = 0;
7878
complexityBSearch.complexityN(size).run("Array - Binary Search", [&data, &i] {
79-
data.FindSortedEqual(i);
79+
data.FindSorted(i);
8080
++i;
8181
});
8282
}

Include/Pipe/Core/Platform.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,4 @@ namespace p
178178
#else
179179
#define P_RESTRICT
180180
#define P_ATTR_MALLOC
181-
#endif
181+
#endif

Include/Pipe/Core/TypeTraits.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,20 @@ namespace p
155155
template<typename T>
156156
concept IsChar = Internal::TIsChar<T>::value;
157157

158+
159+
template<typename T>
160+
struct HasSuper
161+
{
162+
private:
163+
template<typename V>
164+
static void Impl(decltype(typename V::Super(), int()));
165+
template<typename V>
166+
static bool Impl(char);
167+
168+
public:
169+
static const bool value = std::is_void<decltype(Impl<T>(0))>::value;
170+
};
171+
158172
template<typename T>
159173
struct HasTypeMember
160174
{

Include/Pipe/Core/Utility.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ namespace p
6060
#endif
6161
}
6262

63+
struct Undefined
64+
{
65+
explicit Undefined() = default;
66+
};
67+
6368
template<typename Predicate>
6469
class ReversePredicate
6570
{

Include/Pipe/Reflect/TypeId.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "Pipe/Core/Hash.h"
55
#include "Pipe/Core/Platform.h"
6+
#include "Pipe/Core/Utility.h"
67

78
#include <format>
89
#include <iostream>
@@ -13,11 +14,12 @@ namespace p
1314
struct PIPE_API TypeId
1415
{
1516
protected:
16-
u64 id = 0;
17+
u64 id;
1718

1819

1920
public:
20-
constexpr TypeId() = default;
21+
constexpr TypeId() : id{0} {}
22+
constexpr TypeId(p::Undefined) {}
2123
explicit constexpr TypeId(u64 id) : id(id) {}
2224

2325
constexpr u64 GetId() const
@@ -69,11 +71,17 @@ namespace p
6971
}
7072

7173
template<typename T>
72-
inline consteval TypeId GetTypeId()
74+
inline consteval TypeId GetTypeId() requires(!IsConst<T>)
7375
{
7476
return TypeId{p::GetStringHash(TX(UNIQUE_FUNCTION_ID))};
7577
}
7678

79+
template<typename T>
80+
inline consteval TypeId GetTypeId() requires(IsConst<T>)
81+
{
82+
return GetTypeId<Mut<T>>();
83+
}
84+
7785
} // namespace p
7886

7987

Include/Pipe/Reflect/TypeRegistry.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ namespace p
2525
bool initialized = false;
2626

2727

28+
TArray<TypeId> ids;
29+
TArray<TypeId> parentIds;
30+
TArray<StringView> names;
31+
32+
2833
public:
2934
TypeRegistry();
3035
~TypeRegistry()

Include/PipeArrays.h

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ namespace p
559559
}
560560

561561
template<typename Value, typename SortPredicate = TLess<>>
562-
i32 FindSortedEqual(const Value& value, SortPredicate sortPredicate = {}) const
562+
i32 FindSorted(const Value& value, SortPredicate sortPredicate = {}) const
563563
{
564564
return p::BinarySearch(Data(), 0, Size(), value, sortPredicate);
565565
}
@@ -589,7 +589,7 @@ namespace p
589589
template<typename Value, typename SortPredicate = TLess<>>
590590
bool ContainsSorted(const Value& value, SortPredicate sortPredicate = {}) const
591591
{
592-
return FindSortedEqual(value, sortPredicate) != NO_INDEX;
592+
return FindSorted(value, sortPredicate) != NO_INDEX;
593593
}
594594
#pragma endregion Search
595595

@@ -871,55 +871,55 @@ namespace p
871871
*/
872872
template<typename SortPredicate = TLess<Type>>
873873
i32 AddUniqueSorted(const Type& value, SortPredicate sortPredicate = {},
874-
bool* outFound = nullptr, bool insertSorted = true)
874+
bool* outAdded = nullptr, bool insertSorted = true)
875875
{
876876
const i32 index = Super::LowerBound(value, sortPredicate);
877877
if (index != NO_INDEX)
878878
{
879879
if (!sortPredicate(value, Super::data[index])) // Equal check, found element
880880
{
881-
if (outFound)
882-
*outFound = false;
881+
if (outAdded)
882+
*outAdded = false;
883883
return index;
884884
}
885885
else if (insertSorted)
886886
{
887887
Insert(index, value);
888-
if (outFound)
889-
*outFound = true;
888+
if (outAdded)
889+
*outAdded = true;
890890
return index;
891891
}
892892
}
893893

894-
if (outFound)
895-
*outFound = true;
894+
if (outAdded)
895+
*outAdded = true;
896896
return Add(value);
897897
}
898898

899899
template<typename SortPredicate = TLess<Type>>
900900
i32 AddUniqueSorted(Type&& value, SortPredicate sortPredicate = {},
901-
bool* outFound = nullptr, bool insertSorted = true)
901+
bool* outAdded = nullptr, bool insertSorted = true)
902902
{
903903
const i32 index = Super::LowerBound(value, sortPredicate);
904904
if (index != NO_INDEX)
905905
{
906906
if (!sortPredicate(value, Super::data[index])) // Equal check, found element
907907
{
908-
if (outFound)
909-
*outFound = false;
908+
if (outAdded)
909+
*outAdded = false;
910910
return index;
911911
}
912912
else if (insertSorted)
913913
{
914914
Insert(index, p::Forward<Type>(value));
915-
if (outFound)
916-
*outFound = true;
915+
if (outAdded)
916+
*outAdded = true;
917917
return index;
918918
}
919919
}
920920

921-
if (outFound)
922-
*outFound = true;
921+
if (outAdded)
922+
*outAdded = true;
923923
return Add(p::Forward<Type>(value));
924924
}
925925

@@ -1043,6 +1043,9 @@ namespace p
10431043
return Super::data[atIndex];
10441044
}
10451045

1046+
void AddUninitialized(i32 count);
1047+
void InsertUninitialized(i32 atIndex, i32 count);
1048+
10461049
#pragma endregion Insertions
10471050

10481051

@@ -1098,7 +1101,7 @@ namespace p
10981101
bool RemoveSorted(const OtherType& value, SortPredicate sortPredicate = {},
10991102
const bool shouldShrink = true)
11001103
{
1101-
return RemoveAt(Super::FindSortedEqual(value, sortPredicate));
1104+
return RemoveAt(Super::FindSorted(value, sortPredicate));
11021105
}
11031106

11041107
/**
@@ -1458,8 +1461,6 @@ namespace p
14581461

14591462

14601463
protected:
1461-
void AddUninitialized(i32 count);
1462-
void InsertUninitialized(i32 atIndex, i32 count);
14631464
void CopyFrom(const IArray<const Type>& other);
14641465

14651466
template<u32 OtherInlineCapacity>

Include/PipeECS.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Pipe/Memory/UniquePtr.h"
1010
#include "Pipe/Reflect/Builders/NativeTypeBuilder.h"
1111
#include "PipeArrays.h"
12+
#include "PipeReflect.h"
1213

1314

1415
////////////////////////////////
@@ -2106,7 +2107,7 @@ namespace p
21062107
template<typename T>
21072108
inline TPool<Mut<T>>& EntityContext::AssurePool() const
21082109
{
2109-
constexpr TypeId componentId = GetTypeId<Mut<T>>();
2110+
const TypeId componentId = AssureTypeId<Mut<T>>();
21102111

21112112
i32 index = pools.LowerBound(PoolInstance{componentId, {}});
21122113
if (index != NO_INDEX)

Include/PipeReflect.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2015-2024 Piperift - All rights reserved
2+
3+
#pragma once
4+
5+
#include "Pipe/Core/StringView.h"
6+
#include "Pipe/Reflect/TypeId.h"
7+
#include "Pipe/Reflect/TypeName.h"
8+
9+
10+
namespace p
11+
{
12+
///////////////////////////////////////////////////////
13+
// Runtime reflection
14+
15+
namespace details
16+
{
17+
PIPE_API i32 AssureSingleTypeId(TypeId id);
18+
PIPE_API void SetTypeParentUnsafe(i32 index, TypeId parentId);
19+
PIPE_API void SetTypeNameUnsafe(i32 index, StringView name);
20+
} // namespace details
21+
22+
23+
template<typename T>
24+
TypeId AssureTypeId();
25+
26+
PIPE_API TypeId GetParentId(TypeId id);
27+
PIPE_API TypeId GetParentId(TypeId id);
28+
PIPE_API bool IsParentOf(TypeId parentId, TypeId childId);
29+
PIPE_API StringView GetTypeName(TypeId id);
30+
31+
32+
///////////////////////////////////////////////////////
33+
// Implementations
34+
35+
template<typename T>
36+
TypeId AssureTypeId()
37+
{
38+
// Static to only register once
39+
static TypeId typeId = []() {
40+
TypeId parentId{p::Undefined{}};
41+
if constexpr (HasSuper<T>::value)
42+
{
43+
parentId = AssureTypeId<typename T::Super>();
44+
}
45+
else
46+
{
47+
parentId = TypeId{};
48+
}
49+
50+
const TypeId typeId = GetTypeId<T>();
51+
const i32 index = details::AssureSingleTypeId(typeId);
52+
if (index != NO_INDEX) // Invalid or already registered
53+
{
54+
details::SetTypeParentUnsafe(index, parentId);
55+
details::SetTypeNameUnsafe(index, GetTypeName<T>());
56+
}
57+
return typeId;
58+
}();
59+
return typeId;
60+
}
61+
}; // namespace p

Src/Memory/MemoryStats.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ namespace p
131131
}
132132

133133
std::unique_lock lock{mutex};
134-
const i32 index = allocations.FindSortedEqual(ptr, SortLessAllocationStats{});
134+
const i32 index = allocations.FindSorted(ptr, SortLessAllocationStats{});
135135
if (index != NO_INDEX)
136136
{
137137
AllocationStats& allocation = allocations[index];

0 commit comments

Comments
 (0)