Commit Graph
2854 Commits
Author SHA1 Message Date
Leonardo Zide 554c1d28a7 Add contextual help to Array and Save Image dialogs
Explain array counts, offsets, rotations, image dimensions, file naming,
and step ranges with translated tooltips and contextual help. Give both
dialogs a standard Help button and dialog-scoped F1 support that falls back
from the focused control through its parent groups to the overview.

Link image field labels to their buddies and share tooltip and field help
text. Add accessible names for unlabeled controls. Document the writing and
maintenance conventions, with concise guidance in the existing AGENTS.md.

Refresh all eight language catalogs while preserving existing translations
and review status. The 62 new help and accessibility strings remain
unfinished pending translation.

Validation: Qt 6.10 debug build; runtime checks for seven F1 routes, Help,
Escape, dialog state, spin-box focus, and five label buddies with matching
help; visual layout inspection; catalog coverage for all 2,118 active source
messages and existing translation preservation; git diff --check.
2026-10-22 15:14:11 -07:00
Leonardo Zide 5f3bfbf9fa Use consistent message severities and simplify ordinary dialogs
Show recoverable rendering, export, library, and network failures as warnings.
Default Blender messages to Warning, keep renderer startup failures Critical,
and remove the duplicate Blender installation failure dialog.

Replace 28 ordinary Blender helper calls with QMessageBox statics while
retaining specialized dialogs with informative text, details, or update
preferences. Preserve confirmation buttons and defaults and suppress static
startup/export messages without a main window. Rename the failed-result
helper to ShowResultError and refresh catalog locations and retired strings.

Validation: Qt 6.10 debug build; catalog coverage for all 2,056 active messages
and existing translation preservation; git diff --check.
2026-10-22 12:29:30 -07:00
Leonardo Zide 557c5276bd Use action-specific message box titles
Replace generic application and error titles with the operation that triggered
the message. Reuse translated dialog titles for validation and render errors,
preserve the current submodel naming action, and label edge-color prompts.

Require callers of the shared Blender message helper to provide a title so
installation, updates, extraction, settings, and output messages identify
their action instead of falling back to a product name.

Refresh all eight language catalogs and supply new title translations as
unfinished drafts with provenance comments. Preserve existing translations
and their review status, with drafts still included in release catalogs.

Validation: Qt 6.10 debug build; source and catalog coverage for all 2,058
active messages; existing translation preservation and generic-title checks;
runtime translation and plural checks; git diff --check.
2026-10-22 12:15:34 -07:00
Leonardo Zide b2463083f1 Standardize UI capitalization and punctuation
Use consistent capitalization for labels, dialog titles, acronyms, and
product names. Correct question-mark spacing, sentence boundaries, missing
punctuation, and run-together sentences in prompts and Blender messages.

Refresh the language catalogs without discarding existing translations.
Retain previous source text and mark affected translations unfinished so
translators can review the wording changes while drafts remain visible.

Validation: Qt 6.10 debug build, catalog source coverage and preservation
checks, runtime translation and plural checks, and git diff --check.
2026-10-22 12:05:23 -07:00
Leonardo Zide bcb6545464 Fix runtime localization and refresh translation catalogs
Translate Blender defaults after translators are installed and give the
spinner its own translation context. Translate remaining page and minifigure
labels, and use Qt numerus messages for count-dependent text. Embed an English
plural catalog so missing locale translations still have correct singular
and plural forms.

Refresh all eight language catalogs and fill missing translations as
unfinished drafts with provenance comments. Preserve existing translation
text, placeholders, markup, internal identifiers, and combo/filter syntax.
Keep nonempty unfinished translations visible in release catalogs.

Validation: Qt 6.10 debug build; warning-free lupdate extraction; active
catalog keys match all 2,044 source messages; catalog integrity checks;
runtime checks of spinner and 228 Blender default strings plus 472 plural,
draft visibility, placeholder, and English fallback cases.
2026-10-22 11:34:56 -07:00
Leonardo Zide 66d98fd3a7 Standardize piece terminology and English UI strings
UI labels mixed part and piece terminology, several messages left asset and file names unquoted, and Blender preferences contained British spellings and typos.

