Timeline: decide upon the diff format expected for creating a timeline

other than the regular way of building an object,
we do expect a minimal structure to be sent right within the INS message.

Rationale: the standard way would allow for too much leeway and created
unwanted intermediary states. The non-standard way decided upon here
is well within the limits of our diff language
This commit is contained in:
Fischlurch 2018-10-13 02:46:09 +02:00
parent edf577187b
commit bfca473dce
5 changed files with 512 additions and 263 deletions

View file

@ -50,6 +50,7 @@
#include "proc/cmd.hpp"
#include "backend/real-clock.hpp"
#include "lib/diff/tree-mutator.hpp"
#include "lib/format-string.hpp"
#include "lib/format-obj.hpp"
//#include "gui/ui-bus.hpp"
//#include "lib/util.hpp"
@ -58,6 +59,7 @@
//#include <list>
//using util::isnil;
using util::_Fmt;
//using std::list;
//using std::shared_ptr;
using lib::idi::EntryID;
@ -65,6 +67,7 @@ using lib::hash::LuidH;
using lib::diff::Rec;
using lib::diff::TreeMutator;
using lib::diff::collection;
using lib::diff::LUMIERA_ERROR_DIFF_STRUCTURE;
using std::make_unique;
using util::toString;
@ -309,6 +312,38 @@ namespace interact {
}
namespace {
/**
* The timeline is actually a front-end to a binding to a root track.
* For that reason, we always create the root-track representation alongside
* the timeline, and thus we need a very special INS message to create a timeline:
* - it must be a record (an "object")
* - a nested attribute with key ATTR_fork is mandatory
* - this nested attribute likewise needs to be a record
* - and must be tagged with TYPE_Fork
* More specifically, the usual way to deliver such a structure is not allowed here,
* which would be first to send an empty record and then to open and populate it.
* All the elements mentioned above need to be present right within the payload
* value of the INS message creating the timeline. This non-standard format is
* perfectly legal in our tree diff language (just requires a heap allocation
* behind the scenes to hold the nested data, but who cares?)
*/
ID
verifyDiffStructure_and_extract_RootTrack (GenNode const& spec)
{
if (not (spec.data.isNested()
and spec.data.get<Rec>().hasAttribute(string{ATTR_fork})
and TYPE_Fork == spec.data.get<Rec>().get(string{ATTR_fork}).data.recordType()
) )
throw error::State (_Fmt{"When populating a new Timeline, a root track must be given immediately"
"nested into INS message. We got the following initialisation payload: %s"}
% spec
, LERR_(DIFF_STRUCTURE));
return spec.data.get<Rec>().get(string{ATTR_fork}).idi;
}
}
/** @internal allocate a new TimelineWidget and attach it as child.
* @todo is it really necessary to make such strong assumptions
* regarding the format of the diff spec provided for
@ -319,11 +354,8 @@ namespace interact {
{
unimplemented ("allocate a TimelineWidget in some TimelinePanel and attach it's controller as child entity");
REQUIRE (spec.data.isNested());
REQUIRE (spec.data.get<Rec>().hasAttribute(string{ATTR_fork}));
REQUIRE (TYPE_Fork == spec.data.get<Rec>().get(string{ATTR_fork}).data.recordType());
TimelineGui anchorProxy{spec.idi, spec.data.get<Rec>().get(string{ATTR_fork}).idi};
ID rootTrack = verifyDiffStructure_and_extract_RootTrack (spec);
TimelineGui anchorProxy{spec.idi, rootTrack};
anchorProxy.buildTimelineWidget (this->uiBus_); ///////////////////////////////////////////TODO really create it right here?
return anchorProxy;
}

View file

@ -157,12 +157,12 @@ namespace timeline {
return true;
}))
.mutateAttrib(ATTR_fork, [&](TreeMutator::Handle buff)
{ // »Attribute Mutator« : how enter an object field as nested scope
{ // »Attribute Mutator« : how to enter an object field as nested scope
REQUIRE (fork_);
fork_->buildMutator(buff);
})
.change(ATTR_name, [&](string val)
{ // »Attribute Setter« : how assign a new value to some object field
{ // »Attribute Setter« : how to assign a new value to some object field
name_ = val;
}));
}

View file

@ -100,7 +100,8 @@ namespace diff{
namespace error = lumiera::error;
LUMIERA_ERROR_DECLARE(DIFF_CONFLICT); ///< Collision in diff application: contents of target not as expected.
LUMIERA_ERROR_DECLARE(DIFF_STRUCTURE); ///< Invalid diff structure: implicit rules and assumptions violated.
LUMIERA_ERROR_DECLARE(DIFF_CONFLICT); ///< Collision in diff application: contents of target not as expected.
template<class I, typename E>

View file

@ -39,6 +39,7 @@
namespace lib {
namespace diff{
LUMIERA_ERROR_DEFINE(DIFF_STRUCTURE, "Invalid diff structure: implicit rules and assumptions violated.");
LUMIERA_ERROR_DEFINE(DIFF_CONFLICT, "Collision in diff application: contents of target not as expected.");

File diff suppressed because it is too large Load diff