From 17f1c055daa84e137226336e1f29e1fef7610e6b Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 15 Aug 2025 10:30:33 +0200 Subject: [PATCH] WM: Add message type for remote downloader messages to message bus We plan on using this for online assets (see blender/blender!130543), to send status updates with a URL to identify the online library remote. In future this can be expanded for multiple kinds of messages with differing data, like progress reports, sub-resource download messages (e.g. individual assets), etc. While this will only be used for online assets for the start, I imagine we'd want these same kind of status messages for other remote resources. Hence the name `WM_MSG_TYPE_REMOTE_IO`. Pull Request: https://projects.blender.org/blender/blender/pulls/144567 --- source/blender/windowmanager/CMakeLists.txt | 1 + .../message_bus/intern/wm_message_bus.cc | 1 + .../intern/wm_message_bus_remote_io.cc | 144 ++++++++++++++++++ .../message_bus/wm_message_bus.hh | 40 ++++- 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 source/blender/windowmanager/message_bus/intern/wm_message_bus_remote_io.cc diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index e6f65e54d2b..cf6b6b6261d 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -57,6 +57,7 @@ set(SRC gizmo/intern/wm_gizmo_target_props.cc gizmo/intern/wm_gizmo_type.cc message_bus/intern/wm_message_bus.cc + message_bus/intern/wm_message_bus_remote_io.cc message_bus/intern/wm_message_bus_rna.cc message_bus/intern/wm_message_bus_static.cc diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus.cc b/source/blender/windowmanager/message_bus/intern/wm_message_bus.cc index 7446a0a5274..a6a9ce0cf33 100644 --- a/source/blender/windowmanager/message_bus/intern/wm_message_bus.cc +++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus.cc @@ -33,6 +33,7 @@ using wmMsgTypeInitFn = void (*)(wmMsgTypeInfo *); static wmMsgTypeInitFn wm_msg_init_fn[WM_MSG_TYPE_NUM] = { WM_msgtypeinfo_init_rna, WM_msgtypeinfo_init_static, + WM_msgtypeinfo_init_remote_io, }; void WM_msgbus_types_init() diff --git a/source/blender/windowmanager/message_bus/intern/wm_message_bus_remote_io.cc b/source/blender/windowmanager/message_bus/intern/wm_message_bus_remote_io.cc new file mode 100644 index 00000000000..49c810147a0 --- /dev/null +++ b/source/blender/windowmanager/message_bus/intern/wm_message_bus_remote_io.cc @@ -0,0 +1,144 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup wm + */ + +#include "CLG_log.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_ghash.h" +#include "BLI_hash.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_string_ref.hh" + +#include "WM_types.hh" +#include "message_bus/intern/wm_message_bus_intern.hh" + +/* -------------------------------------------------------------------------- */ + +static uint wm_msg_remote_io_gset_hash(const void *key_p) +{ + const wmMsgSubscribeKey_RemoteIO *key = static_cast(key_p); + const wmMsgParams_RemoteIO *params = &key->msg.params; + uint k = BLI_hash_string(params->remote_url); + return k; +} +static bool wm_msg_remote_io_gset_cmp(const void *key_a_p, const void *key_b_p) +{ + const wmMsgParams_RemoteIO *params_a = + &(static_cast(key_a_p))->msg.params; + const wmMsgParams_RemoteIO *params_b = + &(static_cast(key_b_p))->msg.params; + return !STREQ(params_a->remote_url, params_b->remote_url); +} + +static void *wm_msg_remote_io_gset_key_duplicate(const void *key_p) +{ + const wmMsgSubscribeKey_RemoteIO *key_src = static_cast( + key_p); + wmMsgSubscribeKey_RemoteIO *key = MEM_dupallocN(__func__, *key_src); + key->msg.params.remote_url = BLI_strdup(key_src->msg.params.remote_url); + return key; +} +static void wm_msg_remote_io_gset_key_free(void *key_p) +{ + wmMsgSubscribeKey_RemoteIO *key = static_cast(key_p); + MEM_freeN(key->msg.params.remote_url); + wmMsgSubscribeValueLink *msg_lnk_next; + for (wmMsgSubscribeValueLink *msg_lnk = + static_cast(key->head.values.first); + msg_lnk; + msg_lnk = msg_lnk_next) + { + msg_lnk_next = msg_lnk->next; + BLI_remlink(&key->head.values, msg_lnk); + MEM_freeN(msg_lnk); + } + MEM_freeN(key); +} + +static void wm_msg_remote_io_repr(FILE *stream, const wmMsgSubscribeKey *msg_key) +{ + const wmMsgSubscribeKey_RemoteIO *m = (wmMsgSubscribeKey_RemoteIO *)msg_key; + fprintf(stream, + "msg.head.id, + BLI_listbase_count(&m->head.values)); +} + +void WM_msgtypeinfo_init_remote_io(wmMsgTypeInfo *msgtype_info) +{ + msgtype_info->gset.hash_fn = wm_msg_remote_io_gset_hash; + msgtype_info->gset.cmp_fn = wm_msg_remote_io_gset_cmp; + msgtype_info->gset.key_duplicate_fn = wm_msg_remote_io_gset_key_duplicate; + msgtype_info->gset.key_free_fn = wm_msg_remote_io_gset_key_free; + msgtype_info->repr = wm_msg_remote_io_repr; +} + +/* -------------------------------------------------------------------------- */ + +wmMsgSubscribeKey_RemoteIO *WM_msg_lookup_remote_io(wmMsgBus *mbus, + const wmMsgParams_RemoteIO *msg_key_params) +{ + wmMsgSubscribeKey_RemoteIO key_test; + key_test.msg.params = *msg_key_params; + return static_cast( + BLI_gset_lookup(mbus->messages_gset[WM_MSG_TYPE_REMOTE_IO], &key_test)); +} + +void WM_msg_publish_remote_io_params(wmMsgBus *mbus, const wmMsgParams_RemoteIO *msg_key_params) +{ + CLOG_DEBUG(WM_LOG_MSGBUS_PUB, "remote_io(remote_url=%s)", msg_key_params->remote_url); + + wmMsgSubscribeKey_RemoteIO *key = WM_msg_lookup_remote_io(mbus, msg_key_params); + if (key) { + WM_msg_publish_with_key(mbus, &key->head); + } +} + +void WM_msg_publish_remote_io(wmMsgBus *mbus, const blender::StringRef remote_url) +{ + wmMsgParams_RemoteIO params{}; + params.remote_url = BLI_strdupn(remote_url.data(), remote_url.size()); + WM_msg_publish_remote_io_params(mbus, ¶ms); + + /* Value was copied into the publish key. */ + MEM_freeN(params.remote_url); +} + +void WM_msg_subscribe_remote_io_params(wmMsgBus *mbus, + const wmMsgParams_RemoteIO *msg_key_params, + const wmMsgSubscribeValue *msg_val_params, + const char *id_repr) +{ + wmMsgSubscribeKey_RemoteIO msg_key_test{}; + + /* Use when added. */ + msg_key_test.msg.head.id = id_repr; + msg_key_test.msg.head.type = WM_MSG_TYPE_REMOTE_IO; + /* For lookup. */ + msg_key_test.msg.params = *msg_key_params; + + WM_msg_subscribe_with_key(mbus, &msg_key_test.head, msg_val_params); +} + +void WM_msg_subscribe_remote_io(wmMsgBus *mbus, + const blender::StringRef remote_url, + const wmMsgSubscribeValue *msg_val_params, + const char *id_repr) +{ + wmMsgParams_RemoteIO params{}; + params.remote_url = BLI_strdupn(remote_url.data(), remote_url.size()); + WM_msg_subscribe_remote_io_params(mbus, ¶ms, msg_val_params, id_repr); + + /* Value was copied into the subscribe key. */ + MEM_freeN(params.remote_url); +} diff --git a/source/blender/windowmanager/message_bus/wm_message_bus.hh b/source/blender/windowmanager/message_bus/wm_message_bus.hh index b90676ac946..48bb2b8f1c8 100644 --- a/source/blender/windowmanager/message_bus/wm_message_bus.hh +++ b/source/blender/windowmanager/message_bus/wm_message_bus.hh @@ -8,6 +8,8 @@ #pragma once +#include "BLI_string_ref.hh" + #include "DNA_listBase.h" #include "RNA_prototypes.hh" @@ -35,8 +37,11 @@ using wmMsgSubscribeValueUpdateIdFn = enum { WM_MSG_TYPE_RNA = 0, WM_MSG_TYPE_STATIC = 1, + /** Messages relating to some remote resources, like progress reporting for online asset + * downloads. */ + WM_MSG_TYPE_REMOTE_IO = 2, }; -#define WM_MSG_TYPE_NUM 2 +#define WM_MSG_TYPE_NUM 3 struct wmMsgTypeInfo { struct { @@ -167,6 +172,39 @@ void WM_msg_subscribe_static(wmMsgBus *mbus, const wmMsgSubscribeValue *msg_val_params, const char *id_repr); +/* -------------------------------------------------------------------------- */ +/* `wm_message_bus_remote_io.cc` */ + +struct wmMsgParams_RemoteIO { + /* Owned, needs freeing with `MEM_freeN()`. */ + const char *remote_url; +}; + +struct wmMsg_RemoteIO { + wmMsg head; /* Keep first. */ + wmMsgParams_RemoteIO params; +}; + +struct wmMsgSubscribeKey_RemoteIO { + wmMsgSubscribeKey head; + wmMsg_RemoteIO msg; +}; + +void WM_msgtypeinfo_init_remote_io(wmMsgTypeInfo *msgtype_info); + +wmMsgSubscribeKey_RemoteIO *WM_msg_lookup_remote_io(wmMsgBus *mbus, + const wmMsgParams_RemoteIO *msg_key_params); +void WM_msg_publish_remote_io_params(wmMsgBus *mbus, const wmMsgParams_RemoteIO *msg_key_params); +void WM_msg_publish_remote_io(wmMsgBus *mbus, blender::StringRef remote_url); +void WM_msg_subscribe_remote_io_params(wmMsgBus *mbus, + const wmMsgParams_RemoteIO *msg_key_params, + const wmMsgSubscribeValue *msg_val_params, + const char *id_repr); +void WM_msg_subscribe_remote_io(wmMsgBus *mbus, + blender::StringRef remote_url, + const wmMsgSubscribeValue *msg_val_params, + const char *id_repr); + /* -------------------------------------------------------------------------- */ /* `wm_message_bus_rna.cc` */