Use piece terminology throughout displayed text, quote names and paths in messages and tooltips, and standardize US English spelling. Keep status-bar names and the properties-dialog title unquoted. Update translation source keys while preserving existing translations, settings keys, and external format names.

Validation: macOS Qt 6.10 Debug build passed without warnings; XML, translation-key, placeholder, and whitespace checks passed.
2026-10-22 10:49:59 -07:00
Leonardo Zide 2eff0c3383 Simplify asset completion handling and piece waits
Keep the final piece error on its request and retain that request directly for deferred notification delivery. This removes duplicate notification storage while preserving UI-thread reference cleanup and cancellation behavior.

Inline the single-use piece wait helper into the batch wait, restoring the caller's OpenGL context once per batch. Remove the unused completion progress return value.
2026-10-22 10:17:05 -07:00
Leonardo Zide 069b3b60ab Fix directory subpart classification
The parallel primitive directory and subfile arrays had mismatched entries, causing parts/s/ files to receive a false subfile flag. Pair each directory path with its flag so directory subparts follow the same mesh loading path as archived subparts.
2026-10-21 22:49:11 -07:00
Leonardo Zide 1182f883e7 Unify library cache compression with Qt
Use shared cache readers and writers for archive and directory sources, replacing raw zlib loops with Qt compression and payload checksum validation. Preserve source freshness and decoded-size checks, and bump the cache version so existing entries rebuild in the new format.

Remove unused texture lookup APIs and the Blender zlib include, consolidate library helper access, and alphabetize the project source and header lists without changing their membership.
2026-10-21 22:41:16 -07:00
Leonardo Zide 0ba7c10e7b Fix Windows min and max macro collisions
Define NOMINMAX for Windows builds so windows.h does not introduce min and max macros that break standard-library calls in the group and object history headers.
2026-10-21 11:53:55 -07:00
Leonardo Zide d185d8a938 Fix Windows Qt installation and update CI actions
The released aqtinstall 3.3.0 resolves Qt 6.11.3 but cannot read its Windows repository layout, so CI fails before building. Pin the Windows job to Qt 6.10.3, whose MSVC 2022 packages remain discoverable with that installer.

Update checkout, cache, artifact upload, and CPU core detection to released Node 24 action versions to remove their Node 20 deprecation warnings. Keep the existing MSVC setup action, which has no newer release.

Validation: actionlint and git diff --check passed. Verified Windows Qt 6.10.3 architecture and archive discovery with aqtinstall 3.3.0. A hosted Windows build remains to be run.
2026-10-21 11:46:48 -07:00
Leonardo Zide f7ab4170dd Finish active drags before executing commands
Keyboard edits during dragging started a new history sequence and discarded the drag's original undo state. Deleting the dragged piece also left tracking active with a dangling piece pointer, causing the next mouse move to crash.

Accept the active drag before dispatching every command except Cancel, which retains its existing cancellation behavior. Keyboard edits and deletion then run as separate undoable operations after tracking has ended.

Validation: macOS application build and Qt Test suite passed. An offscreen harness using the production view, model, and command handlers reproduced the Delete crash and lost drag undo state before the fix. The fixed version passed five runs each of Delete with continued mouse movement, keyboard movement with undo, and Cancel.

Fixes #1046
Fixes #1048
2026-10-21 11:37:19 -07:00
Leonardo Zide b3816caadb Add Qt Test runner and Windows CI build
Provide a single qmake test executable with named Qt Test cases and a standard make check entry point. Cover object-history compaction, cancellation, merging, and property-key comparisons with checks that remain active in release builds, and document how to add tests.

Build and run the tests in Linux and macOS CI and add a Windows x64 job using MSVC 2022 and Qt 6. Enable pull request and manual runs alongside master pushes, preserve JUnit reports on failures, and update existing checkout and cache actions.

Validation: macOS Qt 6.10 release tests and actionlint passed. Confirmed a failing assertion produces a nonzero check result and a JUnit failure.

