Files
GacUI/.github/KnowledgeBase/Index_VlppReflection.md
T
2026-08-02 00:54:37 -07:00

7.7 KiB

VlppReflection Knowledge Base

Project introduction remains in Index.md.

Choosing APIs

Reflection Compilation Levels

Three different compilation modes for reflection support with varying runtime capabilities.

The reflection system supports three compilation levels:

  • Full reflection: Complete metadata and runtime support for type registration and function calls
  • Metadata-only (VCZH_DESCRIPTABLEOBJECT_WITH_METADATA): Type metadata without runtime support
  • No reflection (VCZH_DEBUG_NO_REFLECTION): Reflection disabled entirely Always prefer code compatible with VCZH_DEBUG_NO_REFLECTION when possible.

API Explanation

Type Metadata Access

Runtime type information retrieval and manipulation through the reflection system.

  • Use vl::reflection::description::GetTypeDescriptor<T> for type metadata access when reflection is enabled
  • Use vl::reflection::description::Value for boxing any value type similar to C# object or std::any
  • Use Description<T> base class for making classes reflectable
  • Use AggregatableDescription<T> for classes that can be inherited in Workflow scripts
  • Use IDescriptable interface for reflectable interfaces without other base interfaces

API Explanation

Metaonly Metadata Generation and Loading

Generate binary reflection metadata as either an independently loadable file or a layer that depends on types registered from previous files.

  • Use CollectRegisteredTypes after loading a base type manager to capture descriptors supplied by previous layers
  • Pass an empty exclusion list to GenerateMetaonlyTypes for a self-contained file
  • Pass a captured descriptor list to omit foreign metadata records while preserving references to those types
  • Load and activate every dependency before reading a dependent file with LoadMetaonlyTypes

API Explanation

Type Registration Structure

Organized approach for registering types with proper file organization and macro usage.

All type registration must occur in vl::reflection::description namespace with specific file organization:

  • Type lists and interface proxies in .h files
  • Type metadata registration in .cpp files
  • Registration code in dedicated files
  • Follow established patterns from existing source code examples

API Explanation

Enum Registration

Registration patterns for enumeration types with support for simple lists and combinable flags.

  • Use BEGIN_ENUM_ITEM and END_ENUM_ITEM for simple enumeration lists
  • Use BEGIN_ENUM_ITEM_MERGABLE and END_ENUM_ITEM for combinable flag enumerations
  • Use ENUM_CLASS_ITEM for enum class members
  • Use ENUM_ITEM for enum members
  • Use ENUM_ITEM_NAMESPACE and ENUM_NAMESPACE_ITEM for enums defined inside other types

API Explanation

Struct Registration

Registration patterns for structure types with field access capabilities.

  • Use BEGIN_STRUCT_MEMBER and END_STRUCT_MEMBER for struct registration
  • Use STRUCT_MEMBER to register each accessible field
  • Use ATTRIBUTE_TYPE, ATTRIBUTE_MEMBER to attach attributes to the struct or its fields

API Explanation

Class and Interface Registration

