From c4634837a376654350e04f61af693ce55b5e88b5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 30 Jan 2021 19:01:56 +0100 Subject: [PATCH] DisplayEvaluation: further testing and bugfixes - fix a regression introduced with the 3rd DisplayEvaluation pass - use references to pass the timings more efficiently to the ClipDelegate - DisplayEvalutation in fact has a real LifeCycle and is not disposable - generate the population diff for this test in canonical form --- src/stage/timeline/body-canvas-widget.cpp | 11 +- src/stage/timeline/body-canvas-widget.hpp | 1 + src/stage/timeline/clip-presenter.cpp | 4 +- src/stage/timeline/clip-presenter.hpp | 4 +- src/stage/timeline/clip-widget.cpp | 8 +- src/stage/timeline/clip-widget.hpp | 2 +- src/stage/timeline/display-evaluation.cpp | 11 +- src/stage/timeline/display-evaluation.hpp | 2 +- src/stage/timeline/track-presenter.hpp | 6 +- .../session/dummy-session-connection.cpp | 20 +- wiki/thinkPad.ichthyo.mm | 181 ++++++++++++++++-- 11 files changed, 216 insertions(+), 34 deletions(-) diff --git a/src/stage/timeline/body-canvas-widget.cpp b/src/stage/timeline/body-canvas-widget.cpp index 6308e2b1a..2a463403c 100644 --- a/src/stage/timeline/body-canvas-widget.cpp +++ b/src/stage/timeline/body-canvas-widget.cpp @@ -85,7 +85,6 @@ namespace timeline { namespace { /////////////////////////////////////////////////////TICKET #1213 : use proper zoom handling instead of dummy constants!! const int TODO_px_per_second = 25; - const int TODO_px_per_microtick = TODO_px_per_second / Time::SCALE; } /////////////////////////////////////////////////////TICKET #1213 : (END) get rid of these dummy constants!! namespace { // details of track background painting @@ -538,6 +537,14 @@ namespace timeline { adjust (mainCanvas_, canvasWidth, contentHeight); } + + void + BodyCanvasWidget::forceRedraw() + { + rulerCanvas_.queue_draw(); + mainCanvas_.queue_draw(); + } + TimelineCanvas& BodyCanvasWidget::getCanvas (int yPos) { @@ -571,7 +578,7 @@ namespace timeline { int BodyCanvasWidget::translateTimeToPixels (Time startTimePoint) const { - return TODO_px_per_microtick * _raw(startTimePoint); //////////TICKET #1213 : delegate zoom handling to the display manager (field #layout_) !! + return _raw(startTimePoint) * TODO_px_per_second / Time::SCALE; //////////TICKET #1213 : delegate zoom handling to the display manager (field #layout_) !! } /** respond to the DisplayEvaluation pass. diff --git a/src/stage/timeline/body-canvas-widget.hpp b/src/stage/timeline/body-canvas-widget.hpp index 1e665cd04..037786b83 100644 --- a/src/stage/timeline/body-canvas-widget.hpp +++ b/src/stage/timeline/body-canvas-widget.hpp @@ -161,6 +161,7 @@ namespace timeline { /** @internal Initially install the contents corresponding to the root track fork */ void installForkRoot (TrackBody& rootTrackBody); + void forceRedraw(); void disable(); /** @internal allow the header pane to follow our vertical scrolling movement */ diff --git a/src/stage/timeline/clip-presenter.cpp b/src/stage/timeline/clip-presenter.cpp index cb01bafb1..865af5f4c 100644 --- a/src/stage/timeline/clip-presenter.cpp +++ b/src/stage/timeline/clip-presenter.cpp @@ -71,7 +71,7 @@ namespace timeline { * @param timing (optional) start time point and duration of the clip. * @note Clip can not be displayed unless #timing is given */ - ClipPresenter::ClipPresenter (ID identity, ctrl::BusTerm& nexus, WidgetHook& view, optional timing) + ClipPresenter::ClipPresenter (ID identity, ctrl::BusTerm& nexus, WidgetHook& view, optional const& timing) : Controller{identity, nexus} , channels_{} , effects_{} @@ -162,7 +162,7 @@ namespace timeline { UNIMPLEMENTED ("how to create and wire an embedded canvas for the clip contents/effects"); } - int + uint ClipPresenter::determineRequiredVerticalExtension() const { REQUIRE (widget_); diff --git a/src/stage/timeline/clip-presenter.hpp b/src/stage/timeline/clip-presenter.hpp index 6c5ef8669..ef939fa36 100644 --- a/src/stage/timeline/clip-presenter.hpp +++ b/src/stage/timeline/clip-presenter.hpp @@ -97,7 +97,7 @@ namespace timeline { public: - ClipPresenter (ID, ctrl::BusTerm&, WidgetHook&, optional); + ClipPresenter (ID, ctrl::BusTerm&, WidgetHook&, optional const&); ~ClipPresenter(); @@ -109,7 +109,7 @@ namespace timeline { /** find out the number of pixels necessary to render this clip properly, * assuming its current presentation mode (abbreviated, full, expanded). */ - int determineRequiredVerticalExtension() const; + uint determineRequiredVerticalExtension() const; /** update and re-attach the presentation widget into its presentation context. * Will be called during the "re-link phase" of DisplayEvaluation, after the diff --git a/src/stage/timeline/clip-widget.cpp b/src/stage/timeline/clip-widget.cpp index e8adf48df..e8d2c8b52 100644 --- a/src/stage/timeline/clip-widget.cpp +++ b/src/stage/timeline/clip-widget.cpp @@ -175,7 +175,7 @@ namespace timeline { public: - ClipData(TimeSpan timings =TimeSpan{Time::NEVER, Duration::NIL}) + ClipData(TimeSpan const& timings =TimeSpan{Time::NEVER, Duration::NIL}) : ClipDelegate{} , start_{timings.start()} , len_{timings.duration()} @@ -255,7 +255,7 @@ namespace timeline { DormantClip(WidgetHook& displayAnchor) : ClipData{} , display_{displayAnchor} - , clipName_{"?name?"} + , clipName_{} { } /** state switch ctor */ @@ -327,7 +327,7 @@ namespace timeline { public: - ClipWidget(WidgetHook::Pos hookPoint, TimeSpan timings, uString clipName) + ClipWidget(WidgetHook::Pos hookPoint, TimeSpan const& timings, uString clipName) : HookedWidget{hookPoint, clipName} , ClipData{timings} { @@ -385,7 +385,7 @@ namespace timeline { ClipDelegate::Appearance - ClipDelegate::buildDelegate (PDelegate& manager, WidgetHook& view, optional timing) + ClipDelegate::buildDelegate (PDelegate& manager, WidgetHook& view, optional const& timing) { if (timing) manager.reset (new ClipWidget{view.hookedAt(*timing, defaultOffsetY), *timing, defaultName}); diff --git a/src/stage/timeline/clip-widget.hpp b/src/stage/timeline/clip-widget.hpp index be86fd0d5..f64d19a84 100644 --- a/src/stage/timeline/clip-widget.hpp +++ b/src/stage/timeline/clip-widget.hpp @@ -228,7 +228,7 @@ namespace timeline { * viable appearance style. This is the first incantation of #switchAppearance. */ static Appearance buildDelegate (PDelegate& manager, WidgetHook& view, - std::optional timing); + std::optional const& timing); private:/* ===== Internals ===== */ diff --git a/src/stage/timeline/display-evaluation.cpp b/src/stage/timeline/display-evaluation.cpp index ea7399b4c..5aa0d5a18 100644 --- a/src/stage/timeline/display-evaluation.cpp +++ b/src/stage/timeline/display-evaluation.cpp @@ -84,8 +84,7 @@ namespace timeline { void DisplayEvaluation::perform() { - REQUIRE (collectLayout_ == true, - "Lifecycle error: DisplayEvaluation object reused"); + this->reset(); // Phase-1 : collect Layout information forkRoot_->establishLayout (*this); canvas_->establishLayout (*this); @@ -94,6 +93,14 @@ namespace timeline { forkRoot_->establishLayout (*this); } + /** pristine state for the next DisplayEvaluation pass */ + void + DisplayEvaluation::reset() + { + collectLayout_ = true; + } + + diff --git a/src/stage/timeline/display-evaluation.hpp b/src/stage/timeline/display-evaluation.hpp index 673f5ef0b..b7a52ea46 100644 --- a/src/stage/timeline/display-evaluation.hpp +++ b/src/stage/timeline/display-evaluation.hpp @@ -117,7 +117,7 @@ namespace timeline { bool isCollectPhase() const { return this->collectLayout_; } private:/* ===== Internals ===== */ - + void reset(); }; diff --git a/src/stage/timeline/track-presenter.hpp b/src/stage/timeline/track-presenter.hpp index 1d9cb9834..f7b65c6e9 100644 --- a/src/stage/timeline/track-presenter.hpp +++ b/src/stage/timeline/track-presenter.hpp @@ -345,15 +345,15 @@ namespace timeline { inline void DisplayFrame::establishExtension (vector& clips, vector&) { - int maxVSize = max (explore (clips) + uint maxVSize = max (explore (clips) .transform([](PClip const& clip) { return clip->determineRequiredVerticalExtension(); })); this->body_.accomodateHeight(maxVSize); //////////////////////////////////////////////////////////////////////////////////////////TICKET #1211 : actually implement a coordination of head / body sizes here - int headSize = this->head_.get_height(); - int bodySize = this->body_.calcHeight(); + uint headSize = this->head_.get_height(); + uint bodySize = this->body_.calcHeight(); } /** re-flow and adjust after the global layout has been established diff --git a/src/steam/mobject/session/dummy-session-connection.cpp b/src/steam/mobject/session/dummy-session-connection.cpp index fac1f74f7..ef222a503 100644 --- a/src/steam/mobject/session/dummy-session-connection.cpp +++ b/src/steam/mobject/session/dummy-session-connection.cpp @@ -64,6 +64,7 @@ using lib::idi::RandID; using lib::time::Time; using lib::time::FSecs; using lib::time::Duration; +using lib::time::TimeSpan; //using util::cStr; using util::_Fmt; using std::string; @@ -113,12 +114,18 @@ namespace session { } GenNode - clip(string clipID) + clip (string clipID, TimeSpan timings) { return MakeRec() .type (string{stage::TYPE_Clip}) + .set(string{stage::ATTR_timing}, timings) .genNode(clipID); } + GenNode + clip (string clipID, Time start, Duration dur = Duration{FSecs{1}}) + { + return clip (clipID, TimeSpan{start,dur}); + } /** fabricate an attribute node based on the * human-readable part of the given elemen's ID */ @@ -132,7 +139,7 @@ namespace session { GenNode defineTiming (Time start, Duration dur = Duration{FSecs{1}}) { - return GenNode{string{stage::ATTR_timing}, lib::time::TimeSpan{start,dur} }; + return GenNode{string{stage::ATTR_timing}, TimeSpan{start,dur} }; } } //(End)Implementation details.... @@ -160,7 +167,8 @@ namespace session { const GenNode timeline = emptyTimeline (baseID, forkRootID); const GenNode rootTrackName = GenNode{string{stage::ATTR_name}, "Track-"+baseID}; const GenNode forkRoot = MakeRec().genNode(forkRootID); - const GenNode clip1 = clip ("Clip-1"); + const GenNode clip1 = clip ("Clip-1", Time::ZERO); + const GenNode clip2 = clip ("Clip-2", Time::NEVER); return MutationMessage{after(Ref::END) , ins (timeline) @@ -168,10 +176,14 @@ namespace session { , mut (forkRoot) , set (rootTrackName) , ins (clip1) + , ins (clip2) , mut (clip1) , ins (makeName(clip1)) - , ins (defineTiming(Time::ZERO)) , emu (clip1) + , mut (clip2) + , ins (makeName(clip2)) + , ins (defineTiming(Time{FSecs{5}}, Duration{FSecs{2}})) + , emu (clip2) , emu (forkRoot) , emu (timeline) }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 35fcd782f..e8e7ba6dd 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -22190,9 +22190,9 @@ - + - + @@ -22209,6 +22209,10 @@ + + + + @@ -22220,11 +22224,12 @@ - - + + + - + @@ -22275,17 +22280,83 @@ - + + + + + + + + + +

+ commit 5b33605469352f3403d44cb0d77ef3c224895f5b (HEAD, ichthyo/gui) +

+

+ Author: Ichthyostega <prg@ichthyostega.de> +

+

+ Date:   Mon Jan 25 03:06:27 2021 +0100 +

+

+ +

+

+     Clip: fill in minimal implementation to make the clip appear +

+ +
- - + + + + + + + + + + + + + + + + + +

+ Aber der Punkt ist, nach der reinen Lehre sollte eine solche Funktion eine Options-Monade zurückgeben. Aber ich wollte stattdessen den guten alten Fallback-Wert. Wenn man das erst mal akzeptiert, dann muß "man" verdammt noch einmal auch die Wertebereiche ernst nehmen +

+ + +
+
+
+
+
+ + + + + + + + + + + + + + +
+ @@ -22329,7 +22400,28 @@ - + + + + + + + + + + + + + + + +

+ also z.B: wenn man das TestControl schließt, oder auch nur den Fokus an das Lumiera-Hauptfenster gibt +

+ +
+
+
@@ -23528,7 +23620,7 @@
- + @@ -25719,7 +25811,13 @@
- + + + + + + + @@ -25768,6 +25866,7 @@ + @@ -25782,6 +25881,20 @@ + + + + + + +

+ Konvention: Clips mit start==Time::NEVER werden verborgen +

+ +
+ + +
@@ -28719,6 +28832,9 @@ + + + @@ -29278,6 +29394,7 @@
+ @@ -29286,7 +29403,9 @@ - + + + @@ -29313,6 +29432,9 @@ + + + @@ -29328,6 +29450,14 @@ + + + + + + + + @@ -30968,7 +31098,7 @@ - + @@ -31461,6 +31591,31 @@ + + + + + + + +

+ aus Performance-Gründen. +

+

+ Weil dann sofort bei ins(clip) == Konstruktion ein ClipDelegate vom Typ ClipWidget erzeugt, und in den GTK-Canvas geheftet wird.  Andernfalls würde erst ein DormantClip erzeugt, der dann erst später, wenn das timing-Attribut gesetzt wird, sich in ein ClipWidget verwandelt. Das wäre dann im Normalfall eine zusätzliche, unnötige Allokation +

+ +
+ +
+ + + + + + +
+