Closes #1050
2026-10-21 11:32:32 -07:00
Leonardo Zide 851eecee50 Store only changed objects in edit undo history
Full before-and-after model snapshots accumulate large amounts of memory during editing, even when an operation changes only one object. Compact completed edits to retain only added, removed, or modified object states, with ordering metadata kept only for structural changes.

Restore objects by stable IDs, including group relationships, and detach views before removing cameras. Compose merged edits from their deltas and compare animation keys as well as current property values so keyframe-only edits remain undoable.
2026-10-21 10:48:24 -07:00
Leonardo Zide 3d1091492e Reduce asset header dependencies
Keep library source storage details in the implementation and move the primitive constructor out of line so the library header no longer needs string helpers. Use shared forward declarations and asset types in loader and manager headers, keeping the full texture definition in its implementation.
2026-10-20 21:31:31 -07:00
Leonardo Zide 9db02183c8 Keep directory discovery metadata in temporary jobs
Directory folder and file-list indices are only needed while initializing
descriptions and their cache. Replace the persistent lcPieceData fields
with local jobs holding the selected file info, source folder and change
flag. Workers update independent jobs, and cache writing uses their
timestamps after all workers finish.

Pass the discovered paths to alias classification so it opens the selected
source directly without reconstructing paths from asset bookkeeping.
Move include-free piece member defaults into the header and zero-initialize
the filename and description arrays there.

Validated with a warning-free Qt 6.10 Debug build, 58 offscreen lifecycle
groups covering directory/archive caches and cross-source aliases, and
clean diff whitespace checks.
2026-10-20 21:12:31 -07:00
Leonardo Zide 03d58100cb Own library primitives with unique pointers
Store primitive entries as unique_ptr values so source destruction and
replacement release their owned data automatically. This removes the
manual deletion loop and prevents leaking an overwritten entry during
discovery while preserving borrowed pointers used by loaders.

Remove the duplicate IsPrimitive lookup and use FindPrimitive for
directory precedence checks and primitive detection during model import.

Validated with a warning-free Qt 6.10 Debug build, all 58 offscreen
lifecycle groups, and clean diff whitespace checks.
2026-10-20 20:56:19 -07:00
Leonardo Zide b6ab0c4c3b Merge pull request #1043 from PontusPih/pr/free-move-rotation
Fix the rotation of a selection moved with the free move tool
2026-10-20 20:47:28 -07:00
Leonardo Zide e2cb91f6f4 Fix decorated part classification and cache parent IDs
Detect decorations from filenames and description keywords so obsolete
parts with numeric IDs and descriptions starting with ~ are hidden when
Show Decorated Pieces is disabled. Keep decoration flags separate from
the optional plain parent ID, preserving classification when no parent
exists and leaving standalone stickers outside the current heuristic.

Resolve single-reference aliases across official and unofficial sources,
reject cycles, and use resolved parent IDs for category grouping. Cache
classification with descriptions and rebuild dependent alias metadata when
directory sources change. Keep local classification and cache restoration
in lcPieceData; the library handles source reads and registry resolution.

Validated with a warning-free Qt 6.10 Debug build, 58 lifecycle checks,
and offscreen filter checks for 81 obsolete numeric patterned parts on
cold and cached loads.

Fixes #538
2026-10-20 19:59:29 -07:00
Leonardo Zide 8a0b082f77 Merge branch 'master' of https://github.com/leozide/leocad 2026-10-20 11:59:45 -07:00
Leonardo Zide 0d137bcf47 Bound grid generation for distant pieces
A piece at an extreme coordinate expands the grid to millions of lines, causing excessive allocations or a truncated vertex buffer size followed by writes past its end. Larger coordinates can also exceed the integer range during conversion.

Clamp finite grid bounds before converting to integers, limiting the vertex buffer to less than 1 MB, and use the default grid for non-finite bounds. Calculate texture extents in floating point to avoid integer overflow with large spacing values.

Fixes #1044
2026-10-20 11:59:34 -07:00
Leonardo Zide 9709106aff Bound grid generation for distant pieces
A piece at an extreme coordinate expands the grid to millions of lines, causing excessive allocations or a truncated vertex buffer size followed by writes past its end. Larger coordinates can also exceed the integer range during conversion.