Comprehensive registration system for classes and interfaces with methods, properties, and events.

  • Use BEGIN_CLASS_MEMBER and END_CLASS_MEMBER for class registration
  • Use BEGIN_INTERFACE_MEMBER and END_INTERFACE_MEMBER for inheritable interfaces
  • Use BEGIN_INTERFACE_MEMBER_NOPROXY and END_INTERFACE_MEMBER for non-inheritable interfaces
  • Use CLASS_MEMBER_BASE for reflectable base class declaration
  • Use CLASS_MEMBER_FIELD for member field registration
  • Use CLASS_MEMBER_CONSTRUCTOR for constructor registration with Ptr<Class>(types...) or Class*(types...)
  • Use CLASS_MEMBER_EXTERNALCTOR, CLASS_MEMBER_EXTERNALCTOR_TEMPLATE for external function constructors
  • Use CLASS_MEMBER_METHOD, CLASS_MEMBER_METHOD_RENAME for method registration with parameter names
  • Use CLASS_MEMBER_METHOD_OVERLOAD, CLASS_MEMBER_METHOD_OVERLOAD_RENAME for overloaded method registration
  • Use CLASS_MEMBER_EXTERNALMETHOD, CLASS_MEMBER_EXTERNALMETHOD_TEMPLATE for external function methods
  • Use CLASS_MEMBER_STATIC_METHOD, CLASS_MEMBER_STATIC_METHOD_OVERLOAD for static method registration
  • Use CLASS_MEMBER_STATIC_EXTERNALMETHOD, CLASS_MEMBER_STATIC_EXTERNALMETHOD_TEMPLATE for global functions registered as static methods
  • Use CLASS_MEMBER_EVENT for event registration
  • Use CLASS_MEMBER_PROPERTY_READONLY, CLASS_MEMBER_PROPERTY for property registration
  • Use CLASS_MEMBER_PROPERTY_EVENT_READONLY, CLASS_MEMBER_PROPERTY_EVENT for properties with explicit getter/setter/event methods
  • Use CLASS_MEMBER_PROPERTY_REFERENCETEMPLATE for properties with custom generated C++ reference code
  • Use CLASS_MEMBER_PROPERTY_READONLY_FAST, CLASS_MEMBER_PROPERTY_FAST for standard getter/setter patterns
  • Use CLASS_MEMBER_PROPERTY_EVENT_READONLY_FAST, CLASS_MEMBER_PROPERTY_EVENT_FAST for properties with change events
  • Use NO_PARAMETER for parameterless functions
  • Use { L"arg1" _ L"arg2" ... } for parameter name lists
  • Use ATTRIBUTE_TYPE, ATTRIBUTE_MEMBER, ATTRIBUTE_PARAMETER to attach attributes to types, members, and parameters

API Explanation

Interface Proxy Implementation

Proxy generation for interfaces to enable inheritance in Workflow scripts.

  • Use BEGIN_INTERFACE_PROXY_NOPARENT_RAWPTR for interfaces without base interfaces using raw pointers
  • Use BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR for interfaces without base interfaces using Ptr
  • Use BEGIN_INTERFACE_PROXY_RAWPTR for interfaces with base interfaces using raw pointers
  • Use BEGIN_INTERFACE_PROXY_SHAREDPTR for interfaces with base interfaces using Ptr
  • Use END_INTERFACE_PROXY to complete proxy definition
  • Use INVOKE_INTERFACE_PROXY_NOPARAMS for void methods without parameters
  • Use INVOKEGET_INTERFACE_PROXY_NOPARAMS for return value methods without parameters
  • Use INVOKE_INTERFACE_PROXY for void methods with parameters
  • Use INVOKEGET_INTERFACE_PROXY for return value methods with parameters

API Explanation

Attribute Registration

Attach metadata attributes to types, members, and method parameters during reflection registration.

Attributes are instances of reflectable structs whose constructor arguments are serializable values, with ITypeDescriptor* as the explicit descriptor-reference exception. They are stored centrally in the owning type descriptor and can be queried at runtime via the IAttributeBag / IAttributeInfo interfaces. Attributes survive metaonly metadata serialization and deserialization, and appear in the logged text output.

  • Use ATTRIBUTE_TYPE(TYPE, ...) to attach an attribute to the enclosing type descriptor
  • Use ATTRIBUTE_MEMBER(TYPE, ...) to attach an attribute to the most recently registered member (field, property, event, method, or constructor)
  • Use ATTRIBUTE_PARAMETER(PARAMETER_NAME, TYPE, ...) to attach an attribute to a named parameter of the most recently registered method or constructor
  • Use IAttributeBag::GetAttributeCount and IAttributeBag::GetAttribute to query attributes at runtime
  • Use IAttributeInfo::GetAttributeType, IAttributeInfo::GetAttributeValueCount, IAttributeInfo::GetAttributeValueType, IAttributeInfo::GetAttributeValue to inspect attribute content

API Explanation

Design Explanation