summaryrefslogtreecommitdiff
path: root/source/slang/slang-serialize-reflection.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-09-30 13:28:56 -0400
committerGitHub <noreply@github.com>2020-09-30 13:28:56 -0400
commit274c20a5eb133779a9d890ca79120815fb92b04e (patch)
tree50f8074917a102b25a7f34adeacffaf185d59242 /source/slang/slang-serialize-reflection.cpp
parent94d3f2bd9c5557658751f73bc5fc443b41230d2c (diff)
Generalizing Serialization (#1563)
* First pass at generalizing serializer. * Split out ReflectClassInfo * Use the general ReflectClassInfo * Fix some typos in debug generalized serialization. * Add calculation of classIds. Make distinct addCopy/add on SerialClasses. * Write up of more generalized serialization * WIP to transition from ASTSerialReader/Writer etc to generalized SerialReader/Writer and associated types. * Improvements to SerialExtraObjects. Keep RefObjects in scope in factory * Compiles with Serial refactor - doesn't quite work yet. * First pass serialization appears to work with refector. * Split out type info for general slang types. * Split out slang-serialize-misc-type-info.h * DebugSerialData -> SerialSourecLocData DebugSerialReader -> SerialSourceLocReader DebugSerialWriter -> SerialSourceLocWriter * Remove unused template that only compiles on VS. * Fix warning around unused function on non-VS.
Diffstat (limited to 'source/slang/slang-serialize-reflection.cpp')
-rw-r--r--source/slang/slang-serialize-reflection.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/source/slang/slang-serialize-reflection.cpp b/source/slang/slang-serialize-reflection.cpp
new file mode 100644
index 000000000..6430da55e
--- /dev/null
+++ b/source/slang/slang-serialize-reflection.cpp
@@ -0,0 +1,113 @@
+// slang-serialize-reflection.cpp
+#include "slang-serialize-reflection.h"
+
+#include "slang-serialize.h"
+
+namespace Slang {
+
+bool ReflectClassInfo::isSubClassOfSlow(const ThisType& super) const
+{
+ ReflectClassInfo const* info = this;
+ while (info)
+ {
+ if (info == &super)
+ return true;
+ info = info->m_superClass;
+ }
+ return false;
+}
+
+#if 0
+
+// #if'd out because produces a warning->error if not used.
+static bool _checkSubClassRange(ReflectClassInfo*const* typeInfos, Index typeInfosCount)
+{
+ for (Index i = 0; i < typeInfosCount; ++i)
+ {
+ for (Index j = 0; j < typeInfosCount; ++j)
+ {
+ auto a = typeInfos[i];
+ auto b = typeInfos[j];
+ if (a->isSubClassOf(*b) != a->isSubClassOfSlow(*b))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#endif
+
+static uint32_t _calcRangeRec(ReflectClassInfo* classInfo, const Dictionary<const ReflectClassInfo*, List<ReflectClassInfo*> >& childMap, uint32_t index)
+{
+ classInfo->m_classId = index++;
+ // Do the calc range for all the children
+ auto list = childMap.TryGetValue(classInfo);
+
+ if (list)
+ {
+ for (auto child : *list)
+ {
+ index = _calcRangeRec(child, childMap, index);
+ }
+ }
+
+ classInfo->m_lastClassId = index;
+ return index;
+}
+
+static ReflectClassInfo* _calcRoot(ReflectClassInfo* classInfo)
+{
+ while (classInfo->m_superClass)
+ {
+ classInfo = const_cast<ReflectClassInfo*>(classInfo->m_superClass);
+ }
+ return classInfo;
+}
+
+
+/* static */void ReflectClassInfo::calcClassIdHierachy(uint32_t baseIndex, ReflectClassInfo*const* typeInfos, Index typeInfosCount)
+{
+ SLANG_ASSERT(typeInfosCount > 0);
+
+ // TODO(JS):
+ // Note that the calculating of the ranges could be done more efficiently by adding to an array of struct { super, class }, sorting, by super classs
+ // and using a dictionary to map from class it's first in list of super class use. This works for now though.
+
+ // The root cannot be shared with another hierarchy - as doing so will mean that the range will be incorrect (it would need to span both trees)
+ ReflectClassInfo* root = _calcRoot(typeInfos[0]);
+
+ // We want to produce a map from a node that holds all of it's children
+ Dictionary<const ThisType*, List<ThisType*> > childMap;
+
+ const List<ThisType*> emptyList;
+ {
+ for (Index i = 0; i < typeInfosCount; ++ i)
+ {
+ auto typeInfo = typeInfos[i];
+ if (typeInfo->m_superClass)
+ {
+ // Add to that item
+ List<ThisType*>* list = childMap.TryGetValueOrAdd(typeInfo->m_superClass, emptyList);
+ if (!list)
+ {
+ list = childMap.TryGetValue(typeInfo->m_superClass);
+ }
+ SLANG_ASSERT(list);
+ list->add(typeInfo);
+ }
+
+ // The root should be the same for all types
+ SLANG_ASSERT(_calcRoot(typeInfo) == root);
+ }
+ }
+
+ // We want to recursively work out a range
+ _calcRangeRec(root, childMap, baseIndex);
+
+ //SLANG_ASSERT(_checkSubClassRange(typeInfos, typeInfoCount));
+}
+
+} // namespace Slang