Clamp finite grid bounds before converting to integers, limiting the vertex buffer to less than 1 MB, and use the default grid for non-finite bounds. Calculate texture extents in floating point to avoid integer overflow with large spacing values.
2026-10-20 11:54:19 -07:00
PontusPih 79d2765eb8 Fix the rotation of a selection moved with the free move tool
UpdateFreeMoveTool combined the world rotation with the focus frame in the
wrong order, so a selection turned around anything but the vertical axis
ended up rotated wrongly, compounding with every mouse move. Train track
connections only turn around the vertical axis, where the order doesn't matter.
2026-10-20 19:30:45 +02:00
Leonardo Zide e1c2df5767 Centralize ZIP filename lookup
Add FindFileIndex to resolve the first case-insensitive filename match
without extracting it. Reuse the lookup in named extraction and library
include resolution, removing the duplicate archive-entry scan while
preserving archive order and source fallback behavior.

Validated with a warning-free Qt 6.10 Debug build and 51 offscreen
lifecycle groups; the final API rename also builds without warnings.
2026-10-19 22:51:03 -07:00
Leonardo Zide 29c1c142df Simplify model metadata updates and discovery names
Update model filenames and descriptions directly in SetModel, removing
metadata-only forwarding through the library and piece manager. Registry
renames remain synchronized in the manager.

Reuse the bounded piece-name normalizer for archive and directory discovery
to remove duplicated conversion loops and avoid writing a terminator past
the name buffer. Preserve original source filenames and archive offsets.

Validated with a warning-free Qt 6.10 Debug build and all 51 offscreen
lifecycle groups; diff whitespace checks pass.
2026-10-19 22:31:17 -07:00
Leonardo Zide 038e091af4 Return owned include files and consolidate source opening
Callback-based include readers hid open failures and required parser callbacks
to report success through captured variables. Replace them with OpenPieceDataFile
and OpenPrimitiveFile returning lcResult of an owned file positioned at zero.
The mesh loader consumes the file directly and retains its existing strict or
permissive policy for missing includes.

Route include reads, piece builds and primitive builds through the existing
OpenFile service for archive and disk access. Preserve registered-source and
fallback search order, directory retries after parse failure, and primitive
high/low-detail selection. Primitive opening uses its own source metadata,
including stud-style archives with directory libraries, and records opening
errors through the existing synchronized failure path.

Document the owning file contract and retry boundary. Validation: warning-free
macOS Qt 6.10 Debug build, all 51 offscreen lifecycle checks and whitespace checks
pass. Coverage includes independent cursors across unload, missing/invalid sources,
include failure policy, parse retries, official precedence and low-detail/styled
primitive builds. Successful GPU rendering was not tested.
2026-10-19 21:28:49 -07:00
Leonardo Zide edd155dad9 Prefer official parts consistently across library sources
Loading the unofficial archive replaced same-name official part registrations,
while directory loading and include/primitive lookup already preferred official
sources. Keep registered official part sources when scanning unofficial archives;
unofficial-only parts remain available and other source policies stay unchanged.

Bump the library cache version so descriptions and mesh geometry built under the
previous override policy cannot survive the precedence change. Document the
consistent official-first behavior and cache invalidation.

Validation: warning-free macOS Qt 6.10 Debug build, all 47 offscreen lifecycle
checks and diff whitespace checks pass. Added checks cover cold/warm archive and
directory parts, primitives, subparts and includes, plus rejection and rebuilding
of legacy description and geometry caches. GPU rendering was not tested.
2026-10-19 20:52:35 -07:00
Leonardo Zide 137c645ce6 Remove obsolete library cleanup and capability APIs
UnloadUnusedParts selects identities with zero references and calls the release
path, which immediately returns without changing them. Remove the no-op scan
and its model, project and preview callers, including the now-unused LoadLDD
library local. Actual last-reference unload and temporary identity cleanup remain
in their existing lifetime paths.

SupportsStudStyle always returns true. Remove the method and the unreachable
preferences branch that disables the stud-style selector.

