From 4ad2e52662a00f7d8b25be6d451bba33ba62947f Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 6 Oct 2020 17:07:22 -0400 Subject: Use Reflection for (Serial)RefObject Serialization (#1567) * 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. * Improve output of type names that are in scopes in C++ extractor. Update premake5.lua to run generation for RefObject derived types. * C++ extractor working on RefObject type. * Split out serialization functionality that spans different types into slang-serialization-factory.cpp/.h Put AST type info into header. Removed RefObjectSerialSubType - use RefObjectType Add filtering for RefObject derived types Remove construction and filteringhacks. * Set up field serialization for SerialRefObject derived types. * Fix template problem compiling on Clang/Gcc * Work in progress to make Value types work. * Added slang-value-reflect.cpp --- source/slang/slang-ref-object-reflect.cpp | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 source/slang/slang-ref-object-reflect.cpp (limited to 'source/slang/slang-ref-object-reflect.cpp') diff --git a/source/slang/slang-ref-object-reflect.cpp b/source/slang/slang-ref-object-reflect.cpp new file mode 100644 index 000000000..caf8eb6a3 --- /dev/null +++ b/source/slang/slang-ref-object-reflect.cpp @@ -0,0 +1,85 @@ +#include "../../slang.h" + +#include "slang-ref-object-reflect.h" + +#include "slang-ref-object-generated.h" +#include "slang-ref-object-generated-macro.h" + +#include "slang-ast-support-types.h" + +//#include "slang-serialize.h" + +#include "slang-serialize-ast-type-info.h" + +namespace Slang +{ + +static const SerialClass* _addClass(SerialClasses* serialClasses, RefObjectType type, RefObjectType super, const List& fields) +{ + const SerialClass* superClass = serialClasses->getSerialClass(SerialTypeKind::RefObject, SerialSubType(super)); + return serialClasses->add(SerialTypeKind::RefObject, SerialSubType(type), fields.getBuffer(), fields.getCount(), superClass); +} + +#define SLANG_REF_OBJECT_ADD_SERIAL_FIELD(FIELD_NAME, TYPE, param) fields.add(SerialField::make(#FIELD_NAME, &obj->FIELD_NAME)); + +// Note that the obj point is not nullptr, because some compilers notice this is 'indexing from null' +// and warn/error. So we offset from 1. +#define SLANG_REF_OBJECT_ADD_SERIAL_CLASS(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \ +{ \ + NAME* obj = SerialField::getPtr(); \ + SLANG_UNUSED(obj); \ + fields.clear(); \ + SLANG_FIELDS_RefObject_##NAME(SLANG_REF_OBJECT_ADD_SERIAL_FIELD, param) \ + _addClass(serialClasses, RefObjectType::NAME, RefObjectType::SUPER, fields); \ +} + +struct RefObjectAccess +{ + template + static void* create(void* context) + { + SLANG_UNUSED(context) + return new T; + } + + static void calcClasses(SerialClasses* serialClasses) + { + // Add SerialRefObject first, and specially handle so that we add a null super class + serialClasses->add(SerialTypeKind::RefObject, SerialSubType(RefObjectType::SerialRefObject), nullptr, 0, nullptr); + + // Add the rest in order such that Super class is always added before its children + List fields; + SLANG_CHILDREN_RefObject_SerialRefObject(SLANG_REF_OBJECT_ADD_SERIAL_CLASS, _) + } +}; + +#define SLANG_GET_SUPER_BASE(SUPER) nullptr +#define SLANG_GET_SUPER_INNER(SUPER) &SUPER::kReflectClassInfo +#define SLANG_GET_SUPER_LEAF(SUPER) &SUPER::kReflectClassInfo + +#define SLANG_GET_CREATE_FUNC_NONE(NAME) nullptr +#define SLANG_GET_CREATE_FUNC_OBJ_ABSTRACT(NAME) nullptr +#define SLANG_GET_CREATE_FUNC_OBJ(NAME) &RefObjectAccess::create + +#define SLANG_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) \ + /* static */const ReflectClassInfo NAME::kReflectClassInfo = { uint32_t(RefObjectType::NAME), uint32_t(RefObjectType::LAST), SLANG_GET_SUPER_##TYPE(SUPER), #NAME, SLANG_GET_CREATE_FUNC_##MARKER(NAME), nullptr, uint32_t(sizeof(NAME)), uint8_t(SLANG_ALIGN_OF(NAME)) }; + +SLANG_ALL_RefObject_SerialRefObject(SLANG_REFLECT_CLASS_INFO, _) + +/* static */const SerialRefObjects SerialRefObjects::g_singleton; + +// Macro to set all of the entries in m_infos for SerialRefObjects +#define SLANG_GET_REFLECT_CLASS_INFO(NAME, SUPER, ORIGIN, LAST, MARKER, TYPE, param) m_infos[Index(RefObjectType::NAME)] = &NAME::kReflectClassInfo; + +SerialRefObjects::SerialRefObjects() +{ + SLANG_ALL_RefObject_SerialRefObject(SLANG_GET_REFLECT_CLASS_INFO, _) +} + +/* static */SlangResult SerialRefObjects::addSerialClasses(SerialClasses* serialClasses) +{ + RefObjectAccess::calcClasses(serialClasses); + return SLANG_OK; +} + +} // namespace Slang -- cgit v1.2.3