Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement juyter.widget.control protocol #254

Merged
merged 9 commits into from
Feb 10, 2023
7 changes: 3 additions & 4 deletions include/xwidgets/xbinary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ namespace xw
{
using xjson_path_type = std::vector<std::string>;

XWIDGETS_API void extract_buffer_paths(
const std::vector<xjson_path_type>& to_check,
XWIDGETS_API void reorder_buffer_paths(
const std::vector<xjson_path_type>& buffer_paths,
const nl::json& patch,
const xeus::buffer_sequence& buffers,
nl::json& buffer_paths
std::vector<nl::json>& out
);

XWIDGETS_API void insert_buffer_paths(nl::json& patch, const nl::json& buffer_paths);
Expand Down
4 changes: 2 additions & 2 deletions include/xwidgets/xcommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ namespace xw

xeus::xguid id() const noexcept;
void display() const;
std::vector<xjson_path_type>& buffer_paths();
const std::vector<xjson_path_type>& buffer_paths() const;

protected:

Expand All @@ -74,8 +76,6 @@ namespace xw
const xeus::xcomm& comm() const;
const xeus::xmessage*& hold();
const xeus::xmessage* const& hold() const;
std::vector<xjson_path_type>& buffer_paths();
const std::vector<xjson_path_type>& buffer_paths() const;

void open(nl::json&& patch, xeus::buffer_sequence&& buffers);
void close();
Expand Down
7 changes: 6 additions & 1 deletion include/xwidgets/xcontroller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ namespace xw
inline xcontroller<D>::xcontroller()
: base_type()
{
register_control_types();
// Making a dummy static variable to only call the registration once.
static const auto initialized = []()
{
register_control_types();
return true;
}();
set_defaults();
}

Expand Down
83 changes: 59 additions & 24 deletions include/xwidgets/xholder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
#include <string>
#include <utility>

#include "nlohmann/json.hpp"
#include "xeus/xguid.hpp"
#include "xtl/xany.hpp"
#include "xtl/xclosure.hpp"
#include <nlohmann/json.hpp>
#include <xeus/xguid.hpp>
#include <xeus/xmessage.hpp>
#include <xtl/xany.hpp>
#include <xtl/xclosure.hpp>

#include "xbinary.hpp"
#include "xwidgets_config.hpp"

namespace nl = nlohmann;
Expand Down Expand Up @@ -68,6 +71,8 @@ namespace xw

void display() const;
xeus::xguid id() const;
void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const;
const std::vector<xjson_path_type>& buffer_paths() const;

xtl::any value() &;
const xtl::any value() const&;
Expand Down Expand Up @@ -131,6 +136,8 @@ namespace xw

virtual void display() const = 0;
virtual xeus::xguid id() const = 0;
virtual void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const = 0;
virtual const std::vector<xjson_path_type>& buffer_paths() const = 0;

virtual xtl::any value() & = 0;
virtual const xtl::any value() const& = 0;
Expand Down Expand Up @@ -162,31 +169,39 @@ namespace xw
{
}

virtual ~xholder_owning()
{
}
~xholder_owning() override = default;

virtual base_type* clone() const override
base_type* clone() const override
{
return new xholder_owning(*this);
}

virtual void display() const override
void display() const override
{
m_value.display();
}

virtual xeus::xguid id() const override
xeus::xguid id() const override
{
return m_value.id();
}

virtual xtl::any value() & override
void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const override
{
return m_value.serialize_state(state, buffers);
}

const std::vector<xjson_path_type>& buffer_paths() const override
{
return m_value.buffer_paths();
}

xtl::any value() & override
{
return xtl::closure(m_value);
}

virtual const xtl::any value() const& override
const xtl::any value() const& override
{
return xtl::closure(m_value);
}
Expand Down Expand Up @@ -214,32 +229,42 @@ namespace xw
{
}

virtual ~xholder_weak()
~xholder_weak() override
{
p_value = nullptr;
}

virtual base_type* clone() const override
base_type* clone() const override
{
return new xholder_weak(*this);
}

virtual void display() const override
void display() const override
{
p_value->display();
}

virtual xeus::xguid id() const override
xeus::xguid id() const override
{
return p_value->id();
}

virtual xtl::any value() & override
void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const override
{
return p_value->serialize_state(state, buffers);
}

const std::vector<xjson_path_type>& buffer_paths() const override
{
return p_value->buffer_paths();
}

xtl::any value() & override
{
return xtl::closure(*p_value);
}

virtual const xtl::any value() const& override
const xtl::any value() const& override
{
return xtl::closure(*p_value);
}
Expand Down Expand Up @@ -274,29 +299,39 @@ namespace xw
{
}

virtual ~xholder_shared() = default;
~xholder_shared() override = default;

virtual base_type* clone() const override
base_type* clone() const override
{
return new xholder_shared(*this);
}

virtual void display() const override
void display() const override
{
p_value->display();
}

virtual xeus::xguid id() const override
xeus::xguid id() const override
{
return p_value->id();
}

virtual xtl::any value() & override
void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const override
{
return p_value->serialize_state(state, buffers);
}

const std::vector<xjson_path_type>& buffer_paths() const override
{
return p_value->buffer_paths();
}

xtl::any value() & override
{
return xtl::closure(*p_value);
}

virtual const xtl::any value() const& override
const xtl::any value() const& override
{
return xtl::closure(*p_value);
}
Expand Down
9 changes: 8 additions & 1 deletion include/xwidgets/xregistry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ namespace xw

using holder_type = xholder;
using storage_type = std::unordered_map<xeus::xguid, holder_type>;
using mapped_type = typename storage_type::mapped_type;
using const_iterator = typename storage_type::const_iterator;

XWIDGETS_API const_iterator begin() const;
XWIDGETS_API const_iterator cbegin() const;
XWIDGETS_API const_iterator end() const;
XWIDGETS_API const_iterator cend() const;

template <class D>
void register_weak(xtransport<D>* ptr);
Expand All @@ -39,7 +46,7 @@ namespace xw

XWIDGETS_API void unregister(xeus::xguid id);

XWIDGETS_API typename storage_type::mapped_type& find(xeus::xguid id);
XWIDGETS_API mapped_type& find(xeus::xguid id);

private:

Expand Down
27 changes: 19 additions & 8 deletions src/xbinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,34 @@ namespace xw
}
}

void extract_buffer_paths(
const std::vector<xjson_path_type>& to_check,
void reorder_buffer_paths(
const std::vector<xjson_path_type>& buffer_paths,
const nl::json& patch,
const xeus::buffer_sequence& buffers,
nl::json& buffer_paths
std::vector<nl::json>& out
)
{
buffer_paths = nl::json(buffers.size(), nullptr);
for (const auto& path : to_check)
auto ensure_out_size = [&out](std::size_t size)
{
if (out.size() < size)
{
out.resize(size, nullptr);
}
};

ensure_out_size(buffer_paths.size());
for (const auto& path : buffer_paths)
{
const nl::json* item = detail::get_buffers(patch, path);
if (item != nullptr && item->is_string())
{
const std::string leaf = item->get<std::string>();
const auto& leaf = item->get<std::string>();
if (is_buffer_reference(leaf))
{
buffer_paths[buffer_index(leaf)] = path;
auto const idx = buffer_index(leaf);
// Idx may be greater than to_check.size() when the buffers are used with
// multiple states
ensure_out_size(idx + 1);
out[idx] = path;
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/xcommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ namespace xw
void xcommon::send_patch(nl::json&& patch, xeus::buffer_sequence&& buffers, const char* method) const
{
// extract buffer paths
auto paths = nl::json::array();
extract_buffer_paths(buffer_paths(), patch, buffers, paths);
std::vector<nl::json> paths{};
reorder_buffer_paths(buffer_paths(), patch, paths);

// metadata
nl::json metadata;
Expand All @@ -174,8 +174,8 @@ namespace xw
void xcommon::open(nl::json&& patch, xeus::buffer_sequence&& buffers)
{
// extract buffer paths
auto paths = nl::json::array();
extract_buffer_paths(buffer_paths(), patch, buffers, paths);
std::vector<nl::json> paths{};
reorder_buffer_paths(buffer_paths(), patch, paths);

// metadata
nl::json metadata;
Expand Down
12 changes: 12 additions & 0 deletions src/xholder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ namespace xw
return p_holder->id();
}

void xholder::serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const
{
check_holder();
return p_holder->serialize_state(state, buffers);
}

const std::vector<xjson_path_type>& xholder::buffer_paths() const
{
check_holder();
return p_holder->buffer_paths();
}

xtl::any xholder::value() &
{
check_holder();
Expand Down
34 changes: 20 additions & 14 deletions src/xholder_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,41 @@ namespace xw
{
}

virtual ~xholder_id() = default;
~xholder_id() override = default;

virtual base_type* clone() const override
base_type* clone() const override
{
return new xholder_id(*this);
}

virtual void display() const override
void display() const override
{
auto& holder = get_transport_registry().find(m_id);
holder.display();
return get_transport_registry().find(m_id).display();
}

virtual xeus::xguid id() const override
xeus::xguid id() const override
{
auto& holder = get_transport_registry().find(m_id);
return holder.id();
return get_transport_registry().find(m_id).id();
}

virtual xtl::any value() & override
void serialize_state(nl::json& state, xeus::buffer_sequence& buffers) const override
{
auto& holder = get_transport_registry().find(m_id);
return holder.value();
return get_transport_registry().find(m_id).serialize_state(state, buffers);
}

virtual const xtl::any value() const& override
const std::vector<xjson_path_type>& buffer_paths() const override
{
const auto& holder = get_transport_registry().find(m_id);
return holder.value();
return get_transport_registry().find(m_id).buffer_paths();
}

xtl::any value() & override
{
return get_transport_registry().find(m_id).value();
}

const xtl::any value() const& override
{
return get_transport_registry().find(m_id).value();
}

private:
Expand Down
Loading