Validation: warning-free macOS Qt 6.10 Debug build, all 45 offscreen lifecycle
checks and diff whitespace checks pass. No remaining references to either API.
2026-10-19 20:41:18 -07:00
Leonardo Zide 664cec006f Protect library directory and shared buffer access
Move the library directory and shared vertex/index buffer handles into the
protected source and rendering groups. Expose one GetBuffers accessor returning
const references to both buffers, and use structured binding in BindMesh while
preserving GL binding and uncached-mesh fallback behavior.

Add GetLibraryFilePath for mapping-file lookups and update the LXF and BrickLink
callers. Keep file opening and bundled-resource fallback in those callers so the
library only resolves the path and exposes no mutable directory state.

Validation: warning-free macOS Qt 6.10 Debug build, all 45 offscreen lifecycle
checks and diff whitespace checks pass. No remaining external field accesses
for the protected directory or buffers. GPU rendering was not tested.
2026-10-19 18:44:13 -07:00
Leonardo Zide 9d2ec2197c Fix official library update counts and encapsulate access
Counting the combined registry after unofficial archives load can inflate the
installed official-piece count and suppress legitimate update notifications.
Capture the count immediately after the official archive is discovered, before
unofficial additions or overrides, so overrides still count as official entries.

Pass official-library eligibility explicitly into Load from the startup path
metadata. Custom paths, directory libraries and fallback loading retain a zero
update count, and unload clears it before any subsequent load. Remove the
post-load setter and expose the protected count through GetOfficialPieceCount
for the update dialog.

Validation: warning-free macOS Qt 6.10 Debug build and all 45 offscreen lifecycle
checks pass. Count checks cover unofficial additions and overrides, later missing
identities, custom archives, directory/failed reloads, fallback and unload reset.
Diff whitespace checks are clean.
2026-10-19 18:35:17 -07:00
Leonardo Zide 959f351a51 Organize library interfaces and centralize buffer invalidation
Group library functions and protected state by responsibility, and document
their ownership, readiness and worker contracts. Restrict teardown, source
snapshot/build/cache services, file opening and deferred repacking to protected
access; their production callers are internal or the existing loader friend.

Remove model-side buffer dirty writes from inventory loading and piece insertion.
Mesh publication already schedules deferred repacking, which includes all
registered meshes; uncached meshes use their own data until repacking finishes.
Keep mBuffersDirty protected with the library rendering state so model changes
no longer bypass that scheduling or cause an extra rebuild.

Validation: warning-free macOS Qt 6.10 Debug build, all 43 offscreen lifecycle
checks and diff whitespace checks pass. Signatures and inline bodies are
unchanged; explicit teardown ordering remains intact. GPU rendering was not
tested. The existing official-piece update-count behavior is unchanged.
2026-10-19 18:26:45 -07:00
Leonardo Zide 59225f9437 Finish piece manager synchronization and error ownership
Move sparse piece load errors and registry locking into lcPieceManager so
registry access, reference bookkeeping and copied worker metadata share one
owner. Release registry and error locks before resource teardown, recursive
project deletion or loader cancellation; remove library lock scopes around
UI source resolution and worker-drained settings changes.

Add HasOtherReferences to the shared asset reference for piece and texture
consumer checks, removing the library/manager consumer-query wrappers. Keep
the post-release cancellation count check and existing lifetime policies.
Rename the sparse error map to mPieceDataLoadErrors and document the completed
manager boundary and thread/teardown contracts.

Validation: warning-free macOS Qt 6.10 Debug build and all 43 offscreen
lifecycle checks pass, including concurrent metadata/error reads, settings
changes with pending requests and shared reference queries. Qt 5, ASan and
successful GPU rendering were not tested.
2026-10-19 18:03:34 -07:00
Leonardo Zide b38a1ce0fa Move piece lifetime bookkeeping into lcPieceManager
Piece registrations were centralized but creation, reference bookkeeping and
cleanup still lived in the library. Move creation/model reuse, normalization,
metadata renaming, reference operations, temporary cleanup, project transfer and
ordered identity teardown into the manager. Keep registration/deletion helpers
private and remove the temporary local-registry enumeration APIs.

