SWMMVis  6.0.0-alpha.4
Qt6/C++ GIS-based graphical user interface for the SWMMVis engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
loadprogress.h File Reference
#include <QObject>
#include <QString>
#include <array>
#include <functional>
Include dependency graph for loadprogress.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  OpenProgressModel
 Weighted, monotonic progress aggregator for one project open. More...
 

Typedefs

using LoadProgressFn = std::function< void(int localPct, const QString &stage)>
 Progress sink handed to a worker-side producer.
 

Enumerations

enum class  OpenStage {
  EngineParse = 0 ,
  SoaCopy ,
  GeomCache ,
  CrsFinish ,
  Sidecar ,
  Results ,
  MeshParse ,
  MeshSceneA ,
  MeshSceneB ,
  Count_
}
 The stages of a single project open, in nominal order. More...
 

Functions

int packLoadProgress (OpenStage stage, int localPct)
 
OpenStage unpackLoadProgressStage (int packed)
 
int unpackLoadProgressPct (int packed)
 

Variables

constexpr int kLoadProgressStride = 101
 Encode a (stage, localPct) pair into a single QPromise progress int.
 

Detailed Description

Author
Caleb Buahin caleb.nosp@m..bua.nosp@m.hin@g.nosp@m.mail.nosp@m..com
Date
2026
License\n GPL-3.0-or-later

Determinate open-progress model (LOAD_PERF plan Phase 1a).

Opening a project is not one operation — it is a chain of stages spread across THREE async phases (model worker → GUI adopt/sidecar/results → mesh worker → GUI adopt → mesh Phase-B worker) plus post-open work on the GUI thread. Each phase can only report its own local 0-100.

OpenProgressModel turns that into a single monotonic 0-100 for the status bar: every stage owns a fixed slice of the total (stageWeight), and the overall percent is the sum of completed slices plus the partial slice of whatever is running.

Deliberate design points:

  • Fixed weights, never renormalized. A model that turns out to have no 2D mesh simply completes the three mesh stages instantly, which makes the bar JUMP FORWARD. That is fine. Renormalizing the table on stage discovery would instead make it run BACKWARDS, which reads as a bug.
  • Monotonic by construction. percent never returns less than it previously returned. Stages may complete out of order (the mesh worker and the GUI-thread sidecar apply genuinely overlap) without the bar stuttering.
  • No Qt Concurrent here. Producers deep inside the layers take a plain LoadProgressFn, so swmmmodellayer / inpmeshreader stay free of QPromise and remain unit-testable.

Typedef Documentation

◆ LoadProgressFn

using LoadProgressFn = std::function<void(int localPct, const QString &stage)>

Progress sink handed to a worker-side producer.

localPct is 0-100 WITHIN that producer's own stage — the producer knows nothing about the overall weighting. stage is a short human-readable label ("Parsing 2D mesh…"); an empty string keeps the previous label.

A default-constructed (empty) function is the "nobody is watching" case and every producer must tolerate it, so the sync code paths and the unit tests can call the same functions with no progress plumbing at all.

Enumeration Type Documentation

◆ OpenStage

enum class OpenStage
strong

The stages of a single project open, in nominal order.

Note
Nominal, not guaranteed: Sidecar/Results run on the GUI thread while MeshParse is already running on a worker. The model tolerates any completion order.
Enumerator
EngineParse 

swmm_engine_open — the .inp parse itself

SoaCopy 

SWMMModelLayer::buildFromEngine SoA pull.

GeomCache 

buildGeometryCache (5 sub-stages)

CrsFinish 

adoptOpenEngine CRS resolution + finishModelLoad

Sidecar 

.oswp sidecar apply

Results 

sibling .out discovery + open

MeshParse 

InpMeshReader::read.

MeshSceneA 

rebuildSceneGeometryLight + LOD pyramid

MeshSceneB 

finishSceneGeometryAsync (edges/grids/adjacency)

Count_ 

sentinel — not a stage

Function Documentation

◆ packLoadProgress()

int packLoadProgress ( OpenStage  stage,
int  localPct 
)
inline
Here is the caller graph for this function:

◆ unpackLoadProgressPct()

int unpackLoadProgressPct ( int  packed)
inline
Here is the caller graph for this function:

◆ unpackLoadProgressStage()

OpenStage unpackLoadProgressStage ( int  packed)
inline
Here is the caller graph for this function:

Variable Documentation

◆ kLoadProgressStride

constexpr int kLoadProgressStride = 101
constexpr

Encode a (stage, localPct) pair into a single QPromise progress int.

QPromise gives a worker exactly one integer channel, but the model-load worker spans three stages. Rather than invent a cross-thread pointer with its own lifetime rules, the worker packs the stage into the value and the GUI-side QFutureWatcher handler unpacks it — Qt already guarantees the delivery is thread-safe and lands on the GUI thread.

Layout: stageIndex * 101 + clamp(localPct, 0, 100). The stride is 101, not 100, so localPct == 100 is distinguishable from the next stage's 0.