Sync knowledge base structure

This commit is contained in:
vczh
2026-06-18 11:48:58 -07:00
parent 9d67c11bae
commit d539742d41
10 changed files with 670 additions and 632 deletions
File diff suppressed because it is too large Load Diff
+151
View File
@@ -0,0 +1,151 @@
# GacUI Knowledge Base
Project introduction remains in [Index.md](./Index.md#gacui).
### Choosing APIs
#### Remote Protocol Unit Test Framework
Testing GacUI applications without real OS windows or rendering, using the remote protocol architecture with a mock renderer (`UnitTestRemoteProtocol`) that captures rendering snapshots and simulates user input.
- Use `GacUIUnitTest_Initialize` and `GacUIUnitTest_Finalize` for global test executable setup and teardown.
- Use `GacUIUnitTest_SetGuiMainProxy` to register frame-based test callbacks per test case.
- Use `GacUIUnitTest_LinkGuiMainProxy` for decorator-style proxy chaining to compose setup layers.
- Use `GacUIUnitTest_StartFast_WithResourceAsText<Theme>` for the most common entry point that compiles XML resources, registers themes, creates windows, and runs the application.
- Use `GacUIUnitTest_Start` and `GacUIUnitTest_StartAsync` for synchronous and async protocol stack tests.
- Use `OnNextIdleFrame(name, callback)` on `UnitTestRemoteProtocol` to register frame callbacks; the name describes the rendering result, not the upcoming action.
- Use `LocationOf(controlOrComposition)` to compute absolute screen coordinates for input simulation.
- Use `LClick`, `RClick`, `MClick`, `LDBClick`, `MouseMove` for mouse input simulation.
- Use `KeyPress`, `KeyDown`, `KeyUp`, `TypeString` for keyboard input simulation.
- Use `TryFindObjectByName<T>(window, name)` to look up named controls from GacUI XML resources.
- Use `GetApplication()->InvokeInMainThread` to defer IO actions that would trigger blocking functions like `ShowDialog`.
[API Explanation](./KB_GacUI_RemoteProtocolUnitTestFramework.md)
### Design Explanation
#### Platform Initialization and Multi-Platform Architecture
- GacUI implements a sophisticated multi-platform initialization system that provides consistent API across different operating systems and rendering backends while maintaining platform-specific optimizations.
- The initialization process follows a layered architecture from platform entry points through renderer setup to application framework. It supports:
- Windows Direct2D/GDI
- Linux GTK
- macOS Cocoa
- remote rendering for testing
- hosted mode for embedded applications.
- The system uses a consistent naming pattern `Setup[Platform][Renderer][Mode]()` with standard mode providing full application framework, hosted mode running within a single native window, and raw mode bypassing GuiApplication entirely.
- Key features include hardware acceleration fallbacks, comprehensive error handling, frame-based unit testing through remote mode, and systematic service registration with proper dependency management.
[Design Explanation](./KB_GacUI_Design_PlatformInitialization.md)
#### Main Window and Modal Window Management
- GacUI provides a sophisticated multi-layered window management architecture that enables consistent main window and modal window behavior across all supported platforms while maintaining platform-specific optimizations.
- The application loop operates through hierarchical delegation from `GuiApplication` layer down to platform-specific `INativeWindowService` implementations, supporting Windows native, hosted mode, and remote mode environments.
- Modal windows achieve apparent "blocking" behavior without actually blocking the underlying event processing system through an event-driven callback architecture that maintains full user interaction capabilities.
- The system supports three modal window variants: `ShowModal` for basic modal behavior, `ShowModalAndDelete` for automatic cleanup, and `ShowModalAsync` for modern async/await integration patterns.
- Cross-platform consistency is maintained through unified modal APIs, continuous message loop processing, and platform-optimized implementations that abstract differences while providing rich windowing capabilities.
[Design Explanation](./KB_GacUI_Design_MainWindowModalWindow.md)
#### Implementing IGuiGraphicsElement
- Defines element lifecycle via `IGuiGraphicsElement`, `IGuiGraphicsRenderer`, renderer factories, and render targets.
- Uses `GuiElementBase<T>` pattern with property change notifications through `InvokeOnElementStateChanged` for invalidation and size recalculation.
- Renderer abstraction supplies hooks (`InitializeInternal`, `FinalizeInternal`, `RenderTargetChangedInternal`, `Render`, `OnElementStateChanged`, `GetMinSize`) and caches platform resources.
- Parallel renderer families per backend (Direct2D, GDI, Remote/Hosted) registered in backend initialization via static `Register()`.
- Composition + host rendering pipeline traverses compositions, applies clippers, calls element renderers; invalidation chain from property setter to `GuiGraphicsHost::Render`.
- Provides checklist, lifecycle summary, common pitfalls, and distinction from complex `GuiDocumentElement` model-based rendering architecture.
[Design Explanation](./KB_GacUI_Design_ImplementingIGuiGraphicsElement.md)
#### Layout and GuiGraphicsComposition
- Core layout system centered on `GuiGraphicsComposition` with measurement (`Layout_CalculateMinSize`) and arrangement (`Layout_CalculateBounds`) passes driven only by host render loop invalidation.
- Three subclass archetypes (`_Trivial`, `_Controlled`, `_Specialized`) define ownership of size calculation and parent-child constraint propagation.
- Eight predefined layout families (Bounds, Table, Stack, Flow, Shared Size, Side Aligned, Partial View, Window Root) plus responsive (`GuiResponsive*`) adaptive level-based system.
- Bidirectional constraints: parent supplies space; children optionally enlarge parent via `Layout_CalculateMinClientSizeForParent`; controlled items receive bounds from parent setters.
- Invalidation via `InvokeOnCompositionStateChanged`; `GuiGraphicsHost::Render` iteratively recalculates until stable; `ForceCalculateSizeImmediately` only for interactive latency.
- Responsive compositions add multi-level adaptive switching with aggregation strategies (View, Stack, Group, Fixed) and automatic container adjustment.
[Design Explanation](./KB_GacUI_Design_LayoutAndGuiGraphicsComposition.md)
#### Control Focus Switching and TAB/ALT Handling
- Three-layered architecture from composition focus (`GuiGraphicsHost`) through control focus (`GuiControl`) to automatic clearing on state changes.
- TAB navigation managed by `GuiTabActionManager` with `IGuiTabAction` service, prioritized control list building, wrapping navigation logic, and character suppression.
- ALT navigation managed by `GuiAltActionManager` with `IGuiAltAction` service, nested ALT host hierarchy (`IGuiAltActionHost`), visual label creation, and prefix-based key filtering.
- Critical `continue` barrier in `CollectAltActionsFromControl` blocks children from parent-level collection when control has ALT action, enabling nested context pattern.
- Custom `GetActivatingAltHost` implementations handle non-child relationships (menu popups), intentional blocking (combo boxes), dynamic content (grid editors), and scoped navigation (ribbon groups, date pickers).
- Event flow integration processes ALT before TAB in key event chain, with character suppression for both managers in character event chain.
[Design Explanation](./KB_GacUI_Design_ControlFocusSwitchingAndTabAltHandling.md)
#### List Control Architecture
- Three-layer architecture separates data management (`IItemProvider` with view system), layout arrangement (`IItemArranger` with virtual repeat composition), and visual rendering (item templates with background wrapping).
- Item lifecycle from creation (`InstallStyle`) through property updates to destruction (`UninstallStyle`) with event translation from compositions to item-level events via `ItemCallback`.
- Virtual repeat composition system delegates to `GuiVirtualRepeatCompositionBase` with four arranger types (free height, fixed height, fixed size multi-column, fixed height multi-column) supporting efficient virtualization.
- Provider hierarchy includes concrete providers (holding actual data), bindable providers (wrapping observable data sources via reflection), and converter providers (transforming tree to list via `NodeItemProvider`).
- Selection management in `GuiSelectableListControl` handles multi-selection with ctrl/shift modifiers, synchronizes with item templates, and provides keyboard navigation with special right-click behavior.
- Specialized controls (`GuiVirtualTextList`, `GuiVirtualListView`, `GuiVirtualTreeView`, `GuiVirtualDataGrid`, combo boxes, ribbon galleries) with view-specific templates and default implementations.
- Scroll view integration with size calculation (`QueryFullSize`), view updates (`UpdateView`), adopted size for responsive layouts, and lifecycle management (`OnRenderTargetChanged`).
- Template and arranger coordination through `SetStyleAndArranger` process with detach/clear/update/attach phases, `PredefinedListItemTemplate` pattern, and display item background wrapping.
- Data grid advanced features with visualizer system (cell rendering customization via decorator pattern), editor system (in-place editing with keyboard/mouse integration), sorter system (multi-level sorting with stable ordering), and filter system (row filtering with AND/OR/NOT composition).
[Design Explanation](./KB_GacUI_Design_ListControlArchitecture.md)
#### Adding a New Control
- Coordinated changes across control class definition, template system, theme management, reflection registration, and XML compiler integration.
- Control class inherits from `GuiControl` and `Description<T>`, specifies template type via macro, overrides lifecycle methods, attaches event handlers to `boundsComposition`, and defines events/properties.
- Template system with declaration in `GuiControlTemplates.h` using macro expansion, property definition macros, auto-generated implementations including getters/setters/change events.
- Inheritance pattern for derived controls using parent template as base, selective lifecycle override, and attachment to parent events instead of re-implementing handlers.
- Reflection registration in three steps: type list addition, control class registration with base/constructor/members, automatic template registration.
- XML loader registration via `ADD_TEMPLATE_CONTROL` or `ADD_VIRTUAL_CONTROL` for themed variants.
- Theme integration through `GUI_CONTROL_TEMPLATE_TYPES` macro generating `ThemeName` enum values.
- Minimal working example demonstrates complete lifecycle from class definition through template, theme, reflection, to XML loader registration.
- File modification checklist covers 10+ files across Controls, Templates, Application, Reflection, and Compiler directories.
- Header organization requires updates to `IncludeForward.h` and `IncludeAll.h` for proper compilation order.
[Design Explanation](./KB_GacUI_Design_AddingNewControl.md)
#### Hosted Mode Window Management
- Hosted mode runs the entire GUI application inside a single OS native window, virtualizing all sub-windows, dialogs, popups, and menus as graphics within that window.
- `GuiHostedController` is the central class wrapping a real native controller, implementing its own window manager, input dispatching, and service delegation while replacing the global `INativeController`.
- The window manager template `hosted_window_manager::WindowManager<T>` maintains z-ordered lists (ordinary and top-most), a parent-child tree, and handles activation, focus, hit testing, dragging, and resizing.
- `GuiHostedWindow` implements `INativeWindow` with a proxy pattern: `PlaceholderProxy` for unassigned windows, `MainProxy` delegating to the real native window, and `NonMainProxy` operating purely through the window manager.
- Input dispatching uses `HandleMouseCallback` templates with pluggable PreAction/GetSelectedWindow/PostAction strategies, and `HandleKeyboardCallback` routes to the active window.
- The rendering pipeline renders all hosted windows in a single begin/end session via `StartHostedRendering`/`StopHostedRendering`, with per-window offset via `GetRenderingOffset()`.
- Remote mode inherently requires hosted mode, with `GuiHostedController` wrapping `GuiRemoteController` in the same architecture.
[Design Explanation](./KB_GacUI_Design_HostedModeWindowManagement.md)
#### Remote Protocol Core Architecture
- Remote protocol mode separates GacUI into a core side (application logic) and a renderer side (rendering and OS services), communicating through `IGuiRemoteProtocol`.
- Messages flow core → renderer via `IGuiRemoteProtocolMessages`; events and responses flow renderer → core via `IGuiRemoteProtocolEvents`.
- `GuiRemoteMessages` provides synchronous batched request-response with auto-incrementing IDs and blocking `Submit()`.
- `GuiRemoteController` implements `INativeController` and all sub-services as virtual stubs: single window only, intentionally null clipboard/dialog services, synchronous key state queries.
- Connection lifecycle: `SetupRemoteNativeController` creates a layered stack (`GuiRemoteController``GuiHostedController` → resource managers), with connect/disconnect/reconnection handling that re-sends all window state.
- Rendering pipeline: element lifecycle via ID allocation, diff-based element updates, frame rendering flow (`StartRenderingOnNativeWindow` → traversal → `StopRenderingOnNativeWindow`), and measurement feedback loop (font heights, min sizes, image metadata, inline object bounds).
- `GuiRemoteGraphicsParagraph` handles rich text with run property system, incremental diff synchronization, delegated layout queries, and caret bounds caching.
- DOM diff layer (`GuiRemoteProtocolDomDiffConverter`) converts per-frame command streams into diffed tree structures.
- Protocol combinator and filter layers enable composable transformations and traffic optimization via `[@DropRepeat]`/`[@DropConsecutive]` annotations.
- Channel layer (`IGuiRemoteProtocolChannel`, `GuiRemoteProtocolAsyncChannelSerializer`) supports real remote deployment with async IO on a separate thread.
[Design Explanation](./KB_GacUI_Design_RemoteProtocolCoreArchitecture.md)
#### Remote Protocol Renderer and Serialization
- `GuiRemoteRendererSingle` is the renderer-side implementation that bridges `IGuiRemoteProtocol` to a real native window with actual graphics rendering, relying on an existing platform provider (e.g., Windows Direct2D).
- It implements `IGuiRemoteProtocol` to receive protocol messages and translates them into native element operations, and implements `INativeWindowListener`/`INativeControllerListener` to forward OS events back as protocol events.
- Rendering pipeline: receives `RequestRendererBeginRendering` with `OrdinaryElementDescVariant` updates, applies them to real graphics elements, renders the DOM tree in `GlobalTimer()`, and returns measurement feedback via `RespondRendererEndRendering`.
- Event forwarding coalesces high-frequency events (mouse move, wheel, key auto-repeat) and sends discrete events immediately; hit testing is performed locally by traversing the rendering DOM tree.
- Layered channel architecture for protocol serialization: `IGuiRemoteProtocol``JsonObject` (via `GuiRemoteProtocolFromJsonChannel`/`GuiRemoteJsonChannelFromProtocol`) ↔ `WString` (via `JsonToStringSerializer`) ↔ user-implemented transport.
- JSON envelope format with `semantic`, `id`, `name`, `arguments` fields; protocol types code-generated from `Protocol/*.txt` with `JsonHelper<T>` specializations.
- `GuiRemoteProtocolAsyncChannelSerializer` provides thread separation (channel thread for IO, UI thread for application logic) with queued event delivery and connection-safe request matching.
- Demo project pair (`RemotingTest_Core` and `RemotingTest_Rendering_Win32`) demonstrates full protocol stack assembly for both core and renderer sides with named-pipe/HTTP transport.
[Design Explanation](./KB_GacUI_Design_RemoteProtocolRendererAndSerialization.md)
+160
View File
@@ -0,0 +1,160 @@
# Vlpp Knowledge Base
Project introduction remains in [Index.md](./Index.md#vlpp).
### Choosing APIs
#### String Types and Handling
Immutable string types for text processing across different encodings with UTF conversion capabilities.
- Use `WString` for general purpose wide character strings (UTF-16 on Windows, UTF-32 on other platforms)
- Use `AString` for ASCII string operations
- Use `U8String` for UTF-8 string handling
- Use `U16String` and `U32String` for specific UTF encoding requirements
- Use `ObjectString<T>` template when you need custom character types
- Use `Unmanaged`, `CopyFrom`, `TakeOver` static functions for string initialization
- Use `wtoi`, `wtoi64`, `wtou`, `wtou64` for string to integer conversion
- Use `itow`, `i64tou`, `utow`, `u64tow` for integer to string conversion
- Use `ftow`, `wtof` for double and string conversion
- Use `wupper`, `wlower` for case conversion
- Use `ConvertUtfString<From, To>` for template-based UTF string conversion
- Use `AtoB` functions (like `wtou8`, `u8tow`) for direct UTF encoding conversion
[API Explanation](./KB_Vlpp_StringTypes.md)
#### Exception Handling
Error reporting and exception management for fatal errors and recoverable conditions.
- Use `Error` base class for fatal errors that should never happen
- Use `Exception` base class for recoverable errors and control flow
- Use `CHECK_ERROR(condition, message)` to raise errors on assertion failures
- Use `CHECK_FAIL(message)` to raise errors without conditions
[API Explanation](./KB_Vlpp_ExceptionHandling.md)
#### Object Model and Memory Management
Reference counting smart pointers and object lifecycle management following specific inheritance patterns.
- Use `Object` base class for all reference types
- Use `Interface` base class for all interface types with virtual inheritance
- Use `Ptr<T>` for shared ownership of reference types instead of raw pointers
- Use `ComPtr<T>` for COM objects on Windows API
- Use `Nullable<T>` to add nullptr semantics to value types
- Use `struct` for value types and `class` for reference types
[API Explanation](./KB_Vlpp_ObjectModel.md)
#### Lambda Expressions and Callable Types
Function objects and event handling with type-safe callable containers.
- Use `Func<T(TArgs...)>` for function objects similar to std::function
- Use `Event<void(TArgs...)>` for multi-subscriber event handling
- Use lambda expressions for callbacks instead of native functions when possible
- Use `Func(callable-object)` for automatic type inference
[API Explanation](./KB_Vlpp_LambdaExpressions.md)
#### Primitive Value Types
Container types for organizing and manipulating related data values.
- Use `Pair<Key, Value>` for two-value tuples with key and value fields
- Use `Tuple<T...>` for multiple value organization without defining structs
- Use `Variant<T...>` for type-safe unions that can hold one of several types
- Use `Pair(k, v)` and `Tuple(a, b, c...)` for type inference
- Use `get<0>` method for tuple value access
- Use `Get<T>()`, `TryGet<T>()` for variant value access
- Use `Apply` with `Overloading` for variant type-specific handling
[API Explanation](./KB_Vlpp_PrimitiveTypes.md)
#### Date and Time Operations
Cross-platform date and time handling with timezone conversions and arithmetic operations.
- Use `DateTime::LocalTime()` and `DateTime::UtcTime()` for current time retrieval
- Use `DateTime::FromDateTime()` for creating specific date/time instances
- Use `ToLocalTime()` and `ToUtcTime()` for timezone conversions
- Use `Forward()` and `Backward()` for time arithmetic operations
- Use `InjectDateTimeImpl` to replace implementation for testing and customization
- Use `EjectDateTimeImpl` to remove injected implementations and restore previous ones
[API Explanation](./KB_Vlpp_DateTimeOperations.md)
#### Collection Types
Dynamic containers implementing IEnumerable interface with comprehensive manipulation capabilities.
- Use `Array<T>` for fixed-size collections with random access
- Use `List<T>` for dynamic arrays with insertion and removal operations
- Use `SortedList<T>` for automatically ordered collections
- Use `Dictionary<Key, Value>` for one-to-one key-value mappings
- Use `Group<Key, Value>` for one-to-many key-value relationships
- Use `Count()`, `Get(index)`, `Contains(value)`, `IndexOf(value)` for common operations
- Use `Add()`, `Insert()`, `Remove()`, `RemoveAt()`, `Clear()` for modification operations
- Use `Keys()`, `Values()` for dictionary access patterns
[API Explanation](./KB_Vlpp_CollectionTypes.md)
#### LINQ Operations
Functional programming operations on collections with lazy evaluation and method chaining.
Check out comments before `#ifndef VCZH_COLLECTIONS_OPERATION` for a full list of operators.
- Use `LazyList<T>` for LINQ-style operations on any IEnumerable collection
- Use `From(collection)` to create LazyList from collections
- Use method chaining with `Skip()`, `Reverse()`, `Where()`, `Select()` for data transformation
- Use `indexed` function for enumeration with index access
- Use range-based for loops with any IEnumerable implementation
[API Explanation](./KB_Vlpp_LinqOperations.md)
#### Sorting and Ordering
Algorithms for arranging data with support for both total and partial ordering relationships.
- Use `Sort(T*, vint)` for quick sort on raw pointer ranges
- Use lambda expressions returning `std::strong_ordering` or `std::weak_ordering` as comparators
- Use `PartialOrderingProcessor` for partial ordering scenarios where Sort doesn't work
- Use `<=>` operator to obtain ordering values for comparators
[API Explanation](./KB_Vlpp_SortingOrdering.md)
#### Console Operations
Basic input/output operations for console applications.
- Use `Console::Write` and `Console::WriteLine` for console output in CLI applications
- Use `Console::TryRead` for nullable line input that handles console input, redirection, and EOF
[API Explanation](./KB_Vlpp_ConsoleOperations.md)
#### Memory Leak Detection
Global storage management and memory leak detection for debugging and testing.
- Use `BEGIN_GLOBAL_STORAGE_CLASS`, `INITIALIZE_GLOBAL_STORAGE_CLASS`, `FINALIZE_GLOBAL_STORAGE_CLASS`, `END_GLOBAL_STORAGE_CLASS` for global variable management
- Use `FinalizeGlobalStorage()` before memory leak detection
- Use `GetStorageName().IsInitialized()` to check availability
- Use `_CrtDumpMemoryLeaks()` on Windows for leak detection
[API Explanation](./KB_Vlpp_MemoryLeakDetection.md)
#### Unit Testing Framework
Testing infrastructure with hierarchical test organization and assertion capabilities.
- Use `TEST_FILE` to define test file scope
- Use `TEST_CATEGORY(name)` for grouping related tests
- Use `TEST_CASE(name)` for individual test implementations
- Use `TEST_ASSERT(expression)` for test assertions
- Use nested `TEST_CATEGORY` for hierarchical organization
- Use `TEST_PRINT` for logging information to CLI in tests
[API Explanation](./KB_Vlpp_UnitTesting.md)
### Design Explanation
+151
View File
@@ -0,0 +1,151 @@
# VlppOS Knowledge Base
Project introduction remains in [Index.md](./Index.md#vlppos).
### Choosing APIs
#### Locale Support
Cross-platform localization and globalization with culture-aware string operations and formatting.
- Use `Locale::Invariant()` or `INVLOC` macro for culture-invariant operations
- Use `Locale::SystemDefault()` for OS code page interpretation
- Use `Locale::UserDefault()` for user language and location settings
- Use `Locale::Enumerate(locales)` to get all supported locales
- Use `Get*Formats` methods for date-time format enumeration
- Use `FormatDate` and `FormatTime` for locale-aware date/time formatting
- Use `Get*Name` methods for localized week day and month names
- Use `FormatNumber` and `FormatCurrency` for locale-aware number formatting
- Use `Compare`, `CompareOrdinal`, `CompareOrdinalIgnoreCase` for locale-aware string comparison
- Use `FindFirst`, `FindLast`, `StartsWith`, `EndsWith` for normalized string searching
- Use `InjectLocaleImpl` to replace `Locale` implementation for testing and customization
- Use `EjectLocaleImpl` to remove specific injected implementations or reset to default
- Use `EnUsLocaleImpl` class as platform-independent en-US fallback implementation
[API Explanation](./KB_VlppOS_LocaleSupport.md)
#### File System Operations
Cross-platform file and directory manipulation with path handling and content access.
- Use `FilePath` for path representation and manipulation
- Use `GetName`, `GetFolder`, `GetFullPath`, `GetRelativePathFor` for path operations
- Use `IsFile`, `IsFolder`, `IsRoot` to determine path object types
- Use `File` class for file operations when `FilePath::IsFile` returns true
- Use `ReadAllTextWithEncodingTesting`, `ReadAllTextByBom`, `ReadAllLinesByBom` for text reading
- Use `WriteAllText`, `WriteAllLines` for text writing
- Use `Exists`, `Delete`, `Rename` for file operations
- Use `Folder` class for directory operations when `FilePath::IsFolder` or `FilePath::IsRoot` returns true
- Use `GetFolders`, `GetFiles` for directory content enumeration
- Use `Create` for creating new folders
- Use `InjectFileSystemImpl` to replace file system implementation for testing and customization
- Use `EjectFileSystemImpl` to remove specific injected implementations or reset to default
[API Explanation](./KB_VlppOS_FileSystemOperations.md)
#### Stream Operations
Unified stream interface for file, memory, and data transformation operations with encoding support.
- Use `IStream` interface for all stream operations
- Use `FileStream` for file I/O with `ReadOnly`, `WriteOnly`, `ReadWrite` modes
- Use `MemoryStream` for in-memory buffer operations
- Use `MemoryWrapperStream` for operating on existing memory buffers
- Use `EncoderStream` and `DecoderStream` for data transformation pipelines
- Use `IsAvailable`, `CanRead`, `CanWrite`, `CanSeek`, `IsLimited` for capability checking
- Use `Read`, `Write`, `Peek`, `Seek`, `Position`, `Size` for stream operations
- Use `Close` for resource cleanup (automatic on destruction)
[API Explanation](./KB_VlppOS_StreamOperations.md)
#### Encoding and Decoding
Text encoding conversion between different UTF formats with BOM support and binary data encoding.
- Use `BomEncoder` and `BomDecoder` for UTF encoding with BOM support
- Use `UtfGeneralEncoder<Native, Expect>` and `UtfGeneralDecoder<Native, Expect>` for UTF conversion without BOM
- Use `Utf8Encoder`, `Utf8Decoder`, `Utf16Encoder`, `Utf16Decoder`, `Utf16BEEncoder`, `Utf16BEDecoder`, `Utf32Encoder`, `Utf32Decoder` for specific UTF conversions
- Use `MbcsEncoder` and `MbcsDecoder` for ASCII/MBCS conversion
- Use `TestEncoding` for automatic encoding detection
- Use `Utf8Base64Encoder` and `Utf8Base64Decoder` for Base64 encoding in UTF-8
- Use `LzwEncoder` and `LzwDecoder` for data compression
- Use `CopyStream`, `CompressStream`, `DecompressStream` helper functions
[API Explanation](./KB_VlppOS_EncodingDecoding.md)
#### Additional Streams
Specialized stream types for caching, recording, and broadcasting data operations.
- Use `CacheStream` for performance optimization with non-random accessed data, although it supports random accessing if the underlying stream does
- Use `RecorderStream` for copying data from one stream to another during reading
- Use `BroadcastStream` for writing the same data to multiple target streams
- Use `Targets()` method to manage BroadcastStream destinations
[API Explanation](./KB_VlppOS_AdditionalStreams.md)
#### Multi-threading
Cross-platform threading primitives and synchronization mechanisms for concurrent programming.
- Use `ThreadPoolLite::Queue` and `ThreadPoolLite::QueueLambda` for thread pool execution
- Use `TaskQueue` when queued work must run on one blocking task loop instead of the thread pool
- Use `Thread::Sleep` for thread pausing
- Use `Thread::GetCurrentThreadId` for thread identification
- Use `Thread::CreateAndStart` only when thread pool is insufficient
[API Explanation](./KB_VlppOS_MultiThreading.md)
#### Synchronization Primitives
Non-waitable synchronization objects for protecting shared resources in multi-threaded environments.
- Use `SpinLock` for protecting very fast code sections
- Use `CriticalSection` for protecting time-consuming code sections
- Use `ReaderWriterLock` for multiple reader, single writer scenarios
- Use `Enter`, `TryEnter`, `Leave` for manual lock management
- Use `SPIN_LOCK`, `CS_LOCK`, `READER_LOCK`, `WRITER_LOCK` macros for exception-safe automatic locking
- Use `ConditionVariable` with `SleepWith`, `SleepWithForTime` for conditional waiting
- Use `WakeOnePending`, `WaitAllPendings` for condition variable signaling
[API Explanation](./KB_VlppOS_SynchronizationPrimitives.md)
#### Waitable Objects
Cross-process synchronization objects that support waiting operations with timeout capabilities.
- Use `Mutex` for cross-process mutual exclusion
- Use `Semaphore` for counting semaphore operations across processes
- Use `EventObject` for event signaling across processes
- Use `Create` and `Open` methods for establishing named synchronization objects
- Use `Wait`, `WaitForTime` for blocking operations with optional timeout
- Use `WaitAll`, `WaitAllForTime`, `WaitAny`, `WaitAnyForTime` for multiple object synchronization
- Use `Signal`, `Unsignal` for event object state management
- Use `Release` for releasing mutex and semaphore ownership
[API Explanation](./KB_VlppOS_WaitableObjects.md)
#### Inter-Process Network Protocols and Channels
Inter-process text transport and typed named-channel communication for applications that need client/server messaging, local server-side channel participants, batched package delivery, and optional Windows-only NamedPipe or HTTP transports.
- Use `INetworkProtocolServer`, `INetworkProtocolClient`, `INetworkProtocolConnection` and `INetworkProtocolCallback` for raw asynchronous text-message transport.
- Use `IChannelServer<TPackage>`, `IChannelClient<TPackage>`, `IChannel<TPackage>` and `IChannelReader<TPackage>` for typed named channels with client ids, direct sends, broadcasts and batched writes.
- Use `NetworkProtocolChannelServer<TPackage, TSerialization, TServerBase>`, `NetworkProtocolChannelClient<TPackage, TSerialization>` and `NetworkProtocolLocalChannelClient<TPackage, TSerialization>` for the default channel implementation over an `INetworkProtocol*` transport.
- Use `NamedPipeServer` / `NamedPipeClient` and `HttpServer` / `HttpClient` only when targeting Windows, because the current built-in NamedPipe and HTTP implementations are Windows-only.
- Use `HttpClientApi` and `HttpServerApi` when implementing or maintaining the Windows HTTP transport layer directly.
[API Explanation](./KB_VlppOS_InterProcessNetworkProtocolsAndChannels.md)
### Design Explanation
#### Implementing an Injectable Feature
- Linked-list based dependency injection mechanism enabling runtime replacement and extension of feature implementations while maintaining delegation capabilities
- Three core components: `IFeatureImpl` base interface, `FeatureImpl<TImpl>` template for type-safe delegation, and `FeatureInjection<TImpl>` manager for chain operations
- Standard implementation pattern with interface definition, default implementation, global management functions using static local variables for thread-safe singleton behavior
- Delegation mechanism through `Previous()` method allowing partial overrides and full delegation with LIFO injection structure and cascading ejection behavior
- Critical lifecycle guarantees where `EndInjection` only called during explicit operations, and restriction of injection/ejection to application-level code for proper ordering
- Real-world implementation demonstrated through DateTime system with platform-specific implementations and testing integration using mock implementations
[Design Explanation](./KB_Vlpp_Design_ImplementingInjectableFeature.md)
@@ -0,0 +1,7 @@
# VlppParser2 Knowledge Base
Project introduction remains in [Index.md](./Index.md#vlppparser2).
### Choosing APIs
### Design Explanation
@@ -0,0 +1,122 @@
# VlppReflection Knowledge Base
Project introduction remains in [Index.md](./Index.md#vlppreflection).
### 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](./KB_VlppReflection_CompilationLevels.md)
#### 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](./KB_VlppReflection_TypeMetadata.md)
#### 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](./KB_VlppReflection_TypeRegistrationStructure.md)
#### 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](./KB_VlppReflection_EnumRegistration.md)
#### 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](./KB_VlppReflection_StructRegistration.md)
#### 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` for external function constructors
- Use `CLASS_MEMBER_METHOD` for method registration with parameter names
- Use `CLASS_MEMBER_METHOD_OVERLOAD` for overloaded method registration
- Use `CLASS_MEMBER_EXTERNALMETHOD` for external function methods
- Use `CLASS_MEMBER_STATIC_METHOD` for static method registration
- Use `CLASS_MEMBER_EVENT` for event registration
- Use `CLASS_MEMBER_PROPERTY_READONLY`, `CLASS_MEMBER_PROPERTY` for property registration
- 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](./KB_VlppReflection_ClassInterfaceRegistration.md)
#### 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<T>
- 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<T>
- 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](./KB_VlppReflection_InterfaceProxy.md)
#### 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 primitive values.
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::GetAttributeValue` to inspect attribute content
[API Explanation](./KB_VlppReflection_AttributeRegistration.md)
### Design Explanation
+38
View File
@@ -0,0 +1,38 @@
# VlppRegex Knowledge Base
Project introduction remains in [Index.md](./Index.md#vlppregex).
### Choosing APIs
#### Pattern Matching Operations
Text pattern matching and searching operations with support for different UTF encodings.
- Use `Regex_<T>` for pattern definition with `ObjectString<T>` encoding
- Use `MatchHead<U>` for finding longest prefix matching the pattern
- Use `Match<U>` for finding earliest substring matching the pattern
- Use `TestHead<U>` for boolean prefix matching without detailed results
- Use `Test<U>` for boolean substring matching without detailed results
- Use `Search<U>` for finding all non-overlapping matches
- Use `Split<U>` for using pattern as delimiter to split text
- Use `Cut<U>` for combined search and split operations
[API Explanation](./KB_VlppRegex_PatternMatching.md)
#### Type Aliases
Convenient type aliases for common character encodings to simplify regex usage.
- Use `RegexString` instead of `RegexString_<wchar_t>`
- Use `RegexMatch` instead of `RegexMatch_<wchar_t>`
- Use `Regex` instead of `Regex_<wchar_t>`
- Use `RegexToken` instead of `RegexToken_<wchar_t>`
- Use `RegexProc` instead of `RegexProc_<wchar_t>`
- Use `RegexTokens` instead of `RegexTokens_<wchar_t>`
- Use `RegexLexerWalker` instead of `RegexLexerWalker_<wchar_t>`
- Use `RegexLexerColorizer` instead of `RegexLexerColorizer_<wchar_t>`
- Use `RegexLexer` instead of `RegexLexer_<wchar_t>`
[API Explanation](./KB_VlppRegex_TypeAliases.md)
### Design Explanation
+19
View File
@@ -0,0 +1,19 @@
# Workflow Knowledge Base
Project introduction remains in [Index.md](./Index.md#workflow).
### Choosing APIs
### Design Explanation
#### Attribute System
Workflow script attributes (`@category:name`) are translated to reflected struct types following the naming convention `system::workflow_attributes::att_category_name`. The compiler resolves, evaluates, and populates attributes onto type descriptors during assembly generation, and the binary serialization format preserves attribute metadata across assembly load/save cycles. Predefined `@cpp:*` attributes control C++ code generation behavior.
- The naming convention is implemented by `WfLexicalScopeManager::GetWorkflowAttributeTypeName` in `Source/Analyzer/WfAnalyzer.cpp`.
- Predefined attributes include `@cpp:File`, `@cpp:UserImpl`, `@cpp:Private`, `@cpp:Protected`, and `@cpp:Friend`.
- Assembly population is performed by `PopulateAttributesForDeclarations` in `Source/Emitter/WfEmitter_Assembly.cpp`.
- Binary serialization is handled by `IOAttributeBag` in `Source/Runtime/WfRuntimeAssembly.cpp`.
- C++ code generation emits `ATTRIBUTE_TYPE` / `ATTRIBUTE_MEMBER` macros via `WriteAttributeMacro` in `Source/Cpp/WfCpp_WriteReflection.cpp`.
[Design Explanation](./KB_Workflow_Design_AttributeSystem.md)
+4 -3
View File
@@ -97,7 +97,8 @@ If you need to find any script files, they are in the `REPO-ROOT/.github/Ubuntu`
- When making design or coding decisions, you must leverage the knowledge base to make the best choice.
- The main entry is `REPO-ROOT/.github/KnowledgeBase/Index.md`, it is organized in this way:
- `## Guidance`: General guidance that plays an important role repo-wide.
- Each `## Project`: A brief description of each project and its purpose.
- Each `## Project`: A brief description of each project and its purpose, plus a link to `Index_<PROJECT>.md` for project-specific guidance.
- Each `Index_<PROJECT>.md`: Project-specific API and design guidance linked from the project section in `Index.md`.
- `### Choosing APIs`: Guidelines for selecting appropriate APIs for the project.
- `### Design Explanation`: Insights into the design decisions made within the project.
- `## Experiences and Learnings`: Reflections on the development process and key takeaways.
@@ -106,7 +107,7 @@ If you need to find any script files, they are in the `REPO-ROOT/.github/Ubuntu`
- Not every project is included.
- Manual for the unit test framework is in `## Unit Testing`.
### Project/Choosing APIs
### Index_<PROJECT>.md/Choosing APIs
There are multiple categories under `Choosing APIs`. Each category begins with a short and accurate title `#### Category`.
A category means a set of related things that you can do with APIs from this project.
@@ -119,7 +120,7 @@ If many classes or functions serve the same, or very similar purpose, one bullet
At the end of the category, there is a hyperlink: `[API Explanation](./KB_Project_Category.md)` (no space between file name, all PascalCase).
### Project/Design Explanation
### Index_<PROJECT>.md/Design Explanation
There are multiple topics under `Design Explanation`. Each topic begins with a short and accurate title `#### Topic`.
A topic means a feature of this project; it can involve multiple components combined.
+11 -9
View File
@@ -5,7 +5,8 @@
- The `Copilot_KB.md` file should already exist, it may or may not contain content from the last knowledge base writing.
- If you cannot find the file, you are looking at a wrong folder.
- Following `Leveraging the Knowledge Base` in `REPO-ROOT/.github/copilot-instructions.md`, find the knowledge and documents for this project in `REPO-ROOT/.github/KnowledgeBase/Index.md`.
- `Index.md` below means this file.
- `Index.md` below means the main entry file.
- `Index_<PROJECT>.md` below means the project-specific guidance file linked from the corresponding project section in `Index.md`.
## Goal and Constraints
@@ -27,7 +28,7 @@
- `## DRAFT REQUEST`: The exact copy of the draft request I gave you.
- `## IMPROVEMENTS`:
- `### IMPROVEMENT`: The exact copy of the improvement request I gave you.
- `## (API|DESIGN) EXPLANATION`: The title of the drafting KB document, and where to put the document in `Index.md` and surrounding anchors.
- `## (API|DESIGN) EXPLANATION`: The title of the drafting KB document, and where to put the document in `Index_<PROJECT>.md` and surrounding anchors.
- `## DOCUMENT`: The drafting KB document.
## Identify the Problem
@@ -113,16 +114,16 @@
- Keep everything before `# DRAFT` unchanged, DO NOT edit anything in it.
- Read everything before `# DRAFT` carefully, you are going to draft the document based on all information there, including necessary supporting materials mentioned there.
- Extra information is already copied to `## DRAFT REQUEST` if any.
- You are not going to edit `Index.md` at the moment, you are only editing `Copilot_KB.md`.
- You are not going to edit index files at the moment, you are only editing `Copilot_KB.md`.
### Decide the Type of the Document
- You are going to decide which project this document belongs to.
- You are going to decide the type of the document.
- Change `## (API|DESIGN) EXPLANATION` to `## API EXPLANATION (PROJECT)` if it is more about the usage and contract of APIs.
- It means eventually a new section will be added under `### Choosing APIs` under the specified project in `Index.md`.
- It means eventually a new section will be added under `### Choosing APIs` in the specified project's `Index_<PROJECT>.md`.
- Change `## (API|DESIGN) EXPLANATION` to `## DESIGN EXPLANATION (PROJECT)` if it is more about how a set of APIs are working together and the design and implementation of the source code.
- It means eventually a new section will be added under `### Design Explanation` under the specified project in `Index.md`.
- It means eventually a new section will be added under `### Design Explanation` in the specified project's `Index_<PROJECT>.md`.
- Fill the section to describe which part you will update in the knowledge base.
### Draft the Document
@@ -141,20 +142,21 @@
- Your goal is to update `## DOCUMENT` based on my suggestion.
- The finding I would like you to clarify is already copied to the last `### IMPROVEMENT`.
- You are not going to edit `Index.md` at the moment, you are only editing `Copilot_KB.md`.
- You are not going to edit index files at the moment, you are only editing `Copilot_KB.md`.
## Steps for Execute
- There is `## API EXPLANATION (PROJECT)` or `## DESIGN EXPLANATION (PROJECT)` section filled with the title and content of the document you drafted.
- If it is `## API EXPLANATION (PROJECT)`:
- A new section will be added under `### Choosing APIs` under the specified project in `Index.md`.
- A new section will be added under `### Choosing APIs` in the specified project's `Index_<PROJECT>.md`.
- At the end of the new section, a `[API Explanation]()` link is expected.
- If it is `## DESIGN EXPLANATION (PROJECT)`:
- A new section will be added under `### Design Explanation` under the specified project in `Index.md`.
- A new section will be added under `### Design Explanation` in the specified project's `Index_<PROJECT>.md`.
- At the end of the new section, a `[Design Explanation]()` link is expected.
- Create a new section in `Index.md`.
- Create a new section in the specified project's `Index_<PROJECT>.md`.
- Following `Leveraging the Knowledge Base` in `REPO-ROOT/.github/copilot-instructions.md` to figure out the expected format.
- The document is super long, you have to carefully figure out where is the exact place to add the new section.
- The main `Index.md` only keeps project introductions and links to `Index_<PROJECT>.md`; do not add API or design sections there.
- Use bullet points for the description of the topic to cover the most important points so that it will be easy to identify in the future if this topic is relevant to work to do.
- Create a document file according to the hyperlink.
- The title of the new document file should follow `## API EXPLANATION (PROJECT)` or `## DESIGN EXPLANATION (PROJECT)`.