The library remains the acquisition facade and coordinates source resolution,
loading, invalidation and cancellation after unlocking. Handles still bind to
the library. Clear sparse errors from lcPieceData::Unload before resource teardown
so manager deletion does not require a library pointer or callback. Sparse error
storage and the existing synchronization remain library-side.

Use one project-aware manager lookup, passing nullptr for shared-only searches.
Remove the maximum-size name reservation so short names can use inline storage.
Replace remaining bounded C-string copy/terminator pairs with lcstrcpy and record
the helper convention in common/AGENTS.md. Update the asset lifetime documentation.

Validation: macOS Qt 6.10 Debug build, whitespace checks and 40 offscreen lifecycle
checks, including already-zero release, last-owner cancellation, model reuse,
project detach/transfer cleanup, sparse errors, archive/directory caches and forced
nested external-project teardown. Successful GPU rendering is not covered by the
offscreen checks.
2026-10-19 11:48:21 -07:00
Leonardo Zide 41e5432395 Extract piece registration storage into lcPieceManager
Library and project name registries were accessed directly by source discovery,
cache processing and UI consumers. Centralize their storage and index operations
in a library-owned lcPieceManager, with ordered borrowed snapshots and copied
file metadata for worker include lookup.

Keep source resolution, reference counts, unload/deletion policy, cache I/O and
existing synchronization in lcPiecesLibrary. Preserve project-index collisions,
name normalization and reentrant teardown ordering while routing registration
changes through the manager.

Return the GetParts snapshot by value, name model rename/reservation operations
RenameModelPieceData, and centralize manager forward declarations in the PCH.
Document the registry boundary and register the new files in qmake.

Validation: macOS Qt 6.10 Debug build, whitespace checks and 35 offscreen lifecycle
checks, including archive/directory cold and warm caches, source precedence,
worker includes, borrowed snapshot lifetimes, rename collisions, project transfer
and nested external-project destruction. Successful GPU rendering is not covered
by the offscreen checks.
2026-10-19 11:07:43 -07:00
Leonardo Zide 98c67f3705 Align texture acquisition and scoped ownership
Texture lookup previously acquired references implicitly, and mesh sections and
loader requests paired raw texture pointers with manual release paths. Separate
borrowed lookup from scoped acquisition and explicit load requests/waits to match
the piece data ownership API.

Store lcTextureRef in mesh sections and loader requests, retain references on
section copies, and reset worker-shared request handles on the UI thread before
completion, cancellation, or shutdown. Keep reference primitives internal and use
scoped acquisitions for merge validation. Remove redundant section initialization
and synth-notification resets, and document the resulting ownership contracts.

Validation: macOS Debug build, diff whitespace checks, and 30 offscreen lifecycle
checks covering reference copies/moves, texture dependencies, cancellation,
shutdown, merge conflicts, and existing piece ownership paths. Successful GPU
upload/rendering is not covered by the offscreen checks.
2026-10-19 10:38:51 -07:00
Leonardo Zide 61be531444 Manage piece data ownership with scoped asset references
Replace manual piece-data retain/release bookkeeping with shared copyable
asset-reference handles. Pieces, models, selection, minifigs, thumbnails,
and stored insertion previews retain their dependencies explicitly, while
transient queries continue to borrow pointers.

Separate registered lookup and acquisition from asynchronous load requests
and explicit readiness waits. Keep loader-held references through work and
notification delivery, resetting shared request handles on the UI thread
and guarding callback-triggered library teardown.

Validated with the Qt 6.10 debug build and 26 offscreen lifecycle checks,
including cancellation, stale requests, copy/move operations, model/preview
teardown, undo, project merge/export, and loader shutdown.
2026-10-19 10:02:26 -07:00
Leonardo Zide 7bc6c018b1 Rename PieceInfo to lcPieceData
Use PieceData consistently for the shared part/model record, its related
APIs and variables, and its source files. Keep the existing reference
counting and loading behavior so ownership and readiness changes can be
reviewed separately.
2026-10-18 23:22:28 -07:00
Leonardo Zide 74e16b0d13 Enable shadow warnings for non-MSVC builds
Enable -Wshadow to bring GCC and Clang shadowing diagnostics closer to the MSVC warning configuration. Rename the filename extension variable to avoid shadowing the file type extension, and remove the unused synthesized-piece failure counter.

Validated with a macOS debug rebuild with no warnings or errors.
2026-10-17 13:41:41 -07:00
Leonardo Zide 58f60b9423 Separate asset readiness from loader request progress
Keep piece readiness, mesh publication, and settled synth errors in the
library while the loader manages scheduling, request outcomes, cancellation,
and deferred notifications. Capture synth inputs and base identities at the
library boundary so the loader treats pieces as opaque identities.

Use a shared asset readiness enum for pieces and textures. Keep texture
queueing, decoding, and retry progress in requests, pass resolved sources to
the loader, and centralize texture failure messages in lcTexture. Preserve
scoped wait failure and cancellation results alongside final readiness checks.

Consolidate shared priorities, sources, snapshots, build results, and texture
error codes in lc_assettypes.h, replacing lc_filesource.h. Forward declarations
remove the loader header's piece, library, and texture-manager dependencies.

Validated with the Qt Debug build, header isolation compilation, asset loader
lifecycle and scheduling regression checks, and 14 first/repeat export checks.
2026-10-16 17:42:16 -07:00
Leonardo Zide c7de6bfecc Keep asset refresh orchestration in the library
Keep the persistent registry of live synth instances in the library, where
settings changes can refresh completed and failed generations through the
normal request lifecycle. The loader retains only pending work and errors.

After draining assigned jobs to change shared settings safely, resume
replacement work asynchronously instead of waiting for unrelated queued
assets. Rebuild model geometry through the normal loader entry point,
invalidating stale requests without adding a consumer reference.

Reduce the loader's public API, group its declarations by responsibility,
and document the ownership and asynchronous refresh behavior.

Validated with the Qt Debug build, loader lifecycle and scheduling regression
checks, model and synth refresh checks, and 14 first/repeat export checks.
2026-10-16 15:17:40 -07:00
Leonardo Zide 6795887758 Schedule asset builds on the UI thread
Move request selection and lifecycle updates to the UI thread so worker jobs
only build their assigned asset and hand back a completion. This removes
request-map locking and keeps priority promotion, cancellation, and publication
under one thread's ownership.

Limit outstanding jobs to half the reported hardware threads, with a minimum
of one and no fixed cap. Release job slots before texture dependency settlement
and retain completion wakeups for synchronous waits, pause, and shutdown.

Share piece-request cleanup while preserving in-flight load holds. Use cancelled
request states to suppress invalidated notifications instead of an obsolete flag.
Clarify function names, document the lifecycle, and group header declarations.

Validation: Qt Debug build, scheduler and lifecycle harness, one-slot texture
success/retry checks, notification suppression and reference checks, 14 asset
exports, and git diff --check passed.
2026-10-16 13:13:02 -07:00
Leonardo Zide 793815efe8 Simplify asset loader scheduling with request states
The loader kept separate queues alongside its request maps and represented
request progress with overlapping booleans. Keep pending work in the maps
and select queued requests by priority and age using a shared lifecycle
state and scheduling fields.

Preserve cancellation ownership through outstanding worker completions,
restart staged meshes after settings changes, and protect wait-state reads
with the request mutex. Skip request scans when workers cannot start.
Pass the existing piece source snapshot to texture resolution instead of
separate lookup containers, and document the updated request lifecycle.

Validation: Qt Debug build, loader scheduling/cancellation/cache/lifecycle
checks, 14 first/repeat exports, and git diff --check passed.
2026-10-16 12:30:34 -07:00
Leonardo Zide 4129788f95 Build piece and synth meshes in one worker job
Color finalization no longer requires a UI-thread handoff between parsing and mesh conversion. Have the library and synth build services return converted private meshes, removing intermediate request/result mesh data and conversion requeue paths.

Fall back to source parsing immediately when a cached mesh cannot be decoded, eliminating SkipCache and the UI retry branch. Simplify paused staging cleanup and document the combined worker lifecycle; section finalization and publication remain on the UI thread.
2026-10-15 14:37:07 -07:00
Leonardo Zide 9f7e4d3a41 Unify mesh color resolution and section finalization
Cached meshes retained color-dependent flags and section ordering from the palette used when they were saved. Finalize fresh piece, synth, and cached mesh sections on the UI thread so color indices, flags, and ordering all reflect the current palette before publication.

