diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-09-30 13:28:56 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-30 13:28:56 -0400 |
| commit | 274c20a5eb133779a9d890ca79120815fb92b04e (patch) | |
| tree | 50f8074917a102b25a7f34adeacffaf185d59242 /source/slang/slang-serialize-reflection.cpp | |
| parent | 94d3f2bd9c5557658751f73bc5fc443b41230d2c (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.cpp | 113 |
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 |
