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
openswmmvis::timeseries::TimeseriesProvider Class Reference

#include <timeseriesprovider.h>

Inheritance diagram for openswmmvis::timeseries::TimeseriesProvider:
Collaboration diagram for openswmmvis::timeseries::TimeseriesProvider:

Public Types

enum class  SourceMode {
  Inline ,
  ExternalFile ,
  GeopackageObserved
}
 Where the data lives. More...
 
enum class  TimeMode {
  Absolute ,
  Relative ,
  Mixed
}
 How the series' times were authored in the .inp. More...
 

Signals

void timeModeChanged ()
 The derived timeMode() flipped, or the relative anchor moved. Payload-free; subscribers re-read (metadataChanged style).
 
void pointsChanged (int firstIndex, int count)
 Points in [firstIndex, firstIndex+count) had their value changed in place.
 
void pointsInserted (int at, int count)
 count points were inserted starting at at.
 
void pointsRemoved (int at, int count)
 count points were removed starting at at.
 
void metadataChanged ()
 Identity / units / description changed (signal carries no payload; subscribers re-read).
 
void sourceModeChanged (SourceMode prev, SourceMode now)
 Source mode flipped.
 
void nameChanged (QString prev, QString now)
 Tseries was renamed; dependent-reference cascading is the registry's job (subscribers should not rewrite refs from this signal).
 
void mutationRejected (QString reason)
 A mutator was refused because it would have violated an invariant. Surfaced to UI so the drag-edit status bar can show the offending state.
 
void pointCacheDisposed ()
 Step F — ExternalFile mode: the lazy point cache was dropped via disposePointCache. Distinguishes "freed to save memory" from "legitimately empty" so views can render a placeholder instead of treating it as a parse failure.
 

Public Member Functions

 TimeseriesProvider (QString name, QObject *parent=nullptr)
 
 ~TimeseriesProvider () override
 
QString name () const noexcept
 Tseries ID. Uniqueness within a project is owned by the registry.
 
QString unitsLabel () const noexcept
 Units label inferred from column suffix or set explicitly (e.g. "m", "ft³/s"). UI hint only — no unit conversion happens here.
 
QString description () const noexcept
 Optional free-text description; surfaced by the editor's header context menu.
 
SourceMode sourceMode () const noexcept
 
QString filePath () const noexcept
 External file path (meaningful only when sourceMode == ExternalFile).
 
QString columnSelector () const noexcept
 Column selector inside the external file ("" = first / name-match).
 
QDateTime fileMTime () const noexcept
 Last-known file mtime for staleness detection.
 
int pointCount () const noexcept
 Number of stored points. ExternalFile mode reports 0 until the read-through cache is implemented in its dedicated sub-phase.
 
bool isPointCacheLoaded () const noexcept
 True iff the in-memory point vector is populated. Inline / GeopackageObserved modes always return true (their points ARE the authoritative storage). ExternalFile mode returns true between a load and a disposePointCache call.
 
void disposePointCache ()
 Drop the in-memory point vector for ExternalFile-mode providers to reclaim memory when the editor switches to a different series. The file path / column selector / mtime stay so a later Reload can re-read from disk. No-op for Inline / GeopackageObserved — those caches are authoritative storage and disposing would lose data. Emits pointsChanged(0, prevCount) so the table / chart views drop to an empty-state render (and pointCacheDisposed() for callers that need to distinguish "disposed" from "naturally empty").
 
const TimeseriesPointpointAt (int i) const
 Read a single point by index. Caller must ensure 0 ≤ i < pointCount().
 
const QVector< TimeseriesPoint > & points () const noexcept
 All points (const ref).
 
bool setAllPoints (QVector< TimeseriesPoint > newPoints, QString *reasonOut=nullptr)
 Replace the entire point list. Validates strict-monotone time before applying. Atomic: either all replaced or none.
 
bool setValueAt (int i, double newValue, QString *reasonOut=nullptr)
 Change only the value at index i. Time stays put so monotonicity is preserved by construction.
 
bool setValueLive (int i, double newValue)
 Live variant of setValueAt for drag-edit: does NOT push undo per-frame (caller handles batching). Same monotonicity guarantee.
 
