Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,28 +838,37 @@ void SendspinClient::process_json_message(SendspinConnection* conn, const char*
break;
}
case SendspinServerToClientMessageType::SERVER_STATE: {
ServerStateMessage state_msg;
if (process_server_state_message(root, &state_msg)) {
// Parse and hand off one section at a time, each in its own scope. Parsing the whole
// message into an aggregate would hold every section's storage (a metadata delta alone
// is 200 bytes) in this frame at once, and this runs on the network task, whose stack
// is small on ESP-IDF. Scoping the sections lets the compiler reuse the same slots, and
// a section is only parsed at all when its role is present.
#ifdef SENDSPIN_ENABLE_CONTROLLER
if (this->controller_ && state_msg.controller.has_value()) {
this->controller_->impl_->handle_server_state(
std::move(state_msg.controller.value()));
if (this->controller_ != nullptr) {
ServerStateControllerObject controller_state;
if (process_server_state_controller(root, &controller_state)) {
this->controller_->impl_->handle_server_state(std::move(controller_state));
}
}
#endif

#ifdef SENDSPIN_ENABLE_METADATA
if (this->metadata_ && state_msg.metadata.has_value()) {
this->metadata_->impl_->handle_server_state(
std::move(state_msg.metadata.value()));
if (this->metadata_ != nullptr) {
ServerMetadataStateDelta metadata_delta;
if (process_server_state_metadata(root, &metadata_delta)) {
this->metadata_->impl_->handle_server_state(std::move(metadata_delta));
}
}
#endif

#ifdef SENDSPIN_ENABLE_COLOR
if (this->color_ && state_msg.color.has_value()) {
this->color_->impl_->handle_server_state(state_msg.color.value());
if (this->color_ != nullptr) {
ServerColorStateDelta color_delta;
if (process_server_state_color(root, &color_delta)) {
this->color_->impl_->handle_server_state(color_delta);
}
#endif
}
#endif
break;
}
case SendspinServerToClientMessageType::SERVER_COMMAND: {
Expand Down
2 changes: 1 addition & 1 deletion src/color_role.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void ColorRole::Impl::build_hello_fields(ClientHelloMessage& msg) {
msg.supported_roles.push_back(SendspinRole::COLOR);
}

void ColorRole::Impl::handle_server_state(ServerColorStateDelta delta) const {
void ColorRole::Impl::handle_server_state(const ServerColorStateDelta& delta) const {
// Merge incoming wire delta into the accumulated delta in the inbox slot; see
// merge_color_state_delta for the field-overlay semantics.
this->event_state->slot.merge(merge_color_state_delta, delta);
Expand Down
5 changes: 4 additions & 1 deletion src/color_role_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ struct ColorRole::Impl {

void attach_inbox(Inbox& inbox);
void build_hello_fields(ClientHelloMessage& msg);
void handle_server_state(ServerColorStateDelta delta) const;
// Takes a const reference, unlike the metadata and controller overloads: a
// ServerColorStateDelta is trivially copyable (see merge_color_state_delta), so there is
// nothing for an rvalue reference to move out of.
void handle_server_state(const ServerColorStateDelta& delta) const;
// True if a slot delta needs folding in, or a delta already held from a prior tick (see
// held_delta) is still waiting out its server-clock deadline -- the deadline itself sets no
// inbox bit, so held_delta must be polled every tick until it fires.
Expand Down
2 changes: 1 addition & 1 deletion src/controller_role.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void ControllerRole::Impl::build_hello_fields(ClientHelloMessage& msg) {
msg.supported_roles.push_back(SendspinRole::CONTROLLER);
}

void ControllerRole::Impl::handle_server_state(ServerStateControllerObject state) const {
void ControllerRole::Impl::handle_server_state(ServerStateControllerObject&& state) const {
this->event_state->slot.write(std::move(state));
}

Expand Down
2 changes: 1 addition & 1 deletion src/controller_role_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct ControllerRole::Impl {

void attach_inbox(Inbox& inbox);
void build_hello_fields(ClientHelloMessage& msg);
void handle_server_state(ServerStateControllerObject state) const;
void handle_server_state(ServerStateControllerObject&& state) const;
// True if a controller-state delta is waiting in the inbox slot.
bool needs_drain(uint32_t pending_bits) const {
return (pending_bits & INBOX_TOPIC_CONTROLLER) != 0;
Expand Down
2 changes: 1 addition & 1 deletion src/metadata_role.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void MetadataRole::Impl::build_hello_fields(ClientHelloMessage& msg) {
msg.supported_roles.push_back(SendspinRole::METADATA);
}

void MetadataRole::Impl::handle_server_state(ServerMetadataStateDelta delta) const {
void MetadataRole::Impl::handle_server_state(ServerMetadataStateDelta&& delta) const {
// Merge incoming wire delta into the accumulated delta in the inbox slot; see
// merge_metadata_state_delta for the field-overlay semantics.
this->event_state->slot.merge(merge_metadata_state_delta, std::move(delta));
Expand Down
2 changes: 1 addition & 1 deletion src/metadata_role_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct MetadataRole::Impl {

void attach_inbox(Inbox& inbox);
void build_hello_fields(ClientHelloMessage& msg);
void handle_server_state(ServerMetadataStateDelta delta) const;
void handle_server_state(ServerMetadataStateDelta&& delta) const;
// True if a slot delta needs folding in, or a delta already held from a prior tick (see
// held_delta) is still waiting out its server-clock deadline -- the deadline itself sets no
// inbox bit, so held_delta must be polled every tick until it fires.
Expand Down
Loading
Loading