From 06163f6016451f45bc12a3ffdb33c82be024e1e8 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 21 Jun 2019 23:18:44 +0200 Subject: [PATCH] Timeline: filter to select the pinned prefix part of the profile ...when rendering this part, which shall be always visible. And the rest of the profile needs to be rendered into a second canvas, which is placed within a pane with scrollbar. Implemented as a statefull iterator filter --- research/try.cpp | 249 +++------------------- src/stage/timeline/body-canvas-widget.cpp | 3 +- src/stage/timeline/track-profile.hpp | 60 +++++- wiki/thinkPad.ichthyo.mm | 116 ++++++++-- 4 files changed, 183 insertions(+), 245 deletions(-) diff --git a/research/try.cpp b/research/try.cpp index e108c4e0d..a99028e37 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -42,18 +42,15 @@ // 10/18 - investigate insidious reinterpret cast // 12/18 - investigate the trinomial random number algorithm from the C standard lib // 04/19 - forwarding tuple element(s) to function invocation +// 06/19 - use a statefull counting filter in a treeExplorer pipeline /** @file try.cpp - * Research how to apply a tuple to a varargs function forwarder. - * The recent standard library has a std::apply, which we can not yet use, unfortunately. - * @note this research remains inconclusive. As far as I can see, the simplified setup - * exactly mimics the problematic call situation; however, in the real use case, - * we need to std::forward the argument tuple object field while here in - * this simplified case, it compiles just fine without -- as it should after all, - * since that is the whole point of perfect forwarding; std::get should expose - * a LValue reference to the tuple element, and we pass that through a forwarding - * function into the double dispatch to the receiving visitor. + * How to pick a configurable prefix segment from an iterable sequence. + * Instead of using a classic indexed for loop, the same effect can be achieved + * through a statefull filter functor in a `treeExplore()`-pipeline; after full + * optimisation I'd expect even to get the same assembly as from an equivalent + * hand written for loop. (Caveat: debug builds will be bloated) */ typedef unsigned int uint; @@ -61,17 +58,13 @@ typedef unsigned int uint; #include "lib/format-cout.hpp" #include "lib/test/test-helper.hpp" #include "lib/util.hpp" -#include "lib/verb-visitor.hpp" - -#include "lib/meta/variadic-helper.hpp" +#include "lib/iter-tree-explorer.hpp" #include #include -#include +#include -using lib::Literal; using std::string; -using std::tuple; @@ -80,219 +73,37 @@ using std::tuple; #define SHOW_EXPR(_XX_) \ cout << "Probe " << STRINGIFY(_XX_) << " ? = " << _XX_ < -void -forwardInvoker (FUN& fun, ARGS&&... args) +template +auto +selectSeg(IT&& it, bool useFirst) { - cout << "forwardInvoker...\n" - << lib::test::showVariadicTypes(args...) - << endl; - fun (std::forward(args)...); -} - -template -struct Holder - { - using Args = tuple; - - Args tup; - - Holder (Args& tup) - : tup{tup} - { } - -template -void -unpack_and_forward (FUN& fun, lib::meta::IndexSeq) -{ - cout << "unpack_and_forward...\n"; - SHOW_TYPE (Args) - - forwardInvoker (fun, std::get (tup)...); -} - -void -applyTuple (FUN& fun) -{ - cout << "applyTuple...\n"; - SHOW_TYPE (Args) - - using SequenceIterator = typename lib::meta::BuildIdxIter::Ascending; - - unpack_and_forward (fun, SequenceIterator()); -} - }; - - - - ///////////////////////////TODO : Debugging - struct Trackr - { - size_t num; - - Trackr (size_t val) - : num(val) + struct CountingFilter { - cout <<"Trackr("< buggy; -// return verb_.applyTo (receiver, std::get (std::forward(args_))...); /// <<------------this compiles, but consumes the tuple's content (move init) -// return verb_.applyTo (receiver, std::get (args_)...); -// return (receiver.*handler_)(std::get (args_)...); /// <<------------this works -// return applyToVerb (receiver, std::get (args_)...); -// return getVerbFun(receiver) (std::get (args_)...); /// <<------------this compiles, but creates a spurious copy - return verb_.applyTo (receiver, forwardElm (args_)...); /// <<------------this compiles, but consumes the tuple's content (move init) - } - - template - using TupleElmType = typename std::tuple_element::type; - - template -// std::remove_reference_t (args))>&& - TupleElmType&& - forwardElm (Args& args) - { - using ElmRef = decltype(std::get (args)); - using Elm = std::remove_reference_t>; + int cnt; + bool useFirst; - return std::forward> (std::get (args)); - } - - RET - applyToVerb (REC& receiver, ARGS&& ...args) - { -// REQUIRE ("NIL" != token_); - return (receiver.*handler_)(std::forward(args)...); - } - -// std::function - decltype(auto) - getVerbFun(REC& receiver) - { - return [&](ARGS...args) -> RET - { - return (receiver.*handler_)(std::forward(args)...); - }; - } - }; - -using lib::meta::Yes_t; -using lib::meta::No_t; - -META_DETECT_FUNCTION(void, cloneInto, (void*) const); -META_DETECT_FUNCTION_NAME(cloneInto); + bool + operator() (...) + { + bool isPrefixPart = 0 < cnt--; + return useFirst? isPrefixPart : not isPrefixPart; + } + }; + return lib::treeExplore(std::forward (it)) + .filter(CountingFilter{50, useFirst}); +} int main (int, char**) { - auto tup = std::make_tuple(1,2,3); - auto fun = [](int a, int b, int c) - { - cout << a<<"+"<; - Hol holder(tup); - holder.applyTuple (fun); - - - uint zwo{2}; - std::tuple trp{zwo,Trackr(3)}; - auto frn = [](uint& x, Trackr y) - { - cout << x<<"*Trckr("<; - Hrl hrlder(trp); - hrlder.applyTuple (frn); - cout << "\n.ulps.\n"; - - Hodler holyh(&Receiver::grrrn, "holyhandgrenade", zwo, Trackr(5)); - Receiver recy; -// recy.grrrn (std::get<0>(trp), Trackr(5)); - holyh.applyTo (recy); - - cout << "---Types---"<; - using CloneI = lib::polyvalue::CloneValueSupport; - SHOW_TYPE(BussI); - SHOW_EXPR (lib::polyvalue::exposes_CloneFunction::value) - SHOW_EXPR (HasFunSig_cloneInto::value) - SHOW_EXPR (HasFunSig_cloneInto::value) - SHOW_EXPR (HasFunName_cloneInto::value) - SHOW_EXPR (HasFunName_cloneInto::value) - using BussP = decltype(&BussI::cloneInto); - SHOW_TYPE(BussP) + using VecN = std::vector; + VecN numz{1,1,2,3,5,8,13,21}; + for (auto& elm : selectSeg(numz, false)) + cout << elm<<"::"; + for (auto& elm : selectSeg(numz, true)) + cout << elm<<"::"; cout << "\n.gulp.\n"; return 0; diff --git a/src/stage/timeline/body-canvas-widget.cpp b/src/stage/timeline/body-canvas-widget.cpp index 362270d2c..17733544b 100644 --- a/src/stage/timeline/body-canvas-widget.cpp +++ b/src/stage/timeline/body-canvas-widget.cpp @@ -220,8 +220,7 @@ namespace timeline { return [&](CairoC cox) { PINT concreteRenderScheme{cox, layout}; - /////////////////////////////////////////////////////////////////////////////////TICKET #1039 : find out a way how to select the header/body part of the profile! - getProfile().performWith (concreteRenderScheme); + getProfile().performWith (concreteRenderScheme, isRuler); }; } diff --git a/src/stage/timeline/track-profile.hpp b/src/stage/timeline/track-profile.hpp index d44c2fb55..f2baea533 100644 --- a/src/stage/timeline/track-profile.hpp +++ b/src/stage/timeline/track-profile.hpp @@ -41,6 +41,7 @@ #include "stage/gtk-base.hpp" #include "lib/verb-visitor.hpp" +#include "lib/iter-tree-explorer.hpp" #include "lib/symbol.hpp" #include "lib/util.hpp" @@ -110,6 +111,10 @@ namespace timeline { slopeVerb.applyTo (interpreter); } + void performWith (ProfileInterpreter& interpreter, bool selectRuler); + + + private:/* ===== Internals: handling tokens ===== */ template @@ -151,12 +156,6 @@ namespace timeline { append_close (1); } - uint - getPinnedPrefixCnt() - { - return firstEntryIs("prelude")? elements.front().accessArg() : 0; - } - private: bool firstEntryIs (Literal expectedToken) @@ -180,8 +179,57 @@ namespace timeline { ++ slopeDepth; } + + int + getPinnedPrefixCnt() + { + return firstEntryIs("prelude")? elements.front().accessArg() : 0; + } + + auto + filterSegment(bool selectPrefixPart) + { + struct CountingFilter + { + int cnt; + bool selectPrefix; + + bool + operator() (...) + { + bool isPrefixPart = 0 < cnt--; + return selectPrefix? isPrefixPart : not isPrefixPart; + } + }; + + + return lib::treeExplore(elements) + .filter(CountingFilter{getPinnedPrefixCnt(), selectPrefixPart}); + } }; + /** + * A variation of standard evaluation, only rendering one segment of the profile. + * The `prelude` verb defines a special _prefix part_ of the track profile, which + * is assumed to correspond to the timecode ruler tracks. These special _overview_ + * tracks are rendered _always visible_ at the top of the timeline, even when scrolling + * down on large arrangements with several tracks. Effectively this means we have to + * split the TrackProfile into two segments, which are to be rendered within two + * distinct TimelineCanvas widgets (the first one always on top, while the second one + * with the actual track content is shown within pane with scrollbars). + * @param selectRuler decide if this evaluation shall render the overview rulers + * (when given `true`) or alternatively the remaining standard body + * part of the timeline (when given `false`). + */ + inline void + TrackProfile::performWith (ProfileInterpreter& interpreter, bool selectRuler) + { + for (auto& slopeVerb : filterSegment(selectRuler)) + slopeVerb.applyTo (interpreter); + } + + + }}// namespace stage::timeline #endif /*STAGE_TIMELINE_TRACK_PROFILE_H*/ diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a07bb19e6..e509f695f 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -16671,7 +16671,7 @@ - + @@ -18018,7 +18018,7 @@ - + @@ -19241,7 +19241,8 @@ - + + @@ -20619,9 +20620,9 @@ - + - + @@ -20712,6 +20713,60 @@ + + + + + + + + + + + + + + + + + + + + +

+ d.h. ich will den Standardfall als Standardfall sichtbar haben, +

+

+ und dann diese zusätzliche Filterung oben drauf pflanzen +

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

+ als ob es darauf ankäme... +

+

+ Hauptsache, keine zusätzliche Speicher-Allokation +

+ + +
+
+
@@ -20761,9 +20816,11 @@
- + + + - + @@ -20792,17 +20849,19 @@ - + + - - + + - + + @@ -20832,8 +20891,16 @@ - + + + + + + + + + @@ -20848,7 +20915,8 @@ - + + @@ -20939,7 +21007,14 @@ - + + + + + + + + @@ -21175,7 +21250,7 @@ - + @@ -21214,6 +21289,10 @@ + + + + @@ -22982,7 +23061,7 @@ - + @@ -23455,7 +23534,8 @@ - + + @@ -41818,7 +41898,7 @@ - +