Anything considered static can be aggregated into a single VArena. We don't have to worry about ever releasing its memory or it growing "too large". All memory here must be fixed sized. Conservative persistent memory can grow on demand but we would perfer if it could be trimmed or released when no longer dealing with heavy scenarios. Persistent memory should use a slab allocator that is backed by a virtual address space pool allocator instead of pools allocating from a single varena. Chained Arenas can source thier chunks of vmem from the slab which can be utilized for scratch memory. Fonts should be loaded from VSlab. The string cache should use a dedicated varena with 16-byte alignment. All conservative memory should be trimmable by a wipe command which should free all unused blocks. Each block should be a single OS aware reserve of vmem. The Frame can possilby stay as a single varena with scratch allocation utilized on demand. Although it may be more viable for chained varenas to be derived from the main varena via a slab or pool interface. Frame memory should be trimmable on command which should release its committed vmem to its initial value. A dedicated transient varena should not exist. It should be removed when possible. File mappings for now can use a dedicated varena made on demand with a capped reserve size of 4 meg. Any file exceeding this needs the host to support virtual memory mapped I/O for files. The codebase db will use sqlite for the file I/O abstraction. Host might only need to track the first persistent block of vmem, and the rest can be handled by the client (including wrapping that vmem up in a varena). Hot-reload only needs persistent vmem's ref restored on the client module's side. All other references can be resolved from there.
Sectr Prototype
This prototype aims to flesh out ideas I've wanted to explore futher on code editing & related tooling.
The things to explore:
- 2D canvas for laying out code visualized in various types of ASTs
- WYSIWYG frontend ASTs
- Making AST editing as versatile as text editing.
- High-performance UI framework designed & built for AST editing.
- Generating a large amount of UI widget boxes with proper auto-layout & no perceptible rendering-lag or input lag for interactions (frametimes stable).
- Model-View-Controller interface between code managed by a 'backend' (both in memory and filesystem) and the UX composition (which has separate filesystem composition).
https://github.com/user-attachments/assets/0a895478-4a04-4ac6-a0ac-5355ff87ef4e
The dependencies are:
- Odin Compiler (Slightly custom fork)
- I added support for 'monlithic packages' or 'uniform-across-subdirectories packages'. It allows me to organize the main package with sub-directories.
- Added the ability to debug using statements on structs (fields get dumped to the stack as ptr refs)
- Remove implicit assignments for container allocators in the Base and Core packages
- I did not enjoy bug hunting a memory corruption because I mistakenly didn't properly initialize a core container with their designated initiatizer: new, make, or init.
- See fork Readme for which procedures were changed..
- Odin repo's base, core, and some of vendor
- VEFontCache-Odin: Text rendering & shaping library created for this prototype
- stb_truetype-odin: Variant of the stb/truetype package in odin's vendor collection made for VEFontCache-Odin
- harfbuzz-odin: Custom repo with tailor made bindings for VEFontCache-Odin
- sokol-odin (Sectr Fork)
- sokol-tools
- Powershell (if you want to use my build scripts)
- backtrace (not used yet)
- freetype (not used yet)
- Eventually some config parser (maybe I'll use metadesk, or ini)
The project is so far in a "codebase boostrapping" phase. Most the work being done right now is setting up high performance linear zoom rendering for text and UI. Text has recently hit sufficient peformance targets, and now inital UX has become the focus.
The project's is organized into 2 runtime modules sectr_host & sectr. The host module loads the main module & its memory. Hot-reloading it's dll when it detects a change.
Codebase organization:
- App: General app config, state, and operations.
- Engine: client interface for host, tick, update, rendering.
- Has the following definitions: startup, shutdown, reload, tick, clean_frame (which host hooks up to when managing the client dll)
- Will handle async ops.
- Font Provider: Manages fonts.
- Bulk of implementation maintained as a separate library: VEFontCache-Odin
- Grime: Name speaks for itself, stuff not directly related to the target features to iterate upon for the prototype.
- Defining dependency aliases or procedure overload tables, rolling own allocator, data structures, etc.
- Input: All human input related features
- Base input features (polling & related) are platform abstracted from sokol_app
- Entirely user rebindable
- Math: The usual for 2D/3D.
- Parsers:
- AST generation, editing, and serialization.
- Parsers for different levels of "synatitic & semantic awareness", Formatting -> Domain Specific AST
- Figure out pragmatic transformations between ASTs.
- Project: Encpasulation of user config/context/state separate from persistent app's
- Manages the codebase (database & model view controller)
- Manages workspaces : View compositions of the codebase
- UI: Core graphic user interface framework, AST visualzation & editing, backend visualization
- PIMGUI (Persistent Immediate Mode User Interface)
- Auto-layout
- Supports heavy procedural generation of box widgets
- Viewports
- Docking/Tiling, Floating, Canvas
Due to the nature of the prototype there are 'sub-groups' such as the codebase being its own ordeal as well as the workspace. They'll be elaborated in their own documentation
Gallery
Notes
Due to bug with custom ols click file in root of sectr to get full symbol reflection setup on the monolithic package.
For support for regions - grab a region extension and use the following regex:
VS-Code Explicit Folding:
"explicitFolding.rules": {
"odin": [
{
"beginRegex": "region\\b",
"endRegex": "endregion\\b"
},
{
"beginRegex": "{",
"endRegex": "}"
},
{
"beginRegex": "\\[",
"endRegex": "\\]"
},
{
"beginRegex": "\\(",
"endRegex": "\\)"
},
{
"beginRegex": "\"",
"endRegex": "\""
},
{
"beginRegex": "/\\*",
"endRegex": "\\*/"
}
]
},