Skip to content

Commit

Permalink
Rework context interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadden committed Sep 30, 2020
1 parent 92ab13c commit e8b71b0
Show file tree
Hide file tree
Showing 19 changed files with 118 additions and 158 deletions.
54 changes: 3 additions & 51 deletions examples/asm-dom/demos/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ typedef extend_context_type_t<dom::context, username_tag> app_context;
void
internal_app_ui(app_context ctx)
{
dom::text(ctx, alia::printf(ctx, "Welcome, %s!", ctx.get<username_tag>()));
dom::text(ctx,
alia::printf(ctx, "Welcome, %s!", get_object<username_tag>(ctx)));
}

// Our top-level UI function takes the context that the asm-dom wrapper provides
Expand All @@ -32,7 +33,7 @@ main_app_ui(dom::context ctx)
readable<std::string> username = value("tmadden");

// Extend the app context to include the username.
app_context app_ctx = ctx.add<username_tag>(username);
app_context app_ctx = add_object<username_tag>(ctx, username);

// Pass that context along to the internal portions of the app UI...
internal_app_ui(app_ctx);
Expand All @@ -54,52 +55,3 @@ init_demo(std::string dom_id)
static demo the_demo("custom-context", init_demo);

} // namespace custom_context

namespace doubly_extended_context {

// clang-format off
/// [doubly-extended-context]
ALIA_DEFINE_TAGGED_TYPE(username_tag, readable<std::string>&)
ALIA_DEFINE_TAGGED_TYPE(api_key_tag, readable<std::string>&)

typedef extend_context_type_t<dom::context, username_tag, api_key_tag>
app_context;

void
internal_app_ui(app_context ctx)
{
dom::text(ctx, alia::printf(ctx, "Welcome, %s!", ctx.get<username_tag>()));
dom::text(ctx,
alia::printf(ctx,
"Your secret key is %s! Keep it safe!",
ctx.get<api_key_tag>()));
}

void
main_app_ui(dom::context ctx)
{
readable<std::string> username = value("tmadden");
readable<std::string> api_key = value("abc123");

app_context app_ctx =
ctx.add<username_tag>(username).add<api_key_tag>(api_key);

internal_app_ui(app_ctx);
}
/// [doubly-extended-context]
// clang-format on

void
init_demo(std::string dom_id)
{
static alia::system the_system;
static dom::system the_dom;

initialize(the_dom, the_system, dom_id, [](dom::context ctx) {
main_app_ui(ctx);
});
}

static demo the_demo("doubly-extended-context", init_demo);

} // namespace doubly_extended_context
6 changes: 3 additions & 3 deletions examples/asm-dom/dom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ install_element_callback(
char const* event_type)
{
auto external_id = externalize(&data.identity);
auto* system = &get<system_tag>(ctx);
auto* system = &get_object<system_tag>(ctx);
data.callback = [=](emscripten::val v) {
dom_event event(v);
dispatch_targeted_event(*system, event, external_id);
Expand Down Expand Up @@ -73,7 +73,7 @@ text_node_(dom::context ctx, readable<string> text)
data->node.object.create_as_text_node("");
if (is_refresh_event(ctx))
{
refresh_tree_node(get<tree_traversal_tag>(ctx), data->node);
refresh_tree_node(get_object<tree_traversal_tag>(ctx), data->node);
refresh_signal_shadow(
data->value_id,
text,
Expand Down Expand Up @@ -369,7 +369,7 @@ void
system::operator()(alia::context vanilla_ctx)
{
tree_traversal<element_object> traversal;
auto ctx = vanilla_ctx.add<tree_traversal_tag>(traversal);
auto ctx = add_object<tree_traversal_tag>(vanilla_ctx, traversal);

if (is_refresh_event(ctx))
{
Expand Down
6 changes: 3 additions & 3 deletions examples/asm-dom/dom.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ struct element_handle : noncopyable
if (initializing_)
node_->object.create_as_element(type);
if (is_refresh_event(ctx))
refresh_tree_node(get<tree_traversal_tag>(ctx), *node_);
refresh_tree_node(get_object<tree_traversal_tag>(ctx), *node_);
}

template<class Value>
Expand Down Expand Up @@ -238,7 +238,7 @@ struct scoped_element : noncopyable
if (initializing_)
node_->object.create_as_element(type);
if (is_refresh_event(ctx))
tree_scoping_.begin(get<tree_traversal_tag>(ctx), *node_);
tree_scoping_.begin(get_object<tree_traversal_tag>(ctx), *node_);
return *this;
}

Expand Down Expand Up @@ -386,7 +386,7 @@ cached_content(Context ctx, id_interface const& id, Function&& fn)
if (is_refresh_event(ctx))
{
cacher.begin(
get<tree_traversal_tag>(ctx),
get_object<tree_traversal_tag>(ctx),
data->caching,
id,
container.is_dirty());
Expand Down
18 changes: 9 additions & 9 deletions examples/qt/adaptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ set_next_node(qt_traversal& traversal, qt_layout_node* node)
void
add_layout_node(dataless_qt_context ctx, qt_layout_node* node)
{
qt_traversal& traversal = ctx.get<qt_traversal_tag>();
qt_traversal& traversal = get_object<qt_traversal_tag>(ctx);
set_next_node(traversal, node);
traversal.next_ptr = &node->next;
}
Expand All @@ -89,7 +89,7 @@ void
scoped_layout_container::begin(qt_context ctx, qt_layout_container* container)
{
on_refresh(ctx, [&](auto ctx) {
traversal_ = &ctx.get<qt_traversal_tag>();
traversal_ = &get_object<qt_traversal_tag>(ctx);
qt_traversal& traversal = *traversal_;

set_next_node(traversal, container);
Expand Down Expand Up @@ -141,11 +141,11 @@ do_label(qt_context ctx, readable<string> text)
auto& label = get_cached_data<qt_label>(ctx);

on_refresh(ctx, [&](auto ctx) {
auto& system = ctx.get<system_tag>();
auto& system = get_object<system_tag>(ctx);

if (!label.object)
{
auto& traversal = get<qt_traversal_tag>(ctx);
auto& traversal = get_object<qt_traversal_tag>(ctx);
auto* parent = traversal.active_parent;
label.object = new QLabel(parent);
if (parent->isVisible())
Expand Down Expand Up @@ -194,13 +194,13 @@ do_button(qt_context ctx, readable<string> text, action<> on_click)
auto& button = get_cached_data<qt_button>(ctx);

on_refresh(ctx, [&](auto ctx) {
auto& system = get<system_tag>(ctx);
auto& system = get_object<system_tag>(ctx);

refresh_component_identity(ctx, button.identity);

if (!button.object)
{
auto& traversal = get<qt_traversal_tag>(ctx);
auto& traversal = get_object<qt_traversal_tag>(ctx);
auto* parent = traversal.active_parent;
button.object = new QPushButton(parent);
if (parent->isVisible())
Expand Down Expand Up @@ -268,13 +268,13 @@ do_text_control(qt_context ctx, duplex<string> text)
auto& widget = get_cached_data<qt_text_control>(ctx);

on_refresh(ctx, [&](auto ctx) {
auto& system = get<system_tag>(ctx);
auto& system = get_object<system_tag>(ctx);

refresh_component_identity(ctx, widget.identity);

if (!widget.object)
{
auto& traversal = get<qt_traversal_tag>(ctx);
auto& traversal = get_object<qt_traversal_tag>(ctx);
auto* parent = traversal.active_parent;
widget.object = new QTextEdit(parent);
if (parent->isVisible())
Expand Down Expand Up @@ -362,7 +362,7 @@ void
qt_system::operator()(alia::context vanilla_ctx)
{
qt_traversal traversal;
qt_context ctx = vanilla_ctx.add<qt_traversal_tag>(traversal);
qt_context ctx = add_object<qt_traversal_tag>(vanilla_ctx, traversal);

on_refresh(ctx, [&](auto ctx) {
traversal.next_ptr = &this->root;
Expand Down
15 changes: 10 additions & 5 deletions src/alia/context/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,16 @@ make_context(
timing_subsystem& timing)
{
storage->content_id = &unit_id;
return make_context(detail::make_empty_structural_collection(storage))
.add<system_tag>(sys)
.add<event_traversal_tag>(event)
.add<timing_tag>(timing)
.add<data_traversal_tag>(data);
return add_object<data_traversal_tag>(
add_object<timing_tag>(
add_object<event_traversal_tag>(
add_object<system_tag>(
make_context(
detail::make_empty_structural_collection(storage)),
sys),
event),
timing),
data);
}

struct scoped_context_content_id_data
Expand Down
82 changes: 42 additions & 40 deletions src/alia/context/interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ ALIA_ADD_DIRECT_TAGGED_DATA_ACCESS(context_storage, event_traversal_tag, event)
ALIA_ADD_DIRECT_TAGGED_DATA_ACCESS(context_storage, data_traversal_tag, data)
ALIA_ADD_DIRECT_TAGGED_DATA_ACCESS(context_storage, timing_tag, timing)

// Context objects implement this interface if they provide state that might
// influence the component-level application code.
struct stateful_context_object
{
virtual id_interface const&
value_id()
= 0;
};

// the context interface wrapper
template<class Contents>
struct context_interface
Expand Down Expand Up @@ -78,41 +87,41 @@ struct context_interface

typedef Contents contents_type;

template<class Tag>
bool
has() const
{
return detail::has_tagged_data<Tag>(contents_);
}
Contents contents_;
};

template<class Tag, class Data>
auto
add(Data& data)
{
auto new_contents
= detail::add_tagged_data<Tag>(contents_, std::ref(data));
return context_interface<decltype(new_contents)>(
std::move(new_contents));
}
// manipulation of context objects...

template<class Tag>
auto
remove()
{
auto new_contents = detail::remove_tagged_data<Tag>(contents_);
return context_interface<decltype(new_contents)>(
std::move(new_contents));
}
template<class Tag, class Contents>
bool
has_object(context_interface<Contents> ctx)
{
return detail::has_tagged_data<Tag>(ctx.contents_);
}

template<class Tag>
decltype(auto)
get()
{
return detail::get_tagged_data<Tag>(contents_);
}
template<class Tag, class Contents, class Data>
auto
add_object(context_interface<Contents> ctx, Data& data)
{
auto new_contents
= detail::add_tagged_data<Tag>(ctx.contents_, std::ref(data));
return context_interface<decltype(new_contents)>(std::move(new_contents));
}

Contents contents_;
};
template<class Tag, class Contents>
auto
remove_object(context_interface<Contents> ctx)
{
auto new_contents = detail::remove_tagged_data<Tag>(ctx.contents_);
return context_interface<decltype(new_contents)>(std::move(new_contents));
}

template<class Tag, class Contents>
decltype(auto)
get_object(context_interface<Contents> ctx)
{
return detail::get_tagged_data<Tag>(ctx.contents_);
}

template<class Context, class... Tag>
struct extend_context_type
Expand Down Expand Up @@ -180,25 +189,18 @@ copy_context(Context ctx)
return Context(typename Context::contents_type(new_storage));
}

template<class Tag, class Contents>
decltype(auto)
get(context_interface<Contents> context)
{
return context.template get<Tag>();
}

template<class Context>
event_traversal&
get_event_traversal(Context ctx)
{
return ctx.template get<event_traversal_tag>();
return get_object<event_traversal_tag>(ctx);
}

template<class Context>
data_traversal&
get_data_traversal(Context ctx)
{
return ctx.template get<data_traversal_tag>();
return get_object<data_traversal_tag>(ctx);
}

inline id_interface const&
Expand Down
2 changes: 1 addition & 1 deletion src/alia/flow/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ template<class Context>
void
isolate_errors(Context ctx, function_view<void()> const& function)
{
isolate_errors(get<system_tag>(ctx), function);
isolate_errors(get_object<system_tag>(ctx), function);
}

void
Expand Down
2 changes: 1 addition & 1 deletion src/alia/flow/try_catch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ try_block::try_block(context ctx) : ctx_(ctx)
{
get_cached_data(ctx, &data_);
on_refresh(ctx, [&](auto ctx) {
auto refresh_counter = get<system_tag>(ctx).refresh_counter;
auto refresh_counter = get_object<system_tag>(ctx).refresh_counter;
if (data_->last_refresh != refresh_counter)
{
data_->exception = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/alia/signals/async.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ async(Context ctx, Launcher launcher, Args const&... args)
auto reporter = async_reporter<Result>{
data_ptr,
data.version,
&get<system_tag>(ctx),
&get_object<system_tag>(ctx),
get_active_component_container(ctx)};
launcher(ctx, reporter, read_signal(args)...);
data.status = async_status::LAUNCHED;
Expand Down
7 changes: 4 additions & 3 deletions src/alia/timing/ticks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ schedule_animation_refresh(dataless_context ctx)
{
// Invoke the virtual method on the external system interface.
// And also set a flag to indicate that a refresh is needed.
system& sys = ctx.get<system_tag>();
system& sys = get_object<system_tag>(ctx);
if (!sys.refresh_needed)
{
if (sys.external)
Expand All @@ -26,7 +26,7 @@ millisecond_count
get_raw_animation_tick_count(dataless_context ctx)
{
schedule_animation_refresh(ctx);
return ctx.get<timing_tag>().tick_counter;
return get_object<timing_tag>(ctx).tick_counter;
}

value_signal<millisecond_count>
Expand All @@ -38,7 +38,8 @@ get_animation_tick_count(dataless_context ctx)
millisecond_count
get_raw_animation_ticks_left(dataless_context ctx, millisecond_count end_time)
{
int ticks_remaining = int(end_time - ctx.get<timing_tag>().tick_counter);
int ticks_remaining
= int(end_time - get_object<timing_tag>(ctx).tick_counter);
if (ticks_remaining > 0)
{
if (is_refresh_event(ctx))
Expand Down

0 comments on commit e8b71b0

Please sign in to comment.