bool setPointAt (int i, QDateTime newTime, double newValue, QString *reasonOut=nullptr)
 Change both time + value at index i. Validates that the new time still slots between neighbours strictly.
 
int insertPoint (QDateTime time, double value, QString *reasonOut=nullptr)
 Insert one point. Returns the new index on success.
 
void removePointsAt (QVector< int > indices)
 Remove points by index. Indices are deduplicated + sorted descending internally so the loop is safe.
 
void setName (QString newName)
 Rename the Tseries. Uniqueness is the registry's responsibility; this just stores + notifies.
 
void setUnitsLabel (QString units)
 
void setDescription (QString d)
 
void setSourceMode (SourceMode mode)
 
void setFileSource (QString path, QString columnSelector, QDateTime mtime)
 
TimeMode timeMode () const noexcept
 Derived mode: Relative when every point is in the relative prefix (or an empty series carries relative intent), Absolute when the prefix is empty, Mixed otherwise.
 
int relativeCount () const noexcept
 Leading points authored as elapsed-time-from-start.
 
QDateTime relativeAnchor () const noexcept
 Simulation start the relative points' absolute times are anchored to (invalid when the series has no relative rows).
 
void setRelativeInfo (int count, QDateTime anchor, int allRelativeIntent=-1)
 Raw restore used by registry load and undo: sets the prefix count (clamped to [0, pointCount()]), the anchor, and — when allRelativeIntent is 0/1 — the sticky "author every new row as relative" flag (-1 derives it as count > 0 && count == pointCount(), which for an EMPTY series means count > 0 requests relative intent). Emits timeModeChanged() when the derived mode or anchor changes.
 
void setTimeMode (TimeMode mode, QDateTime anchorForRelative={})
 User-facing mode switch. Relative marks every current point relative and records anchorForRelative (when valid) as the anchor; Absolute clears the prefix. Mixed is a loaded state, not a target — requesting it is a no-op.
 

Member Enumeration Documentation

◆ SourceMode

Where the data lives.

Enumerator
Inline 

Stored in the project (.inp [TIMESERIES] rows).

ExternalFile 

Linked to a CSV / TSV / .dat file on disk.

GeopackageObserved 

Stored in the project geopackage observed_* tables.

◆ TimeMode

How the series' times were authored in the .inp.

SWMM [TIMESERIES] rows come in two forms: rows with an explicit date (the date carries forward to date-less continuation rows until the next dated row), and rows with only a time — elapsed since the simulation start. Both may mix in one series: date-less HEAD rows are relative to the start, the dated tail is absolute. The engine tracks this per table (swmm_timeseries_get/set_relative_info); the provider mirrors it so the editor can badge/author the format and the registry can round-trip it. Points are ALWAYS stored as absolute QDateTimes here — the mode only records how the leading rows are (re)emitted.

Enumerator
Absolute 

Every row carries (or inherits) an explicit date.

Relative 

Every row is elapsed time from the simulation start.

Mixed 

Elapsed head rows + dated tail (loaded, not authored).

Constructor & Destructor Documentation

◆ TimeseriesProvider()

openswmmvis::timeseries::TimeseriesProvider::TimeseriesProvider ( QString  name,
QObject *  parent = nullptr 
)
explicit

◆ ~TimeseriesProvider()

openswmmvis::timeseries::TimeseriesProvider::~TimeseriesProvider ( )
overridedefault

Member Function Documentation

◆ columnSelector()

QString openswmmvis::timeseries::TimeseriesProvider::columnSelector ( ) const
inlinenoexcept

Column selector inside the external file ("" = first / name-match).

Here is the caller graph for this function:

◆ description()

QString openswmmvis::timeseries::TimeseriesProvider::description ( ) const
inlinenoexcept

Optional free-text description; surfaced by the editor's header context menu.

◆ disposePointCache()

void openswmmvis::timeseries::TimeseriesProvider::disposePointCache ( )

Drop the in-memory point vector for ExternalFile-mode providers to reclaim memory when the editor switches to a different series. The file path / column selector / mtime stay so a later Reload can re-read from disk. No-op for Inline / GeopackageObserved — those caches are authoritative storage and disposing would lose data. Emits pointsChanged(0, prevCount) so the table / chart views drop to an empty-state render (and pointCacheDisposed() for callers that need to distinguish "disposed" from "naturally empty").

