| 378 | } |
| 379 | |
| 380 | void recompui::ContextId::process_updates() { |
| 381 | // Ensure a context is currently opened by this thread. |
| 382 | if (opened_context_id == ContextId::null()) { |
| 383 | context_error(*this, ContextErrorType::InternalError); |
| 384 | } |
| 385 | |
| 386 | // Check that the context that was specified is the same one that's currently open. |
| 387 | if (*this != opened_context_id) { |
| 388 | context_error(*this, ContextErrorType::InternalError); |
| 389 | } |
| 390 | |
| 391 | // Move the current update set into a local variable. This clears the update set |
| 392 | // and allows it to be used to queue updates from any element callbacks. |
| 393 | std::unordered_set<ResourceId> to_update = std::move(opened_context->to_update); |
| 394 | |
| 395 | Event update_event = Event::update_event(); |
| 396 | |
| 397 | for (auto cur_resource_id : to_update) { |
| 398 | resource_slotmap::key cur_key{ cur_resource_id.slot_id }; |
| 399 | |
| 400 | // Ignore any resources that aren't elements. |
| 401 | if (cur_key.get_tag() != static_cast<uint8_t>(SlotTag::Element)) { |
| 402 | // Assert to catch errors of queueing other resource types for update. |
| 403 | // This isn't an actual error, so there's no issue with continuing in release builds. |
| 404 | assert(false); |
| 405 | continue; |
| 406 | } |
| 407 | |
| 408 | // Get the resource being updaten from the context. |
| 409 | std::unique_ptr<Style>* cur_resource = opened_context->resources.get(cur_key); |
| 410 | |
| 411 | // Make sure the resource exists before dispatching the event. It may have been deleted |
| 412 | // after being queued for a update, so just continue to the next element if it doesn't exist. |
| 413 | if (cur_resource == nullptr) { |
| 414 | continue; |
| 415 | } |
| 416 | |
| 417 | static_cast<Element*>(cur_resource->get())->handle_event(update_event); |
| 418 | } |
| 419 | |
| 420 | std::vector<std::tuple<Element*, ResourceId, std::string>> to_set_text = std::move(opened_context->to_set_text); |
| 421 | |
| 422 | // Delete the Rml elements that are pending deletion. |
| 423 | for (auto cur_text_update : to_set_text) { |
| 424 | Element* element_ptr = std::get<0>(cur_text_update); |
| 425 | ResourceId resource = std::get<1>(cur_text_update); |
| 426 | std::string& text = std::get<2>(cur_text_update); |
| 427 | |
| 428 | // If the resource ID is valid, prefer that as we can quickly validate if the resource still exists. |
| 429 | if (resource != ResourceId::null()) { |
| 430 | resource_slotmap::key cur_key{ resource.slot_id }; |
| 431 | std::unique_ptr<Style>* cur_resource = opened_context->resources.get(cur_key); |
| 432 | |
| 433 | // Make sure the resource exists before setting its text, as it may have been deleted. |
| 434 | if (cur_resource == nullptr) { |
| 435 | continue; |
| 436 | } |
| 437 |
no test coverage detected