Commit graph

4412 commits

Author SHA1 Message Date
2a6e48d7b5 immutable-arguments(#989): verify the tuple builder can handle those too
incidentally, this uncovered yet another unwanted narrowing conversion,
namely from double via gavl_time_t to TimeValue or alternatively
from double via FSecs (= rational<long>) to Duration.

As in all the previos cases, actually the compiler is to blame,
and GCC-5 is known to get that one right, i.e. let the SFINAE fail
instead of passing it with a "narrowing conversion" warning.



Note: the real test for command binding with immutable types
can be found in BusTerm_test
2016-02-07 02:20:01 +01:00
e0f866092d rectify-design(#301): disentangle CmdClosure hierarchy
Completely removed the nested hierarchy, where
the top-level implementation forwarded to yet another
sub-implementation of the same interface. Rather, this
sub-implementation (OpClosure) is now a mere implementation
detail class without VTable, and without half-baked
re-implementation of the CmdClosure interface. And the
state-switch from unbound to bound arguments is now
implemented as a plain-flat boolean flag, instead of
hiding it in the VTable.

To make this possible, without having to rewrite lots of
tests, I've created a clone of StorageHolder as a
"proof-of-concept" dummy implementation, for the sole
purpose of writing test fixtures. This one behaves
similar to the real-world thing, but cares only
for closing the command operation and omits all
the gory details of memento capturing and undo.
2016-02-07 01:41:40 +01:00
9515e45723 evolution(#967): simplify by variadic arguments 2016-02-06 22:17:48 +01:00
a7cd8996aa immutable-arguments(#989): proof-of concept
seems to work as assumed; we'll just have to construct
a new holder tuple in place when binding arguments.
Doesn't look too bad for me
2016-02-06 19:42:41 +01:00
91e74b0456 clean-up(#301): separate inclusions by purpose
and remove some superfluous ones
2016-02-06 19:41:21 +01:00
9847888a00 make TimeSpan default constructible
...probably just an omission. TimeValue and Time are
also default constructible, and this makes sense, semantically.

Please note that Time values are *immutable* though.
Only TimeVar can be reassigned. This is so by design
2016-02-06 19:23:16 +01:00
37fb19ae0a refactoring: separate headers 2016-02-06 18:50:51 +01:00
2fbb7ba7c9 simplification(#301): use ctor chaining to remove clutter 2016-02-06 16:42:42 +01:00
be2179ea81 command-closure-design(#301): better naming of implementation classes
Seems this was part of the confusion when looking at
the inheritance graph: Names where almost reversed
to the meaning. the ArgumentHolder was *not* the
argument holder, but the top level closure. And
the class "Closure" was not "the" Closure, but
just the argument holder. ;-)
2016-02-06 16:29:06 +01:00
dfc28ca2a0 UI-Bus command handling protocol unit test PASS
still TODO: the ability to use immutable types
within the command framework. In theory, this
shouldn't be had to implement, since we're creating
a new opaque value holder within the command registry
anyway, so it should be sufficient to refrain from
re-assigning a new value tuple. This is relevant,
since e.g. our time framework is built on immutable
value types.
2016-02-06 01:28:39 +01:00
deb7a6758c add diagnostic output to the command implementation record
...allows better diagnostic in tests, when handling a command
through the new mock handling pattern within Test-Nexus
2016-02-05 23:55:07 +01:00
3faf586c56 format-frontend: print bool values textually
recently, I've introduced this ability in our toString template.
as it turned out, the bool type was not selected by our
boost::format frontend for special treatment, thus showing
just the fallback «bool»
2016-02-05 23:53:12 +01:00
20bdee4acc convenience ctor condition in Variant to build string from char literal
Because this is especially annoying when constructing any type
based on lib::Variant, which is assumed to hold a string.
2016-02-05 22:33:50 +01:00
743a30c1ed command binding via UI-Bus implemented and covered in mock setup 2016-02-05 17:07:42 +01:00
3f22150ab3 back to topic: get all the arguments of command binding logged
...when the Test-Nexus processes a command binding message.
In the real system of course we do not want to log every bind message.

The challenge here is the fact that command binding as such
is opaque, and the types of the data within the bind message
are opaque as well. Finally I settled on the compromise
to log them as strings, but only the DataCap part;
most value types applicable within GenNode
have a string representation to match.
2016-02-05 15:55:22 +01:00
536a3a94b9 add special iteration mechanism to visit enclosed child data
the rationale is that I deliberately do not want to provide
a mechanism to iterate "over all contents in stringified form".
Because this could be seen as an invitation to process GenNode-
datastructures in an imperative way. Please recall we do not
want that. Users shall either *match* contents (using a visitor),
or they are required to know the type of the contents beforehand.
Both cases favour structural and type based programming over
dynamic run-time based inspection of contents

The actual task prompting me to add this iteration mechanism
is that I want to build a diagnostic, which allows to verify
that a binding message was sent over the bus with some
specific parameter values.
2016-02-05 04:03:11 +01:00
1913620f37 integrate new stringify() variant and add test coverage
...also for the existing variant, which packages an
arbitrary number of arguments in stringified form
into a given container type. Moreover, the new
form of stringify allows to write util::join
in a clearer way, eliminating the lambda.
2016-02-04 23:30:49 +01:00
2cb1ea6920 devise a pipeline based variant of stringify() 2016-02-04 23:05:41 +01:00
0208451906 correctness: should use less-than comparison to detect iteration end
...since, semantically, the template param INT is expected to be
"number like", which implies to base the "in range" notion
on a comparison concept (e.g. we might use floating point numbers)
2016-02-04 22:58:17 +01:00
170bca7044 const correctness: should define the value without const
these typedefs are provided for client code to pick up
the actual type; and for value_type we'd expect the
type without any adornments
2016-02-04 22:53:39 +01:00
34feedf82f sanity: should have defined those operators inline
...this was clearly wrong; it went unnoticed just
because the linker cleans up duplicates of
template instantiations. (I'd expect GCC-5
to spot such errors)
2016-02-04 22:52:01 +01:00
8a33048cc7 simple number range iterator
very similar to boost::irange, but without heavyweight boost
includes, and moreover based on our Lumiera Forward Iterator concept

Such a inline-range construct makes writing simple tests easy
2016-02-04 22:01:48 +01:00
3fef76e1d7 command-binding(#990): add new GenNode based argument binding
based on the new generic tuple builder, we're now able to
add a new binding function into the command implementation
machinery, alongside the existing one. As it stands, the
latter will be used rather by unit tests, while the new
access path is what will be actually taken within
the application, when receiving argument binding
messages dispatched via the UI-Bus.
2016-01-29 00:59:34 +01:00
5abc44b813 additional coverage regarding the restrictive handling of LuidH 2016-01-28 23:30:13 +01:00
fc193da1ac unit-test for tuple initialisation from GenNode
- leave out the type conversion part
- instead verify error handling on some typical corner cases
2016-01-28 22:39:38 +01:00
f2cbac14e2 test-suite: fix lots of missing return value checks
without that check, in theory our test runner will tolerate
a non-zero return value, like throwing or failing an assert,
which is not what we want....

guess these happenend to get in by forgetting to
add this check when switching a test from PLANNED to TEST
2016-01-28 22:30:24 +01:00
69d2a4148d tuple initialisation from GenNode: disallow any numerical conversion from LUID
since this is a quick-n-dirty workariound, until we're using GCC-5,
I'll err for the simple and safe side and disallow any conversion
from LuidH do some algebraic data type. The problem arises,
sincd LuidH defines a conversion to size_t, which depends
on the platform. So, without checking the actual NumericLimits,
there is no way we can allow a conversion to size_t in a
hard wired way, while disallowing a narrowing conversion
to 32bit unsigned int on 64bit platforms.

And in the end, we don't want conversions from LUID to
numeric values to happen automatically anyway. But of
course we *do* want automatic promotion from a LuidH
to a PlacementRef...
2016-01-28 21:21:41 +01:00
80ca498d79 put variant predicate interface in non-anonymous namespace
...to avoid warnings when deriving a publicly visible type
from that interface. Newer GCC and CLang versions emit
warnings when details from an anonymous implementation
namespace will leak into type signatures visible outside
the translation unit. In this case here, it's the VTable.
2016-01-28 21:05:07 +01:00
47ce7ad96b research finished: build a (compiletime) tuple from runtime sequence
...should document this by a unit-test
2016-01-28 15:37:35 +01:00
ae7912dc99 refactoring: move new library helpers into final destination 2016-01-28 15:19:09 +01:00
e748473b77 refactoring: a reworked version of init argument mapper
...used in function-closure.hpp to fabricate an argument tuple
for std::bind, for partially closing some function.

This is an attempt to rewrite this somewhat convoluted helper
in a way to fit in with the tuple element picking mechanism
just defined here. Not sure if it's better readable now;
at least it is significantly shorter and omits some
partial specicalisations
2016-01-28 00:28:56 +01:00
803292dda5 refactoring: towards a more generic formulation
because this element picking mechanism for tuples
looks like an instance of something generic.

At least I've written almost the same just some days ago
for the revised version of function-closure, where the
task was to replace a stretch of type arguments in
a given tuple type with a stretch of placeholder types
and then to build a modified ctor, which just fills
in the remaining arguments, while default constructing
the placeholder types. And if we look into the GNU
implementation of std::bind, they're using a similar
concept (with the difference that they're building
a functor object, where we use a type converter)


This refactoring also integrates some generally useful
bits into our standard metaprogramming helper collection
2016-01-27 12:38:16 +01:00
1cbebb1fab research: investigate narrowing conversion problem
as it turns out, this is a Bug in GCC 4.9 (resolved in 5.x)
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63723

Problem is, GCC emits a warning on narrowing conversions,
while the standard actually disallows them when building
objects from brace-enclosed initialisers.

Unfortunately GCC also emits such a warning from within
a SFINAE context, instead of letting those spurious dangerous
cases fail. So we end up with additional visitor double dispatch
paths, and a lot of additional warnings.

Temporary solution is to hack a custom trait, which
explicitly declares some conversions paths as "narrowing".
Probably this can be implemented in a way more intelligent
way (using std::numeric_limits), but this doesn't seem
worth the effort, since the problem will go away through
compiler evolution eventually.
2016-01-24 13:44:12 +01:00
f4bcdcf4e8 research: full solution, including double-dispatch converter stack
now we're able to construct suitable parameter values from the
arguments passed embedded in the GenNodes, as is demonstrated with the
EntryID<long> constructed from an ID-string. We really need a full-blown
double-dispatch, since the content type of the concrete GenNode is only
known at runtime (encoded in the RTTI)

There is still the problem with generating some spurions additional
conversion pathes, some of which are narrowing (and thus dangerous).
The copiler emits several warnings here, and all of them are justified.

E.g. it would be possible to pass an int64_t in the GenNode and initialise
a short from it. This might be convenient at times, but I tend rather to
be prohibitive here and thus consider to built in distinct limitations
on the allowed conversions.
2016-01-24 00:15:19 +01:00
02b84cd6dc research: solution skeleton, without type conversion
working with those variadic index sequences is quite nasty!
Seemingly you'd always need a 2-step type rebinding,
tried several hours now to avoid that, sorry.


What still needs to be settled is the actual problem
of type conversions; we do not want to be confined
just to the small selection of types allowed within
GenNode, rather we want automatic type promotion
when it comes to extracting values into ctor args!
2016-01-23 17:30:43 +01:00
f743784bc9 add accessor for Nth child to our Record type 2016-01-23 17:10:44 +01:00
a95103eb3b research: define new metaprogramming task
need to bridge between generic typing of tuples
and the DOM-like typing of UI-Bus messages
2016-01-23 11:57:19 +01:00
16597fcd99 extend command API to also accept a lib::diff::Rec<GenNode> for arguments
WIP: have to decide how the arguments can be unpacked
and how to generate proper runtime type mismatch errors.
2016-01-22 20:29:45 +01:00
1dc9642ec4 draft implementation of diagnostic command handler 2016-01-22 19:44:17 +01:00
cc310521a3 verify ability to use custom command handlers
...we're going to need this to implement a
dummy command handler in the test-nexus
2016-01-22 17:17:31 +01:00
005e665c13 clean-up design of the command handling patterns (#210)
this was a classical example of a muddled and messed-up design,
driven just by the fact that I wanted to "spare" some functions,
with the net effect of writing more functions, plus a proxy class
plus create a lot of confusion for the reader.

This was easy to resolve though, once I resorted to the
general adivice to make public interface methods final,
make the extension ponts protected and never
to chain two extension points
2016-01-22 15:25:08 +01:00
eaa12499f3 back to UI command invocation: basically implement a placeholder command
based on the previous experiments, this adds a fake operation
and a definition frame to hook this operation as pseudo Proc-Layer command

WIP: the invocation itself is not yet implemented.
     We need to build a custom invocation pattern for that,
     in order to be able to capture the instance-ID of the command
     on invocation

NOTE: also, because of #989, we can not bind a time value for this test
2016-01-22 12:19:25 +01:00
297f986b5f now able to remove our old Tuple type (closes #988)
all unit-tests PASS again
2016-01-20 01:25:40 +01:00
f6d04d4d02 refactoring(#988): switch correspoinging tests to std::tuple
...with this changeset, our own tuple type should be
basically disconnected and not used anymore
2016-01-19 23:53:20 +01:00
0e10ef09ec refactoring(#988): switch command framework to std::tuple
this was rather easy, since the stadard tuple is a drop-in replacement,
and we do nothing special here, beyond inheriting from a tuple type
2016-01-19 03:56:54 +01:00
fd2d56ca45 refactoring(#988): switch function-closure to std::tuple
not sure yet if any of this works, because the
technicalities of dealing with variadic types are
quite different to our LISP-style typelist processing.

The good news is that with variadic templates it is
indeed possible, to supply dynamically picked arguments
to another function taking arbitrary arguments.

This all relies on the feature to unpack argument packs,
and, more specifically, about the possiblity to "wrap"
this unpacking around interspersed function call syntax

template<size_t...i>
Xyz
do_something(MyTuple myTuple)
  {
    return Xyz (std::get<i> (myTuple) ... );
  }

Here the '...' will be applied to the i... and then
the whole std::get-construct will be wrapped around
each element. Mind bogging, but very powerful
2016-01-19 03:56:53 +01:00
3523b897c2 refactoring(#988): disentangle Tuple metafunctions
we made double use of our Tuple type, not only as a
generic record, but also as a metaprogramming helper.

This changeset replaces these helpers with other
metafunctions available for our typelists or type sequences

(with the exception of code directly related to Tuple itself,
since the intention is to delete this code alltogether shortly)
2016-01-17 00:19:10 +01:00
7ea7866163 design fix: use type sequences and lists coherently
there was a muddeled mix of type lists and type sequences,
and both where used for processing. Probably the origin
of that confusion was the design of our own Tuple class,
which is implemented based on typelists but accepts a
type sequence at the front-end. From there, a confusing
pattern of equivalence between lists and sequences emerged,
leading to several functions accepting "anything".

This misdesign is not eradicated yet, but in this specific
instance here, has cost me several hours to pinpoint a bug
introduced while refactoring.

See also #967 and #301
2016-01-17 00:19:10 +01:00
d784ea23f6 augment typelist definition to allow for rebinding
This definition -- together with the already existing specialisation
in typeseq-util, allows always to rebind from a given type-list back
to the corresponding type-sequence, by accessing the type member `Seq`
2016-01-16 04:03:08 +01:00
c4adc234b4 experiment: now bind a Proc-Layer command to these fabricated functions
yeah! it works.

some problems though.
- problem-A : reference arguments
  * we're storing the parameters as-is
  * for not-yet-bound commands we need to store default constructed values
  * together this means we can not handle reference arguments
- problem-B : noncopyable arguments
  * especially our Time values are noncopyable.
  * this is going to become a huge problem for sure!
2016-01-15 23:55:44 +01:00