Here is the call graph for this function:

◆ fileMTime()

QDateTime openswmmvis::timeseries::TimeseriesProvider::fileMTime ( ) const
inlinenoexcept

Last-known file mtime for staleness detection.

◆ filePath()

QString openswmmvis::timeseries::TimeseriesProvider::filePath ( ) const
inlinenoexcept

External file path (meaningful only when sourceMode == ExternalFile).

◆ insertPoint()

int openswmmvis::timeseries::TimeseriesProvider::insertPoint ( QDateTime  time,
double  value,
QString *  reasonOut = nullptr 
)

Insert one point. Returns the new index on success.

Parameters
reasonOutOn failure, populated with a human-readable reason.
Returns
-1 on rejection.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isPointCacheLoaded()

bool openswmmvis::timeseries::TimeseriesProvider::isPointCacheLoaded ( ) const
noexcept

True iff the in-memory point vector is populated. Inline / GeopackageObserved modes always return true (their points ARE the authoritative storage). ExternalFile mode returns true between a load and a disposePointCache call.

◆ metadataChanged

void openswmmvis::timeseries::TimeseriesProvider::metadataChanged ( )
signal

Identity / units / description changed (signal carries no payload; subscribers re-read).

Here is the caller graph for this function:

◆ mutationRejected

void openswmmvis::timeseries::TimeseriesProvider::mutationRejected ( QString  reason)
signal

A mutator was refused because it would have violated an invariant. Surfaced to UI so the drag-edit status bar can show the offending state.

Here is the caller graph for this function:

◆ name()

QString openswmmvis::timeseries::TimeseriesProvider::name ( ) const
inlinenoexcept

Tseries ID. Uniqueness within a project is owned by the registry.

Here is the caller graph for this function:

◆ nameChanged

void openswmmvis::timeseries::TimeseriesProvider::nameChanged ( QString  prev,
QString  now 
)
signal

Tseries was renamed; dependent-reference cascading is the registry's job (subscribers should not rewrite refs from this signal).

Here is the caller graph for this function:

◆ pointAt()

const TimeseriesPoint & openswmmvis::timeseries::TimeseriesProvider::pointAt ( int  i) const
inline

Read a single point by index. Caller must ensure 0 ≤ i < pointCount().

Here is the caller graph for this function:

◆ pointCacheDisposed

void openswmmvis::timeseries::TimeseriesProvider::pointCacheDisposed ( )
signal

Step F — ExternalFile mode: the lazy point cache was dropped via disposePointCache. Distinguishes "freed to save memory" from "legitimately empty" so views can render a placeholder instead of treating it as a parse failure.

Here is the caller graph for this function:

◆ pointCount()

int openswmmvis::timeseries::TimeseriesProvider::pointCount ( ) const
inlinenoexcept

Number of stored points. ExternalFile mode reports 0 until the read-through cache is implemented in its dedicated sub-phase.

Here is the caller graph for this function:

◆ points()

const QVector< TimeseriesPoint > & openswmmvis::timeseries::TimeseriesProvider::points ( ) const
inlinenoexcept

All points (const ref).

◆ pointsChanged

void openswmmvis::timeseries::TimeseriesProvider::pointsChanged ( int  firstIndex,
int  count 
)
signal

Points in [firstIndex, firstIndex+count) had their value changed in place.

Here is the caller graph for this function:

◆ pointsInserted

void openswmmvis::timeseries::TimeseriesProvider::pointsInserted ( int  at,
int  count 
)
signal

count points were inserted starting at at.

Here is the caller graph for this function:

◆ pointsRemoved

void openswmmvis::timeseries::TimeseriesProvider::pointsRemoved ( int  at,
int  count 
)
signal

count points were removed starting at at.

Here is the caller graph for this function:

◆ relativeAnchor()

QDateTime openswmmvis::timeseries::TimeseriesProvider::relativeAnchor ( ) const
inlinenoexcept

Simulation start the relative points' absolute times are anchored to (invalid when the series has no relative rows).

◆ relativeCount()

int openswmmvis::timeseries::TimeseriesProvider::relativeCount ( ) const
inlinenoexcept

Leading points authored as elapsed-time-from-start.

◆ removePointsAt()

