Actions can stack

This commit is contained in:
LAGonauta 2021-02-23 07:08:56 -03:00
parent 7fd918f32d
commit 40bf3d2fd4
4 changed files with 63 additions and 42 deletions

View file

@ -41,7 +41,7 @@ void winrt_windows_ui_notifications_toast_notification_set_Group(winrtWindowsUIN
gchar* winrt_windows_ui_notifications_toast_notification_get_Group(winrtWindowsUINotificationsToastNotification* self); gchar* winrt_windows_ui_notifications_toast_notification_get_Group(winrtWindowsUINotificationsToastNotification* self);
winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackActivated callback, void* context, void(*free)(void*)); winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackActivated callback, void* context, void(*free)(void*));
void winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token); void winrt_windows_ui_notifications_toast_notification_RemoveActivated(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token);
winrtEventToken* winrt_windows_ui_notifications_toast_notification_Failed(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackSimple callback, void* context, void(*free)(void*)); winrtEventToken* winrt_windows_ui_notifications_toast_notification_Failed(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackSimple callback, void* context, void(*free)(void*));
//winrtEventToken* winrt_windows_ui_notifications_toast_notification_Dismissed(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackDismissed callback, void* context, void(*free)(void*)); //winrtEventToken* winrt_windows_ui_notifications_toast_notification_Dismissed(winrtWindowsUINotificationsToastNotification* self, NotificationCallbackDismissed callback, void* context, void(*free)(void*));

View file

@ -22,22 +22,45 @@ public:
T callback; T callback;
void* context; void* context;
void(*free)(void*); void(*free)(void*);
winrtEventToken* token;
Callback(T callback, void* context, void(*free)(void*))
{
this->callback = callback;
this->free = free;
this->context = context;
}
~Callback()
{
Clear();
}
void Clear() void Clear()
{ {
if (this->callback && this->context && this->free)
{
this->free(this->context);
}
callback = nullptr; callback = nullptr;
context = nullptr; context = nullptr;
free = nullptr; free = nullptr;
g_clear_object(&token);
} }
// delete copy
Callback(const Callback&) = delete;
Callback& operator=(const Callback&) = delete;
// allow move
Callback(Callback&&) = default;
Callback& operator=(Callback&&) = default;
}; };
typedef struct typedef struct
{ {
Callback<NotificationCallbackActivated> activated; std::unordered_map<winrtEventToken*, Callback<NotificationCallbackActivated>> activated;
Callback<NotificationCallbackSimple> failed; std::unordered_map<winrtEventToken*, Callback<NotificationCallbackSimple>> failed;
// Notification_Callback_Dismissed callback; // Notification_Callback_Dismissed callback;
// void* context; // void* context;
@ -52,26 +75,30 @@ static void winrt_windows_ui_notifications_toast_notification_finalize(GObject*
{ {
winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE (self); winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE (self);
if (winrt_event_token_operator_bool(priv->activated.token)) for (const auto& item : priv->activated)
{ {
priv->notification->data.Activated(*winrt_event_token_get_internal(priv->activated.token)); auto token = std::get<0>(item);
g_clear_object(&priv->activated.token); if (winrt_event_token_operator_bool(token))
{
priv->notification->data.Activated(*winrt_event_token_get_internal(token));
} }
g_object_unref(token);
}
priv->activated.clear();
for (const auto& item : priv->failed)
{
auto token = std::get<0>(item);
if (winrt_event_token_operator_bool(token))
{
priv->notification->data.Failed(*winrt_event_token_get_internal(token));
}
g_object_unref(token);
}
priv->failed.clear();
delete priv->notification; delete priv->notification;
if (priv->activated.callback && priv->activated.context && priv->activated.free)
{
priv->activated.free(priv->activated.context);
priv->activated.Clear();
}
if (priv->failed.callback && priv->failed.context && priv->failed.free)
{
priv->failed.free(priv->failed.context);
priv->failed.Clear();
}
G_OBJECT_CLASS(winrt_windows_ui_notifications_toast_notification_parent_class)->dispose(self); G_OBJECT_CLASS(winrt_windows_ui_notifications_toast_notification_parent_class)->dispose(self);
} }
@ -202,12 +229,6 @@ winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(win
winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self);
winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(self, priv->activated.token);
priv->activated.callback = callback;
priv->activated.context = context;
priv->activated.free = free;
auto token = priv->notification->data.Activated([&](auto sender, winrt::Windows::Foundation::IInspectable inspectable) auto token = priv->notification->data.Activated([&](auto sender, winrt::Windows::Foundation::IInspectable inspectable)
{ {
std::wstring arguments; std::wstring arguments;
@ -233,30 +254,30 @@ winrtEventToken* winrt_windows_ui_notifications_toast_notification_Activated(win
} }
std::cout << "Notification activated!" << std::endl; std::cout << "Notification activated!" << std::endl;
priv->activated.callback(wsview_to_char(arguments.data()), nullptr /* user_input */ , 0 /* user_input.size() */, priv->activated.context); callback(wsview_to_char(arguments.data()), nullptr /* user_input */ , 0 /* user_input.size() */, context);
}); });
priv->activated.token = winrt_event_token_new_from_token(&token); auto new_token = winrt_event_token_new_from_token(&token);
g_object_ref(priv->activated.token); g_object_ref(new_token);
return priv->activated.token;
priv->activated.emplace(new_token, Callback<NotificationCallbackActivated>(callback, context, free));
return new_token;
} }
void winrt_windows_ui_notifications_toast_notification_RemoveActivatedAction(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token) void winrt_windows_ui_notifications_toast_notification_RemoveActivated(winrtWindowsUINotificationsToastNotification* self, winrtEventToken* token)
{ {
g_return_if_fail (WINRT_IS_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION (self)); g_return_if_fail (WINRT_IS_WINDOWS_UI_NOTIFICATIONS_TOAST_NOTIFICATION (self));
winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self); winrtWindowsUINotificationsToastNotificationPrivate* priv = WINRT_WINDOWS_UI_NOTIFICATION_TOAST_NOTIFICATION_GET_PRIVATE(self);
if (winrt_event_token_get_value(token) == winrt_event_token_get_value(priv->activated.token)) auto item = priv->activated.find(token);
if (item != priv->activated.end())
{ {
if (winrt_event_token_operator_bool(token)) auto local_token = std::get<0>(*item);
if (winrt_event_token_operator_bool(local_token))
{ {
priv->notification->data.Activated(*winrt_event_token_get_internal(token)); priv->notification->data.Activated(*winrt_event_token_get_internal(local_token));
} }
if (priv->activated.callback && priv->activated.context && priv->activated.free) priv->activated.erase(item);
{
priv->activated.free(priv->activated.context);
priv->activated.Clear();
}
} }
} }

View file

@ -31,7 +31,7 @@ public class Plugin : RootInterface, Object {
var token = m.Activated((c, d) => { var token = m.Activated((c, d) => {
var i = 2; var i = 2;
}); });
m.RemoveActivatedAction(token); m.RemoveActivated(token);
var h = m.ExpiresOnReboot; var h = m.ExpiresOnReboot;
m.ExpiresOnReboot = false; m.ExpiresOnReboot = false;

View file

@ -16,7 +16,7 @@ namespace winrt.Windows.UI.Notifications {
public string Tag { get; set; } // TODO: check if valac is cleaning this string public string Tag { get; set; } // TODO: check if valac is cleaning this string
public string Group { get; set; } public string Group { get; set; }
public winrt.EventToken Activated(owned NotificationCallbackActivated handler); public winrt.EventToken Activated(owned NotificationCallbackActivated handler);
public void RemoveActivatedAction(winrt.EventToken token); public void RemoveActivated(winrt.EventToken token);
} }
[CCode (type_id = "winrt_windows_ui_notifications_toast_notifier_get_type ()")] [CCode (type_id = "winrt_windows_ui_notifications_toast_notifier_get_type ()")]