Skip to content

Commit

Permalink
Merge pull request #35 from tmadden/moving
Browse files Browse the repository at this point in the history
Add signal movement capabilities.
  • Loading branch information
tmadden committed Jul 20, 2020
2 parents 7834bce + 1442f06 commit e7b74cb
Show file tree
Hide file tree
Showing 40 changed files with 1,152 additions and 856 deletions.
13 changes: 0 additions & 13 deletions compilation_tests/read_write_intersection.cpp

This file was deleted.

13 changes: 0 additions & 13 deletions compilation_tests/write_read_intersection.cpp

This file was deleted.

2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class AliaConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
requires = ("Catch/1.12.1@bincrafters/stable", )
requires = ("Catch2/2.12.4@catchorg/stable", )
generators = "cmake"
default_options = "*:shared=False"

Expand Down
17 changes: 10 additions & 7 deletions docs/basic-signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,17 @@ signal that changes over time, but for the purpose of actually understanding
what's going on in your code, it's also helpful to be aware that there's no
actual persistent C++ object associated with that signal.
Directionality
--------------
Capabilities
------------
In C++, when you want to pass a `std::string` parameter into a function, you might do so using `std::string`, `std::string&`, `std::string const&` or even `std::string&&` depending on the intended usage. Each, in effect, conveys a different set of capabilities to the function receiving the parameter: the ability to write back to the string, the ability to move it efficiently somewhere else, the ability to refer to it by reference, etc. In alia, a signal's type carries a similar set of information as a 'capabilities' type tag.
The documentation below will describe signals as either 'read-only' or 'duplex'.
Just like raw C++ values can be either const or non-const, signals have a
*directionality* component to their type that indicates how they allow data to
flow. While read-only signals only allow you to read the value that they carry,
*duplex* signals *also* allow you to *write* a value back along the signal.
Capabilities will be discussed more in depth later on. For now, it's sufficient
to understand that not all signals have the same capabilities with respect to
reading and writing. In particular, the documentation below will describe
signals as either 'read-only' or 'duplex'. While read-only signals only allow
you to read the value that they carry, *duplex* signals *also* allow you to
*write* a value back to the signal.
Basic Constructors
------------------
Expand Down
14 changes: 6 additions & 8 deletions docs/consuming-signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ a typedef for the type of value that the signal carries

<dd>

<dt>direction_tag</dt><dd>
<dt>capabilities</dt><dd>

a type tag representing the directionality of the signal - It will always be one
of the following:

- `read_only_signal`
- `write_only_signal` (uncommon)
- `duplex_signal`
a type tag representing the capabilities of the signal - It's common to simply
use `read_only_signal` or `duplex_signal` here. For a full explanation of
capabilities, see [the
code](https://github.com/tmadden/alia/blob/master/src/alia/signals/core.hpp).

<dd>

Expand Down Expand Up @@ -74,7 +72,7 @@ Is the signal currently ready to write?

</dd>

<dt>void<br>write(Value const& value) const</dt><dd>
<dt>void<br>write(Value value) const</dt><dd>

Write the signal's value.

Expand Down
28 changes: 16 additions & 12 deletions docs/custom-signals.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,61 @@ interface](consuming-signals.md#the-signal-interface). The signature of `signal`
is as follows:

```cpp
template<class Derived, class Value, class Direction>
template<class Derived, class Value, class Capabilities>
struct signal;
```
`Derived` is the signal type that you're implementing.
`Value` is the type of value carried by the signal.
`Direction` is a tag type indicating the directionality of the signal. It should
be one of the following: `read_only_signal`, `write_only_signal`,
`duplex_signal`.
`Capabilities` is a tag type indicating the read/write capabilities of the
signal. It's common to simply use `read_only_signal` or `duplex_signal` here.
For a full explanation of capabilities, see [the
code](https://github.com/tmadden/alia/blob/master/src/alia/signals/core.hpp).
For signals with small value types, it's common for the value ID to simply be a
copy of the signal value. These are called 'regular' signals and can be
implemented by deriving from `regular_signal` instead. It has the same signature
as `signal` but provides the implementation of `value_id` for you.
For illustration, here's the actual implementation of the signal you create when
calling `direct()` on a non-const reference. It's a regular, duplex signal:
calling `direct()` on a non-const reference. It's a regular, duplex signal whose
values are copyable:
```cpp
template<class Value>
struct direct_signal
: regular_signal<direct_signal<Value>, Value, duplex_signal>
: regular_signal<direct_signal<Value>, Value, copyable_duplex_signal>
{
explicit direct_signal(Value* v) : v_(v)
{
}
bool
has_value() const
{
return true;
}
Value const&
read() const
{
return *v_;
}
Value
movable_value() const
{
Value movable = std::move(*v_);
return movable;
}
bool
ready_to_write() const
{
return true;
}
void
write(Value const& value) const
write(Value value) const
{
*v_ = value;
*v_ = std::move(value);
}
private:
Expand Down
2 changes: 1 addition & 1 deletion docs/signal-adaptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ true (in a boolean context), the mask evaluates to a signal equivalent to
`signal`. Otherwise, it evaluates to one with equivalent reading behavior but
with writing disabled.

Note that in either case, the masked version has the same directionality as
Note that in either case, the masked version has the same capabilities as
`signal`.

</dd>
Expand Down
1 change: 1 addition & 0 deletions scripts/set-up-conan.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
@echo off
echo "Setting up Conan..."
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan || exit /b
conan remote add catchorg https://api.bintray.com/conan/catchorg/Catch2
1 change: 1 addition & 0 deletions scripts/set-up-conan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
echo "Setting up Conan..."
set -x -e
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
conan remote add catchorg https://api.bintray.com/conan/catchorg/Catch2
2 changes: 1 addition & 1 deletion single_header_tests/runner.cpp
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#define CATCH_CONFIG_MAIN
#include <catch.hpp>
#include <catch2/catch.hpp>
39 changes: 21 additions & 18 deletions src/alia/flow/actions.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef ALIA_FLOW_ACTIONS_HPP
#define ALIA_FLOW_ACTIONS_HPP

#include <alia/signals/adaptors.hpp>
#include <alia/signals/basic.hpp>
#include <alia/signals/core.hpp>

Expand Down Expand Up @@ -63,7 +64,7 @@ void
perform_action(action_interface<Args...> const& action, Args... args)
{
if (action.is_ready())
action.perform([]() {}, args...);
action.perform([]() {}, std::move(args)...);
}

// action_ref is a reference to an action that implements the action interface
Expand All @@ -90,7 +91,7 @@ struct action_ref : action_interface<Args...>
void
perform(function_view<void()> const& intermediary, Args... args) const
{
action_->perform(intermediary, args...);
action_->perform(intermediary, std::move(args)...);
}

private:
Expand Down Expand Up @@ -159,8 +160,8 @@ template<class Action, class Signal, class BoundArg, class... Args>
struct bound_action<Action, Signal, action_interface<BoundArg, Args...>>
: action_interface<Args...>
{
bound_action(Action const& action, Signal const& signal)
: action_(action), signal_(signal)
bound_action(Action action, Signal signal)
: action_(std::move(action)), signal_(std::move(signal))
{
}

Expand All @@ -173,7 +174,8 @@ struct bound_action<Action, Signal, action_interface<BoundArg, Args...>>
void
perform(function_view<void()> const& intermediary, Args... args) const
{
action_.perform(intermediary, signal_.read(), args...);
action_.perform(
intermediary, forward_signal(signal_), std::move(args)...);
}

private:
Expand All @@ -187,10 +189,10 @@ template<
is_action_type<Action>::value && is_readable_signal_type<Signal>::value,
int> = 0>
auto
operator<<(Action const& action, Signal const& signal)
operator<<(Action action, Signal signal)
{
return bound_action<Action, Signal, typename Action::action_interface>(
action, signal);
std::move(action), std::move(signal));
}
template<
class Action,
Expand All @@ -199,9 +201,9 @@ template<
is_action_type<Action>::value && !is_signal_type<Value>::value,
int> = 0>
auto
operator<<(Action const& action, Value const& v)
operator<<(Action action, Value v)
{
return action << value(v);
return std::move(action) << value(std::move(v));
}

// operator <<=
Expand All @@ -214,7 +216,8 @@ operator<<(Action const& action, Value const& v)
template<class Sink, class Source>
struct copy_action : action_interface<>
{
copy_action(Sink sink, Source source) : sink_(sink), source_(source)
copy_action(Sink sink, Source source)
: sink_(std::move(sink)), source_(std::move(source))
{
}

Expand All @@ -227,9 +230,9 @@ struct copy_action : action_interface<>
void
perform(function_view<void()> const& intermediary) const
{
auto value = source_.read();
typename Source::value_type source_value = forward_signal(source_);
intermediary();
sink_.write(value);
sink_.write(std::move(source_value));
}

private:
Expand All @@ -247,7 +250,7 @@ template<
auto
operator<<=(Sink sink, Source source)
{
return copy_action<Sink, Source>(sink, source);
return copy_action<Sink, Source>(std::move(sink), std::move(source));
}

template<
Expand Down Expand Up @@ -281,7 +284,7 @@ toggle(Flag flag)
template<class Container, class Item>
struct push_back_action : action_interface<Item>
{
push_back_action(Container container) : container_(container)
push_back_action(Container container) : container_(std::move(container))
{
}

Expand All @@ -294,10 +297,10 @@ struct push_back_action : action_interface<Item>
void
perform(function_view<void()> const& intermediary, Item item) const
{
auto new_container = container_.read();
new_container.push_back(item);
auto new_container = forward_signal(alia::move(container_));
new_container.push_back(std::move(item));
intermediary();
container_.write(new_container);
container_.write(std::move(new_container));
}

private:
Expand All @@ -310,7 +313,7 @@ push_back(Container container)
{
return push_back_action<
Container,
typename Container::value_type::value_type>(container);
typename Container::value_type::value_type>(std::move(container));
}

// lambda_action(is_ready, perform) creates an action whose behavior is
Expand Down
24 changes: 12 additions & 12 deletions src/alia/flow/data_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,31 +166,31 @@ delete_named_block_ref_list(named_block_ref_node* head)
static void
clear_data_node_caches(data_node* node)
{
if (node)
{
clear_data_node_caches(node->next);
node->clear_cache();
}
if (node)
{
clear_data_node_caches(node->next);
node->clear_cache();
}
}

// Same with named_block_ref_nodes.
static void
deactivate_ref_nodes(named_block_ref_node* node)
{
if (node)
{
deactivate_ref_nodes(node->next);
deactivate(*node);
}
if (node)
{
deactivate_ref_nodes(node->next);
deactivate(*node);
}
}

void
data_block::clear_cache()
{
if (!this->cache_clear)
{
clear_data_node_caches(this->nodes);
deactivate_ref_nodes(this->named_blocks);
clear_data_node_caches(this->nodes);
deactivate_ref_nodes(this->named_blocks);
this->cache_clear = true;
}
}
Expand Down

0 comments on commit e7b74cb

Please sign in to comment.