void openswmmvis::timeseries::TimeseriesProvider::removePointsAt ( QVector< int >  indices)

Remove points by index. Indices are deduplicated + sorted descending internally so the loop is safe.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setAllPoints()

bool openswmmvis::timeseries::TimeseriesProvider::setAllPoints ( QVector< TimeseriesPoint newPoints,
QString *  reasonOut = nullptr 
)

Replace the entire point list. Validates strict-monotone time before applying. Atomic: either all replaced or none.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setDescription()

void openswmmvis::timeseries::TimeseriesProvider::setDescription ( QString  d)
Here is the call graph for this function:

◆ setFileSource()

void openswmmvis::timeseries::TimeseriesProvider::setFileSource ( QString  path,
QString  columnSelector,
QDateTime  mtime 
)
Here is the call graph for this function:

◆ setName()

void openswmmvis::timeseries::TimeseriesProvider::setName ( QString  newName)

Rename the Tseries. Uniqueness is the registry's responsibility; this just stores + notifies.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setPointAt()

bool openswmmvis::timeseries::TimeseriesProvider::setPointAt ( int  i,
QDateTime  newTime,
double  newValue,
QString *  reasonOut = nullptr 
)

Change both time + value at index i. Validates that the new time still slots between neighbours strictly.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setRelativeInfo()

void openswmmvis::timeseries::TimeseriesProvider::setRelativeInfo ( int  count,
QDateTime  anchor,
int  allRelativeIntent = -1 
)

Raw restore used by registry load and undo: sets the prefix count (clamped to [0, pointCount()]), the anchor, and — when allRelativeIntent is 0/1 — the sticky "author every new row as relative" flag (-1 derives it as count > 0 && count == pointCount(), which for an EMPTY series means count > 0 requests relative intent). Emits timeModeChanged() when the derived mode or anchor changes.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setSourceMode()

void openswmmvis::timeseries::TimeseriesProvider::setSourceMode ( SourceMode  mode)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setTimeMode()

void openswmmvis::timeseries::TimeseriesProvider::setTimeMode ( TimeMode  mode,
QDateTime  anchorForRelative = {} 
)

User-facing mode switch. Relative marks every current point relative and records anchorForRelative (when valid) as the anchor; Absolute clears the prefix. Mixed is a loaded state, not a target — requesting it is a no-op.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setUnitsLabel()

void openswmmvis::timeseries::TimeseriesProvider::setUnitsLabel ( QString  units)
Here is the call graph for this function:

◆ setValueAt()

bool openswmmvis::timeseries::TimeseriesProvider::setValueAt ( int  i,
double  newValue,
QString *  reasonOut = nullptr 
)

Change only the value at index i. Time stays put so monotonicity is preserved by construction.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setValueLive()

bool openswmmvis::timeseries::TimeseriesProvider::setValueLive ( int  i,
double  newValue 
)

Live variant of setValueAt for drag-edit: does NOT push undo per-frame (caller handles batching). Same monotonicity guarantee.

Here is the call graph for this function:

◆ sourceMode()

SourceMode openswmmvis::timeseries::TimeseriesProvider::sourceMode ( ) const
inlinenoexcept

◆ sourceModeChanged

void openswmmvis::timeseries::TimeseriesProvider::sourceModeChanged ( SourceMode  prev,
SourceMode  now 
)
signal

Source mode flipped.

Here is the caller graph for this function:

◆ timeMode()

TimeseriesProvider::TimeMode openswmmvis::timeseries::TimeseriesProvider::timeMode ( ) const
noexcept

Derived mode: Relative when every point is in the relative prefix (or an empty series carries relative intent), Absolute when the prefix is empty, Mixed otherwise.

Here is the caller graph for this function:

◆ timeModeChanged

void openswmmvis::timeseries::TimeseriesProvider::timeModeChanged ( )
signal

The derived timeMode() flipped, or the relative anchor moved. Payload-free; subscribers re-read (metadataChanged style).

Here is the caller graph for this function:

◆ unitsLabel()

QString openswmmvis::timeseries::TimeseriesProvider::unitsLabel ( ) const
inlinenoexcept

Units label inferred from column suffix or set explicitly (e.g. "m", "ft³/s"). UI hint only — no unit conversion happens here.


The documentation for this class was generated from the following files: