/** * \brief Apply the update structure to the current configuration and execute * callbacks (create/update/delete) on channels/profiles * \note After update, the \p update structure is automatically freed. * \param[in,out] mgr Event manager * \param[in] update Update structure */ static void pevents_update_apply(pevents_t *mgr, struct pevents_update *update) { // Copy callbacks from old channels/profiles to new channels/profiles update->profiles.cbs = mgr->profiles.cbs; update->channels.cbs = mgr->channels.cbs; // Call "on_delete" callbacks on OLD profiles/channels group_on_delete(&mgr->profiles); group_on_delete(&mgr->channels); // Call "on_update" callbacks on successfully mapped profiles/channels group_on_update(&update->profiles, update->prfl_flags); group_on_update(&update->channels, update->chnl_flags); // Call "on_create" callbacks on NEW profiles/channels group_on_create(&update->profiles); group_on_create(&update->channels); // Delete old information about channels/profiles and apply the update group_deinit(&mgr->profiles); group_deinit(&mgr->channels); mgr->profiles = update->profiles; mgr->channels = update->channels; // Cleanup after the update bitset_clear(mgr->profiles.bitset); bitset_clear(mgr->channels.bitset); free(update->chnl_flags); free(update->prfl_flags); free(update); }
/** * \brief Delete an update structure * * Free internal auxiliary structures and then delete the structure. * \param[in,out] update Pointer to the structure */ static void pevents_update_delete(struct pevents_update *update) { group_deinit(&update->channels); group_deinit(&update->profiles); free(update->chnl_flags); free(update->prfl_flags); free(update); }
void pevents_destroy(pevents_t *mgr) { // Call on "on_delete" callbacks on all profiles and channels bitset_clear(mgr->profiles.bitset); bitset_clear(mgr->channels.bitset); group_on_delete(&mgr->profiles); group_on_delete(&mgr->channels); // Delete internal structures for profiles and channels group_deinit(&mgr->profiles); group_deinit(&mgr->channels); free(mgr); }
pevents_t * pevents_create(struct pevent_cb_set profiles, struct pevent_cb_set channels) { pevents_t *events = calloc(1, sizeof(*events)); if (!events) { MSG_ERROR(msg_module, "Unable to allocate memory (%s:%d)", __FILE__, __LINE__); return NULL; } /* Initialize an internal structures. Because we don't have information * about profiles/channels we should prepare empty structures. * However, pre-allocation for "0" items is not suitable, so we use "1". */ if (group_init(&events->profiles, 1)) { free(events); return NULL; } if (group_init(&events->channels, 1)) { group_deinit(&events->profiles); free(events); return NULL; } events->channels.cbs = channels; events->profiles.cbs = profiles; return events; }
/** * \brief Create a new update structure and parse a new profile tree * * Returned structure is prepared for mapping old channels/profiles to new * channels/profiles (those are store in this update structure). * \param[in] mgr Event manager * \param[in] tree_root Root profile of the new profile tree * \return On success returns a pointer to the structure. Otherwise (memory * allocation error) returns NULL. */ static struct pevents_update * pevents_update_create(pevents_t *mgr, void *tree_root) { struct pevents_update *update; update = (struct pevents_update *) calloc(1, sizeof(*update)); if (!update) { MSG_ERROR(msg_module, "Unable to allocate memory (%s:%d)", __FILE__, __LINE__); return NULL; } struct pevents_group *chnl_grp = &update->channels; struct pevents_group *prfl_grp = &update->profiles; /* Prepare hints (expected number of channels/profiles) * Helps to prevent expensive reallocations. */ size_t profile_hint = mgr->profiles.all_size + PEVENTS_HINT_OVERLAP; size_t channel_hint = mgr->channels.all_size + PEVENTS_HINT_OVERLAP; if (profile_hint < PEVENTS_HINT_PROFILE) { profile_hint = PEVENTS_HINT_PROFILE; } if (channel_hint < PEVENTS_HINT_CHANNELS) { channel_hint = PEVENTS_HINT_CHANNELS; } // Initialize groups for channels and profiles if (group_init(prfl_grp, profile_hint)) { free(update); return NULL; } if (group_init(chnl_grp, channel_hint)) { group_deinit(prfl_grp); free(update); return NULL; } // Parse the profile tree if (pevents_update_parse_tree(update, tree_root)) { pevents_update_delete(update); return NULL; } // Set user global variables for (size_t i = 0; i < chnl_grp->all_size; ++i) { struct pevents_item *item = group_item_at(chnl_grp, i); item->ctx.user.global = mgr->user_global; } for (size_t i = 0; i < prfl_grp->all_size; ++i) { struct pevents_item *item = group_item_at(prfl_grp, i); item->ctx.user.global = mgr->user_global; } // Success return update; }
void groupws_deinit(WGroupWS *ws) { extl_unref_table(ws->initial_outputs); screen_unnotify_if_workspace(ws); group_deinit(&(ws->grp)); }