Skip to content
31 changes: 31 additions & 0 deletions core/src/action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,34 @@ bool km::core::state::set_actions(

return true;
}
using namespace km::core;

namespace {

km_core_usv * duplicate_km_core_usv(const km_core_usv *src) {
if (!src) {
return nullptr;
}
size_t len = 0;
while (src[len]) {
++len;
}
km_core_usv *result = new km_core_usv[len + 1];
std::copy(src, src + len + 1, result);
return result;
}

} // namespace

km_core_actions km::core::clone_actions_object(km_core_actions const &src) {
km_core_actions result;
memset(&result, 0, sizeof(result));
result.code_points_to_delete = src.code_points_to_delete;
result.do_alert = src.do_alert;
result.emit_keystroke = src.emit_keystroke;
result.new_caps_lock_state = src.new_caps_lock_state;
result.deleted_context = duplicate_km_core_usv(src.deleted_context);
result.output = duplicate_km_core_usv(src.output);
result.persist_options = clone_options(src.persist_options);
return result;
}
4 changes: 4 additions & 0 deletions core/src/action.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ namespace core
unsigned int code_points_to_delete
);

km_core_actions clone_actions_object(
km_core_actions const &src
);

} // namespace core
} // namespace km
4 changes: 3 additions & 1 deletion core/src/km_core_processevent_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ km_core_event(
return KM_CORE_STATUS_INVALID_ARGUMENT;
}

return state->processor().external_event(state, event, data);
km_core_status status = state->processor().external_event(state, event, data);
state->apply_actions_and_merge_app_context();
return status;
}

km_core_status
Expand Down
11 changes: 10 additions & 1 deletion core/src/mock/mock_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,17 @@ namespace km {
{
assert(state);
assert(action_item);
if ((!state) || (!action_item))
if ((!state) || (!action_item)){
return false;
}
// For this mock processor we only support queuing PERSIST_OPT action items.
if (action_item->type == KM_CORE_IT_PERSIST_OPT && action_item->option) {
state->actions().push_persist(update_option(static_cast<km_core_option_scope>(action_item->option->scope), action_item->option->key, action_item->option->value));
return true;
}
else {
return false;
}
return false;
}

Expand Down
15 changes: 15 additions & 0 deletions core/src/option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,18 @@ json & km::core::operator << (json &j, abstract_processor const &)

return j;
}

km_core_option_item *
km::core::clone_options(km_core_option_item const *src) {
if (!src) {
return nullptr;
}
size_t count = km_core_options_list_size(src);
km_core_option_item *result = new km_core_option_item[count + 1];
for (size_t i = 0; i < count; ++i) {
km::core::option opt(static_cast<km_core_option_scope>(src[i].scope), src[i].key, src[i].value);
result[i] = opt.release();
}
result[count] = KM_CORE_OPTIONS_END;
return result;
}
2 changes: 1 addition & 1 deletion core/src/option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ namespace core
return key == nullptr;
}


km_core_option_item * clone_options(km_core_option_item const *src);

} // namespace core
} // namespace km
35 changes: 35 additions & 0 deletions core/src/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ void actions::push_capslock(bool turnOn) {
emplace_back(std::move(ai));
}

actions::actions(actions const &other)
: std::vector<action>(other)
, _option_items_stack(other._option_items_stack)
{
// Update all option pointers to point to the new stack
for (auto &item : *this) {
if (item.type == KM_CORE_IT_PERSIST_OPT && item.option) {
// Find the corresponding option in the new stack
// The pointers in the original point to positions in other._option_items_stack
// We need to find the equivalent position in our _option_items_stack
auto original_ptr = item.option;
auto original_base = reinterpret_cast<km_core_option_item const *>(other._option_items_stack.data());
auto offset = original_ptr - original_base;
if (offset >= 0 && static_cast<size_t>(offset) < _option_items_stack.size()) {
item.option = &_option_items_stack[offset];
}
}
}
}

state::state(km::core::abstract_processor & ap, km_core_option_item const *env)
: _processor(ap)
Expand All @@ -56,6 +75,9 @@ state::state(km::core::abstract_processor & ap, km_core_option_item const *env)
_imx_callback = nullptr;
_imx_object = nullptr;
memset(const_cast<km_core_actions*>(&_action_struct), 0, sizeof(km_core_actions));
// Ensure _action_struct is initialized to the default values
km_core_action_item no_actions = {KM_CORE_IT_END, {0,}, {0}};
action_item_list_to_actions_object(&no_actions, &this->_action_struct);
}

void state::imx_register_callback(
Expand All @@ -82,6 +104,19 @@ void state::imx_callback(uint32_t imx_id) {
_imx_callback(static_cast<km_core_state *>(this), imx_id, _imx_object);
}

state::state(state const &other)
: _ctxt(other._ctxt)
, _app_ctxt(other._app_ctxt)
, _processor(other._processor)
, _actions(other._actions)
, _action_struct(clone_actions_object(other._action_struct))
, _debug_items(other._debug_items)
, _imx_callback(other._imx_callback)
, _imx_object(other._imx_object)
, _backspace_handled_internally(other._backspace_handled_internally)
{
}

state::~state() {
km::core::actions_dispose(this->_action_struct);
}
Expand Down
6 changes: 5 additions & 1 deletion core/src/state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class actions : public std::vector<action>
public:
template<typename... Args>
actions(Args&&... args);
actions(actions const &other);
// If the operator is needed in the future, it shall be implemented
// in like the deep copy constructor. Blocking accidental use of it.
actions &operator=(actions const &) = delete;

void push_character(km_core_usv usv);
void push_marker(uint32_t marker);
Expand Down Expand Up @@ -135,7 +139,7 @@ class state
public:
state(core::abstract_processor & kb, km_core_option_item const *env);

state(state const &) = default;
state(state const &other);
state(state const &&) = delete;

~state();
Expand Down
Loading
Loading