Keep color codes in private mesh sections until finalization and remove separate color-code vectors, worker palette snapshots, and the early color-resolution path. Geometry conversion now runs without global color access or texture lookup callbacks.
2026-10-15 14:11:05 -07:00
Leonardo Zide f4fe4f8e87 Clarify asset loader request and completion APIs
Use consistent names for piece loading, synth generation, worker completions, and outstanding work. Remove the unused library drain wrapper and call the loader directly during settings updates.

Check for the final consumer release in the library before cancelling queued piece work, and document how running builds retain their load hold until completion. Update callers and asset-loading documentation.
2026-10-15 13:35:34 -07:00
Leonardo Zide d493eee066 Simplify asset loader state and shutdown
Asset requests carried duplicate phase, generation, and notification state.
Remove unused texture dependencies and project-path storage, derive conversion
from owned mesh data, and use request identity, cancellation, and the stopping
flag to reject obsolete results.

Decode cached meshes in the library's worker build service so serialized bytes
stay local and completions retain only decoded data and a cache-origin flag.
Make draining private to the loader destructor and remove duplicate shutdown
calls from library unload and destruction. Document the resulting lifecycle.

Validation: macOS Qt 6.10 Debug build; 14 first/repeat CLI exports; temporary
lifecycle checks covering cold/warm/corrupt caches, notification delivery and
suppression, pause/resume, cancellation, destructor-only draining, and reload.
2026-10-14 21:33:17 -07:00
Leonardo Zide 6a8c05acc5 Initialize stud settings and simplify loader bookkeeping
Pass effective startup stud settings into the library and apply color preferences before loading. Replace the reload toggle with UpdateStudStyleAndColors, preserve configured settings in the fallback library, and save the selected color config before combined preferences updates.

Remove temporary consumer references from synchronous piece waits, the redundant drain mutex, and worker-start queues. Derive loading states from current requests and use explicit piece names for request, queue, and notification storage. Document the updated ownership and settings contracts.

Validated with a Debug build, startup style and color exports, 14 asset export checks, and temporary lifecycle checks covering owned waits, failed and duplicate requirements, regeneration, cancellation, pause/resume, reference cleanup, and shutdown.
2026-10-14 10:57:30 -07:00
Leonardo Zide 3ec8b274b1 Unify asset loading priorities and clarify wait APIs
Replace load flags and the loader's separate priority enum with Low, Normal, and Blocking priorities. Blocking loads wait for completion; asynchronous loads and internal scheduling retain promotion-only behavior.

Acquire consumer references in the library, reuse loader loading for stud-style rebuilds, and remove QueuePiece, single-piece readiness wrappers, and the library texture readiness wrapper. Rename scoped readiness APIs to WaitFor functions and document their scheduling and lifetime contracts.

Validated with a Debug build and a temporary lifecycle harness covering priority promotion, blocking loads, reference cleanup, selective style reloads, cancellation, pause/resume, and shutdown.
2026-10-13 23:27:29 -07:00
Leonardo Zide 2051eeed42 Simplify asset loader lifecycle and paused scheduling
Make the loading lifecycle easier to follow by ordering functions by phase, splitting completion handling by asset type, and sharing color and texture preparation. Use Piece terminology, rename model rebuilding, and document reference and waiting behavior.

Keep pending work in the normal queues while paused, refresh piece snapshots before resuming, and remove duplicate enqueue and cancellation paths. QueuePiece now explicitly schedules background work.

Validated with a Debug build, 14 CLI export checks, and a temporary lifecycle harness covering staging resets, style refresh, cancellation, eight in-flight pause/resume cycles, last-consumer release, and shutdown.
2026-10-13 19:32:12 -07:00
Leonardo Zide 232fc54dee Remove unused asset request IDs
Part request IDs were assigned and copied to build results but never read. Remove the fields, counter, and assignments; stale completion checks continue to use request identity and generation.
2026-10-13 19:07:09 -07:00