GLW View System: Complete Source Analysis Summary¶
Status: 🟢 Comprehensive analysis complete
Last Updated: 2024
Movian Version: 4.8+
Overview¶
This document consolidates the findings from the complete source code analysis of the GLW (OpenGL Widget) view system. It provides a high-level understanding of how view files are processed from raw text to rendered widgets, covering the entire pipeline from file loading through preprocessing, lexing, parsing, evaluation, and rendering.
View File Processing Pipeline¶
graph TB
A[View File URL] --> B[Loader Widget]
B --> C[File Loading]
C --> D[Lexical Analysis]
D --> E[Preprocessing]
E --> F[Parsing]
F --> G[Attribute Resolution]
G --> H[Expression Evaluation]
H --> I[Widget Tree]
I --> J[Layout]
J --> K[Rendering]
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#e8f5e9
style D fill:#f3e5f5
style E fill:#fce4ec
style F fill:#e0f2f1
style G fill:#fff9c4
style H fill:#f1f8e9
style I fill:#e8eaf6
style J fill:#fce4ec
style K fill:#e1f5ff
Component Overview¶
1. File Loading System¶
File: glw_view_loader.c
Purpose: Dynamic view file loading with transitions
Key Responsibilities: - Load view files dynamically at runtime - Manage transitions between different views - Handle fallback URLs - Propagate scope ($args, $self) to loaded views - Auto-hide when no content is loaded
Core Widget: loader
Key Features: - Smooth transitions with configurable effects - Frame-rate independent animation - Automatic child lifecycle management - Scope propagation for data binding
Usage Example:
2. Preprocessing System¶
File: glw_view_preproc.c
Purpose: Macro expansion and file inclusion
Key Responsibilities: - Define and expand macros - Include files (#include) - Import files once (#import) - Support named and positional macro arguments - Handle default argument values
Directives:
- #define macroname(args) { body } - Define macro
- #include "file.view" - Include file (multiple times allowed)
- #import "file.view" - Import file (once only)
Macro Features:
- Named arguments: widget(name="test", width=100)
- Positional arguments: widget("test", 100)
- Default values: #define widget(name, width=100) { ... }
- Nested macro calls
- Recursive expansion
Usage Example:
#define button(label, width=100) {
container_x {
width = $width;
label { caption = $label; }
}
}
button("Click Me")
button("Wide Button", 200)
3. Lexical Analysis¶
File: glw_view_lexer.c
Purpose: Convert text to tokens
Key Responsibilities: - Tokenize view file text - Recognize keywords, identifiers, operators - Parse string literals and numbers - Track file and line information - Handle comments
Token Categories:
- Structural: {, }, (, ), [, ], ,, ;
- Operators: =, +, -, *, /, &&, ||, ==, !=, <, >
- Values: integers, floats, strings, identifiers
- Special: $ (variables), # (preprocessor), : (attributes)
Output: Token chain ready for preprocessing
4. Parsing System¶
File: glw_view_parser.c
Purpose: Build widget tree from tokens
Key Responsibilities: - Parse widget definitions - Build widget hierarchy - Resolve widget types - Parse attribute assignments - Handle blocks and expressions
Widget Definition Syntax:
Supported Constructs: - Widget instantiation - Attribute assignment (=, ?=, &=, !=, ~=) - Property references ($variable) - Nested widgets - Cloner patterns - Event handlers
5. Attribute System¶
File: glw_view_attrib.c
Purpose: Process widget attributes
Key Responsibilities: - Resolve attribute names to attribute IDs - Validate attribute types - Convert values to appropriate types - Handle attribute-specific processing - Support dynamic attributes
Attribute Types: - Integer: width, height, align, etc. - Float: alpha, blur, saturation, etc. - String: id, source, caption, etc. - Color: color, backgroundColor, etc. - Expression: Evaluated dynamically - Property: Property bindings
Attribute Resolution:
6. Expression Evaluation¶
File: glw_view_eval.c
Purpose: Evaluate expressions and bindings
Key Responsibilities: - Evaluate mathematical expressions - Resolve property references - Handle function calls - Manage property subscriptions - Update bindings dynamically
Expression Types:
- Arithmetic: $width * 2 + 10
- Logical: $enabled && $visible
- Comparison: $count > 0
- Ternary: $condition ? value1 : value2
- Function calls: translate($text)
- Property access: $page.model.title
Evaluation Modes: - Static: Evaluated once at parse time - Dynamic: Re-evaluated when properties change - RPN: Reverse Polish Notation for efficiency
7. Support Utilities¶
File: glw_view_support.c
Purpose: Token manipulation utilities
Key Responsibilities: - Allocate/free tokens - Copy/clone tokens and chains - Convert tokens to strings (debugging) - Print token trees - Error reporting - Property name conversion
Core Functions:
- glw_view_token_alloc() - Allocate token
- glw_view_token_free() - Free token
- glw_view_token_copy() - Copy single token
- glw_view_clone_chain() - Deep copy token chain
- glw_view_free_chain() - Free token chain
- token2name() - Token to string
- glw_view_print_tree() - Debug print
- glw_view_seterr() - Error reporting
Complete Processing Flow¶
Step-by-Step Execution¶
-
View File Request
-
File Loading (
glw_view_loader.c) - Resolves file path
- Reads file content
-
Creates initial token stream
-
Lexical Analysis (
glw_view_lexer.c) - Converts text to tokens
- Tracks line numbers
-
Handles string escaping
-
Preprocessing (
glw_view_preproc.c) - Expands macros
- Includes files
-
Imports definitions
-
Parsing (
glw_view_parser.c) - Creates widget instances
- Builds hierarchy
-
Parses attributes
-
Attribute Resolution (
glw_view_attrib.c) - Maps names to IDs
- Validates types
-
Converts values
-
Expression Evaluation (
glw_view_eval.c) - Evaluates expressions
- Creates property bindings
-
Sets up subscriptions
-
Widget Instantiation
- Calls widget constructors
- Initializes state
-
Adds to parent
-
Layout (various widget files)
- Calculates sizes
- Positions children
-
Handles constraints
-
Rendering (
glw_renderer.c)- Renders widgets
- Applies effects
- Handles transitions
Data Structures¶
Token Structure¶
typedef struct token {
token_type_t type; // Token type
struct token *next; // Next token in chain
struct token *child; // Child token chain
rstr_t *file; // Source file
int line; // Line number
union {
int t_int; // Integer value
float t_float; // Float value
rstr_t *t_rstring; // String value
prop_t *t_prop; // Property reference
glw_attribute_t t_attrib; // Attribute ID
// ... other type-specific fields
};
} token_t;
Widget Structure¶
typedef struct glw {
glw_class_t *glw_class; // Widget class
glw_t *glw_parent; // Parent widget
TAILQ_HEAD(, glw) glw_childs; // Children
TAILQ_ENTRY(glw) glw_parent_link;
glw_scope_t *glw_scope; // Variable scope
float glw_alpha; // Alpha value
int glw_flags; // Flags
// ... widget-specific data
} glw_t;
Scope Structure¶
typedef struct glw_scope {
int refcount;
struct {
prop_t *p; // Property
prop_sub_t *s; // Subscription
} gs_roots[GLW_ROOT_num];
} glw_scope_t;
Scope Roots:
- GLW_ROOT_SELF - $self (current item)
- GLW_ROOT_PARENT - $parent (parent scope)
- GLW_ROOT_ARGS - $args (arguments)
- GLW_ROOT_CLONE - $clone (cloner context)
- GLW_ROOT_VIEW - $view (view context)
Key Concepts¶
Property Binding¶
Concept: Link widget attributes to property values
Mechanism:
1. Parse property reference: $page.model.title
2. Resolve property path
3. Create subscription
4. Update attribute when property changes
Example:
Flow:
Macro Expansion¶
Concept: Reusable view fragments with parameters
Mechanism: 1. Define macro with parameters 2. Parse macro body 3. On invocation, bind arguments 4. Clone and expand body 5. Insert into token stream
Example:
#define card(title, image) {
container_y {
image { source = $image; }
label { caption = $title; }
}
}
card("My Title", "icon.png")
Expansion:
Dynamic Loading¶
Concept: Load views at runtime based on data
Mechanism: 1. Loader widget monitors source property 2. When source changes, load new view 3. Transition out old view 4. Transition in new view 5. Destroy old view when hidden
Example:
Flow:
Scope Propagation¶
Concept: Pass data context to child views
Mechanism: 1. Parent creates scope with $args 2. Loader passes scope to loaded view 3. View accesses $args.property 4. Changes propagate through bindings
Example:
<!-- Parent -->
<loader source="item.view" args="$item"/>
<!-- item.view -->
<label caption="$args.title"/>
Performance Considerations¶
Memory Management¶
- Token Pool: Fast allocation/deallocation
- Reference Counting: Shared strings and properties
- Scope Retention: Scopes retained for widget lifetime
- Chain Cloning: Can be expensive for large macros
Subscription Management¶
- Lazy Evaluation: Expressions evaluated only when needed
- Subscription Batching: Multiple updates batched per frame
- Suspension: Inactive widgets suspend subscriptions
- Cleanup: Subscriptions released when widgets destroyed
Rendering Optimization¶
- Dirty Tracking: Only re-render changed widgets
- Culling: Skip rendering of off-screen widgets
- Batching: Batch similar rendering operations
- Caching: Cache computed layouts
Preprocessing Optimization¶
- Import vs Include: Use #import for shared definitions
- Macro Complexity: Keep macros simple to reduce expansion cost
- File Organization: Structure files to minimize includes
Common Patterns¶
Conditional Rendering¶
List Rendering¶
<list_y>
<cloner source="$items">
<container_x>
<label caption="$self.title"/>
</container_x>
</cloner>
</list_y>
Reusable Components¶
#define listItem(title, subtitle) {
container_x {
container_y {
label { caption = $title; }
label { caption = $subtitle; }
}
}
}
Dynamic Content¶
Event Handling¶
<container_x focusable="true"
onEvent(activate, navOpen($self.url))>
<label caption="$self.title"/>
</container_x>
Error Handling¶
Lexer Errors¶
- Unterminated strings
- Invalid characters
- Malformed numbers
Preprocessor Errors¶
- Invalid macro syntax
- Missing files
- Circular includes
- Argument count mismatch
Parser Errors¶
- Unexpected tokens
- Unmatched braces
- Invalid widget types
- Malformed expressions
Runtime Errors¶
- Property not found
- Type mismatches
- Division by zero
- Invalid function calls
Error Reporting¶
All errors include: - File name - Line number - Error description - Context information
Example:
Debugging Techniques¶
Token Tree Printing¶
Output:
<start> 0x12345678 (main.view:1)
container_x 0x12345679 (main.view:2)
width: 0x1234567a (main.view:3)
= 0x1234567b (main.view:3)
100 0x1234567c (main.view:3)
Debug Logging¶
Enable GLW debug flag:
Output:
GLW: myWidget: Loader loading views/content.view
GLW: myWidget: Property subscription created for $page.model.title
GLW: myWidget: Attribute width set to 100
Property Inspection¶
Use debug assignment:
Logs property value changes.
View File Validation¶
Check syntax before loading: 1. Verify braces match 2. Check attribute names 3. Validate expressions 4. Test with simple data
Best Practices¶
File Organization¶
views/
├── common/
│ ├── macros.view # Macro definitions
│ ├── header.view # Common header
│ └── footer.view # Common footer
├── pages/
│ ├── home.view # Home page
│ ├── settings.view # Settings page
│ └── about.view # About page
└── components/
├── button.view # Button component
└── list-item.view # List item component
Macro Design¶
- Keep macros simple and focused
- Use descriptive parameter names
- Provide sensible defaults
- Document macro purpose
- Avoid deep nesting
Property Binding¶
- Use specific property paths
- Avoid complex expressions in bindings
- Cache computed values
- Use conditional rendering wisely
Performance¶
- Minimize file includes
- Use #import for shared code
- Keep widget trees shallow
- Avoid unnecessary subscriptions
- Use autohide for conditional content
Maintainability¶
- Use consistent naming conventions
- Comment complex logic
- Organize files logically
- Keep view files focused
- Reuse components via macros
Integration Points¶
Plugin System¶
Plugins can: - Create pages with custom views - Provide view URLs dynamically - Pass data via $args - Handle events from views
Example:
page.appendItem("", "separator", {
title: "My Item",
viewUrl: "plugin://myplugin/views/item.view"
});
Property System¶
Views bind to properties: - Page properties ($page.) - Global properties ($global.) - Plugin properties ($self.*)
Example:
Event System¶
Views can: - Handle user events (activate, cancel, etc.) - Fire navigation events - Trigger plugin actions
Example:
Theme System¶
Views can: - Reference theme variables - Override theme styles - Adapt to different themes
Example:
Related Documentation¶
Source Analysis¶
- glw_view_loader.c.md - File loading and transitions
- glw_view_preproc.c.md - Preprocessing and macros
- glw_view_support.c.md - Token utilities
- glw_view_lexer.c.md - Lexical analysis
- glw_view_parser.c.md - Parsing
- glw_view_attrib.c.md - Attribute processing
- glw_view_eval.c.md - Expression evaluation
Architecture¶
- ../glw-architecture.md - GLW system overview
- ../rendering-pipeline.md - Rendering process
Guides¶
- ../../plugins/api/core-api.md - Plugin API
- ../../reference/glossary.md - Technical terms
Conclusion¶
The GLW view system is a sophisticated framework for creating dynamic, data-driven user interfaces. Understanding the complete pipeline from file loading through preprocessing, parsing, and evaluation is essential for:
- Creating efficient view files
- Debugging view issues
- Extending the view system
- Optimizing performance
- Building reusable components
This analysis provides the foundation for working effectively with Movian's view system, whether you're creating plugins, customizing themes, or contributing to the core system.
Version History¶
- 2024: Complete source analysis of view system
- Loader system documented
- Preprocessing system documented
- Support utilities documented
- Complete pipeline documented