Skip to content

Commit

Permalink
Major changes: disabling implicit creation verbs; side effects retrie…
Browse files Browse the repository at this point in the history
…vable from Temporal::Update; Other minor improvements
  • Loading branch information
Epixu committed Aug 17, 2024
1 parent 5c5e43f commit e489b1b
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 126 deletions.
2 changes: 1 addition & 1 deletion source/Code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ namespace Langulus::Flow
op.Multicast(false);
Many output;
Many scope {op};
if (Execute(scope, lhs, output)) {
if (Execute(scope, lhs, output, true)) {
// The verb was executed at compile-time, so directly
// substitute LHS with the result
VERBOSE("Verb was executed at compile time: ", output);
Expand Down
142 changes: 96 additions & 46 deletions source/Executor.cpp

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions source/Executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ namespace Langulus::Flow
///
/// Tools for executing containers as flows
///
//LANGULUS_API(FLOW)
//bool Execute(const Many&, Many&, bool silent = false);
LANGULUS_API(FLOW)
bool Execute(const Many&, Many&);
bool Execute(const Many&, Many&, Many& output, bool silent = false);
LANGULUS_API(FLOW)
bool Execute(const Many&, Many&, Many& output);
LANGULUS_API(FLOW)
bool Execute(const Many&, Many&, Many& output, bool& skipVerbs);
bool Execute(const Many&, Many&, Many& output, bool& skipVerbs, bool silent = false);

LANGULUS_API(FLOW)
bool ExecuteAND(const Many&, Many&, Many& output, bool& skipVerbs);
bool ExecuteAND(const Many&, Many&, Many& output, bool& skipVerbs, bool silent = false);
LANGULUS_API(FLOW)
bool ExecuteOR(const Many&, Many&, Many& output, bool& skipVerbs);
bool ExecuteOR(const Many&, Many&, Many& output, bool& skipVerbs, bool silent = false);

LANGULUS_API(FLOW)
bool ExecuteVerb(Many&, Verb&);
bool ExecuteVerb(Many&, Verb&, bool silent = false);
LANGULUS_API(FLOW)
bool IntegrateVerb(Many&, Verb&);
bool IntegrateVerb(Many&, Verb&, bool silent = false);

} // namespace Langulus::Flow
22 changes: 12 additions & 10 deletions source/Temporal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,16 @@ Langulus::Time Temporal::GetUptime() const {

/// Advance the flow - moves time forward, executes stacks
/// @param dt - delta time
/// @param sideffects - any side effects produced by executing
/// @return true if no exit was requested
bool Temporal::Update(Time dt) {
bool Temporal::Update(Time dt, Many& sideffects) {
if (mStart == mNow) {
// We're at the beginning of time - execute the priority stack
VERBOSE_TEMPORAL(Logger::Purple,
"Flow before execution: ", mPriorityStack);

Many unused;
Execute(mPriorityStack, unused);
Many unusedContext;
Execute(mPriorityStack, unusedContext, sideffects);

VERBOSE_TEMPORAL(Logger::Purple,
"Flow after execution: ", mPriorityStack);
Expand All @@ -153,7 +154,7 @@ bool Temporal::Update(Time dt) {
while (ticks >= pair.mKey) {
// Time to execute the periodic flow
pair.mValue.Reset();
pair.mValue.Update();
pair.mValue.Update({}, sideffects);
ticks -= pair.mKey;
}

Expand All @@ -171,7 +172,7 @@ bool Temporal::Update(Time dt) {

// Always update all time points before the tick count
// They might have periodic flows inside
pair.mValue.Update(dt);
pair.mValue.Update(dt, sideffects);
}

return true;
Expand Down Expand Up @@ -232,7 +233,7 @@ void Temporal::Merge(const Temporal& other) {
/// @attention assumes argument is a valid scope
/// @param scope - the scope to analyze and push
/// @return true if the flow changed
bool Temporal::Push(Many scope) {
Many Temporal::PushInner(Many scope) {
VERBOSE_TEMPORAL_TAB("Pushing: ", scope);

// Compile pushed scope to an intermediate format
Expand All @@ -241,18 +242,19 @@ bool Temporal::Push(Many scope) {

// Link new scope with the available stacks
try { Link(compiled); }
catch (...) { return false; }
catch (...) { return {}; }

if (mPriorityStack)
VERBOSE_TEMPORAL(Logger::Purple, "Priority flow: ", mPriorityStack);

if (mTimeStack)
VERBOSE_TEMPORAL(Logger::Purple, "Time flow: ", mTimeStack);

if (mFrequencyStack)
VERBOSE_TEMPORAL(Logger::Purple, "Frequency flow: ", mFrequencyStack);

return true;
// Execute the new scope and return any side effects
Many sideffects;
Update({}, sideffects);
return Abandon(sideffects);
}

/// Compiles a scope into an intermediate form, used by the flow
Expand Down
13 changes: 8 additions & 5 deletions source/Temporal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ namespace Langulus::Flow
LANGULUS_API(FLOW) void Link(const Many&);
LANGULUS_API(FLOW) void LinkRelative(const Many&, const Verb&);

LANGULUS_API(FLOW) Many PushInner(Many);

public:
LANGULUS_API(FLOW) Temporal();
LANGULUS_API(FLOW) Temporal(Temporal*);
Expand All @@ -98,15 +100,16 @@ namespace Langulus::Flow
Time GetUptime() const;

LANGULUS_API(FLOW) void Merge(const Temporal&);
LANGULUS_API(FLOW) bool Push(Many);

template<CT::Data T1, CT::Data...TN> requires (sizeof...(TN) >= 1)
bool Push(T1&& t1, TN&&...tn) {
return Push(Forward<T1>(t1)) and (Push(Forward<TN>(tn)) and ...);
template<CT::Data...TN> requires (sizeof...(TN) >= 1)
Many Push(TN&&...tn) {
Many result;
(result.SmartPush(IndexBack, PushInner(Forward<TN>(tn))), ...);
return result;
}

LANGULUS_API(FLOW) void Reset();
LANGULUS_API(FLOW) bool Update(Time = {});
LANGULUS_API(FLOW) bool Update(Time, Many&);
LANGULUS_API(FLOW) void Dump() const;

protected:
Expand Down
50 changes: 27 additions & 23 deletions source/Verb.inl
Original file line number Diff line number Diff line change
Expand Up @@ -571,32 +571,36 @@ namespace Langulus::Flow
}
else {
// Search for the ability via RTTI
const DMeta fromMeta = context.GetType();
DMeta toMeta;

if constexpr (CT::DerivedFrom<V, Verbs::Interpret>
and requires { typename V::Type; }) {
// Scan for a reflected converter as statically as possible
toMeta = MetaDataOf<typename V::Type>();
}
else if (verb.template IsVerb<Verbs::Interpret>()) {
// Scan for a reflected converter by scanning argument
toMeta = verb.template As<DMeta>();
}

const auto foundConverter = fromMeta->GetConverter(toMeta);
if (foundConverter) {
// Converter was found, prioritize it
// No escape from this scope
auto result = Many::FromMeta(toMeta);
result.template Reserve<true>(1);
foundConverter(context.GetRaw(), result.GetRaw());
verb << Abandon(result);
return verb.IsDone();
const DMeta meta = context.GetType();

if (CT::DerivedFrom<V, Verbs::Interpret>
or verb.template IsVerb<Verbs::Interpret>()) {
// Handle conversion a bit separately
DMeta toMeta;
if constexpr (CT::DerivedFrom<V, Verbs::Interpret>
and requires { typename V::Type; }) {
// Scan for a reflected converter statically
toMeta = MetaDataOf<typename V::Type>();
}
else {
// Scan for a reflected converter by scanning argument
toMeta = verb.template As<DMeta>();
}

const auto foundConverter = meta->GetConverter(toMeta);
if (foundConverter) {
// Converter was found, prioritize it
// No escape from this scope
auto result = Many::FromMeta(toMeta);
result.template Reserve<true>(1);
foundConverter(context.GetRaw(), result.GetRaw());
verb << Abandon(result);
return verb.IsDone();
}
}

// Scan for any other runtime ability
const auto foundAbility = fromMeta->template
const auto foundAbility = meta->template
GetAbility<CT::Mutable<T>>(verb.GetVerb(), verb.GetType());
if (not foundAbility)
return false;
Expand Down
2 changes: 1 addition & 1 deletion source/inner/Missing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "../verbs/Do.inl"
#include "../verbs/Interpret.inl"

#if 1
#if 0
#define VERBOSE_MISSING_POINT(...) Logger::Verbose(__VA_ARGS__)
#define VERBOSE_MISSING_POINT_TAB(...) const auto tabs = Logger::VerboseTab(__VA_ARGS__)
#define VERBOSE_FUTURE(...) Logger::Verbose(__VA_ARGS__)
Expand Down
61 changes: 29 additions & 32 deletions source/verbs/Do.inl
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ namespace Langulus::Flow
}*/

/// Invoke a single verb on a single context
/// @attention assumes that if T is deep, then it contains exactly one
/// element
/// @tparam DISPATCH - whether or not to use context's dispatcher, if
/// any is statically available or reflected
/// @tparam DEFAULT - whether or not to attempt default verb execution
Expand All @@ -154,43 +152,39 @@ namespace Langulus::Flow
// Keep in mind, that once you declare a custom Do for your
// type, you no longer rely on reflected bases' verbs or
// default verbs. You must invoke those by yourself in your
// dispatcher - the custom dispatcher provides full control
// dispatcher - the custom dispatcher provides full control!
context.Do(verb);
}
else {
// Execute verb inside the context directly
if constexpr (FALLBACK)
if constexpr (FALLBACK) {
// Execute the default verb
Verb::GenericExecuteDefault(context, verb);
else {
// Context might have a dispatcher still
if constexpr (CT::Deep<T> and DISPATCH) {
}
else if constexpr (DISPATCH) {
// Context might have a dispatcher
// If that is the case, then it is the context's
// responsibility to dispatch the verb!
if constexpr (CT::Deep<T>) {
auto meta = context.GetType();
if constexpr (CT::Constant<T>) {
if (meta->mDispatcherConstant)
meta->mDispatcherConstant(context.GetRaw(), verb);
else
Verb::GenericExecuteIn(context, verb);
}
else if (meta->mDispatcherConstant)
meta->mDispatcherConstant(context.GetRaw(), verb);
else if (meta->mDispatcherMutable)
meta->mDispatcherMutable(context.GetRaw(), verb);

if (verb.IsDone())
return verb.GetSuccesses();
else
Verb::GenericExecuteIn(context, verb);
}

// If reached, try executing in the proper reflected verbs
Verb::GenericExecuteIn(context, verb);
else Verb::GenericExecuteIn(context, verb);
}
else Verb::GenericExecuteIn(context, verb);

// If that fails, attempt in all reflected bases
/*if constexpr (requires { typename T::CTTI_Bases; }) {
if (not verb.IsDone()) {
// Context has no abilities, or they failed, so try
// with all bases' abilities
ExecuteInBases<DISPATCH, false, FALLBACK>(
context, verb, typename T::CTTI_Bases {});
}
}*/
if (verb.IsDone())
return verb.GetSuccesses();

// If that fails, attempt executing the default verb
if constexpr (DEFAULT and not FALLBACK) {
Expand Down Expand Up @@ -234,7 +228,7 @@ namespace Langulus::Flow
// Context is empty, but has relevant states, so directly
// forward it as context. Alternatively, the verb is not a
// multicast verb, and we're operating on context as one
verb.SetSource(context);
//verb.SetSource(context);
Execute<DISPATCH, DEFAULT, true>(context, verb);
return verb.GetSuccesses();
}
Expand All @@ -245,17 +239,20 @@ namespace Langulus::Flow

// Iterate elements in the current context
for (Count i = 0; i < context.GetCount(); ++i) {
verb.SetSource(context.GetElement(i));
//verb.SetSource(context.GetElement(i));
Many ith = context.GetElement(i);
if constexpr (RESOLVE)
ith = ith.GetResolved();
else
ith = ith.GetDense();

if constexpr (RESOLVE) {
Many resolved = verb.GetSource().GetResolved();
Execute<DISPATCH, DEFAULT, false>(resolved, verb);
}
else {
Many resolved = verb.GetSource().GetDense();
Execute<DISPATCH, DEFAULT, false>(resolved, verb);
if (not verb.GetSource()) {
// Make sure we save the source where execution happens
verb.SetSource(ith);
}

Execute<DISPATCH, DEFAULT, false>(ith, verb);

/*if (verb.IsShortCircuited()) {
// Short-circuit if enabled for verb
if (verb.IsDone() == context.IsOr()) {
Expand Down

0 comments on commit e489b1b

Please sign in to comment.