mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
channel/msgpack_rpc: Refactor msgpack_rpc_notification/serialize_event
- Generalize some argument names(event type -> event name, event data -> event arg) - Rename serialize_event to serialize_message - Rename msgpack_rpc_notification to msgpack_rpc_message - Extract the message type out of msgpack_rpc_message - Add 'id' parameter to msgpack_rpc_message/serialize_message to create messages that are not notifications
This commit is contained in:
parent
c0b0bd07fd
commit
09605cec03
@ -424,8 +424,8 @@ void vim_set_current_tabpage(Tabpage tabpage, Error *err)
|
||||
/// @param event The event type string
|
||||
void vim_subscribe(uint64_t channel_id, String event)
|
||||
{
|
||||
size_t length = (event.size < EVENT_MAXLEN ? event.size : EVENT_MAXLEN);
|
||||
char e[EVENT_MAXLEN + 1];
|
||||
size_t length = (event.size < METHOD_MAXLEN ? event.size : METHOD_MAXLEN);
|
||||
char e[METHOD_MAXLEN + 1];
|
||||
memcpy(e, event.data, length);
|
||||
e[length] = NUL;
|
||||
channel_subscribe(channel_id, e);
|
||||
@ -437,8 +437,10 @@ void vim_subscribe(uint64_t channel_id, String event)
|
||||
/// @param event The event type string
|
||||
void vim_unsubscribe(uint64_t channel_id, String event)
|
||||
{
|
||||
size_t length = (event.size < EVENT_MAXLEN ? event.size : EVENT_MAXLEN);
|
||||
char e[EVENT_MAXLEN + 1];
|
||||
size_t length = (event.size < METHOD_MAXLEN ?
|
||||
event.size :
|
||||
METHOD_MAXLEN);
|
||||
char e[METHOD_MAXLEN + 1];
|
||||
memcpy(e, event.data, length);
|
||||
e[length] = NUL;
|
||||
channel_unsubscribe(channel_id, e);
|
||||
|
@ -115,21 +115,21 @@ void channel_from_stream(uv_stream_t *stream)
|
||||
///
|
||||
/// @param id The channel id. If 0, the event will be sent to all
|
||||
/// channels that have subscribed to the event type
|
||||
/// @param type The event type, an arbitrary string
|
||||
/// @param obj The event data
|
||||
/// @param name The event name, an arbitrary string
|
||||
/// @param arg The event arg
|
||||
/// @return True if the data was sent successfully, false otherwise.
|
||||
bool channel_send_event(uint64_t id, char *type, Object data)
|
||||
bool channel_send_event(uint64_t id, char *name, Object arg)
|
||||
{
|
||||
Channel *channel = NULL;
|
||||
|
||||
if (id > 0) {
|
||||
if (!(channel = pmap_get(uint64_t)(channels, id))) {
|
||||
msgpack_rpc_free_object(data);
|
||||
msgpack_rpc_free_object(arg);
|
||||
return false;
|
||||
}
|
||||
send_event(channel, type, data);
|
||||
send_message(channel, 2, 0, name, arg);
|
||||
} else {
|
||||
broadcast_event(type, data);
|
||||
broadcast_event(name, arg);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -284,29 +284,33 @@ static bool channel_write(Channel *channel, WBuffer *buffer)
|
||||
return success;
|
||||
}
|
||||
|
||||
static void send_event(Channel *channel, char *type, Object data)
|
||||
static void send_message(Channel *channel,
|
||||
int type,
|
||||
uint64_t id,
|
||||
char *name,
|
||||
Object arg)
|
||||
{
|
||||
channel_write(channel, serialize_event(type, data));
|
||||
channel_write(channel, serialize_message(type, id, name, arg));
|
||||
}
|
||||
|
||||
static void broadcast_event(char *type, Object data)
|
||||
static void broadcast_event(char *name, Object arg)
|
||||
{
|
||||
kvec_t(Channel *) subscribed;
|
||||
kv_init(subscribed);
|
||||
Channel *channel;
|
||||
|
||||
map_foreach_value(channels, channel, {
|
||||
if (pmap_has(cstr_t)(channel->subscribed_events, type)) {
|
||||
if (pmap_has(cstr_t)(channel->subscribed_events, name)) {
|
||||
kv_push(Channel *, subscribed, channel);
|
||||
}
|
||||
});
|
||||
|
||||
if (!kv_size(subscribed)) {
|
||||
msgpack_rpc_free_object(data);
|
||||
msgpack_rpc_free_object(arg);
|
||||
goto end;
|
||||
}
|
||||
|
||||
WBuffer *buffer = serialize_event(type, data);
|
||||
WBuffer *buffer = serialize_message(2, 0, name, arg);
|
||||
|
||||
for (size_t i = 0; i < kv_size(subscribed); i++) {
|
||||
channel_write(kv_A(subscribed, i), buffer);
|
||||
@ -364,17 +368,20 @@ static void close_cb(uv_handle_t *handle)
|
||||
free(handle);
|
||||
}
|
||||
|
||||
static WBuffer *serialize_event(char *type, Object data)
|
||||
static WBuffer *serialize_message(int type,
|
||||
uint64_t id,
|
||||
char *method,
|
||||
Object arg)
|
||||
{
|
||||
String event_type = {.size = strnlen(type, EVENT_MAXLEN), .data = type};
|
||||
String method_str = {.size = strnlen(method, METHOD_MAXLEN), .data = method};
|
||||
msgpack_packer packer;
|
||||
msgpack_packer_init(&packer, &msgpack_event_buffer, msgpack_sbuffer_write);
|
||||
msgpack_rpc_notification(event_type, data, &packer);
|
||||
msgpack_rpc_message(type, id, method_str, arg, &packer);
|
||||
WBuffer *rv = wstream_new_buffer(xmemdup(msgpack_event_buffer.data,
|
||||
msgpack_event_buffer.size),
|
||||
msgpack_event_buffer.size,
|
||||
free);
|
||||
msgpack_rpc_free_object(data);
|
||||
msgpack_rpc_free_object(arg);
|
||||
msgpack_sbuffer_clear(&msgpack_event_buffer);
|
||||
|
||||
return rv;
|
||||
@ -391,3 +398,4 @@ static Channel *register_channel()
|
||||
pmap_put(uint64_t)(channels, rv->id, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/vim.h"
|
||||
|
||||
#define EVENT_MAXLEN 512
|
||||
#define METHOD_MAXLEN 512
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "os/channel.h.generated.h"
|
||||
|
@ -115,13 +115,22 @@ void msgpack_rpc_call(uint64_t id, msgpack_object *req, msgpack_packer *res)
|
||||
msgpack_rpc_dispatch(id, req, res);
|
||||
}
|
||||
|
||||
void msgpack_rpc_notification(String type, Object data, msgpack_packer *pac)
|
||||
void msgpack_rpc_message(int type,
|
||||
uint64_t id,
|
||||
String method,
|
||||
Object arg,
|
||||
msgpack_packer *pac)
|
||||
{
|
||||
msgpack_pack_array(pac, 3);
|
||||
msgpack_pack_int(pac, 2);
|
||||
msgpack_pack_raw(pac, type.size);
|
||||
msgpack_pack_raw_body(pac, type.data, type.size);
|
||||
msgpack_rpc_from_object(data, pac);
|
||||
msgpack_pack_array(pac, id ? 4 : 3);
|
||||
msgpack_pack_int(pac, type);
|
||||
|
||||
if (id) {
|
||||
msgpack_pack_uint64(pac, id);
|
||||
}
|
||||
|
||||
msgpack_pack_raw(pac, method.size);
|
||||
msgpack_pack_raw_body(pac, method.data, method.size);
|
||||
msgpack_rpc_from_object(arg, pac);
|
||||
}
|
||||
|
||||
void msgpack_rpc_error(char *msg, msgpack_packer *res)
|
||||
|
@ -24,13 +24,20 @@ typedef enum {
|
||||
void msgpack_rpc_call(uint64_t id, msgpack_object *req, msgpack_packer *res)
|
||||
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3);
|
||||
|
||||
/// Packs a notification message
|
||||
/// Packs a message
|
||||
///
|
||||
/// @param type The message type, an arbitrary string
|
||||
/// @param data The notification data
|
||||
/// @param type The message type
|
||||
/// @param id The message id, must be an unique integer > 0 or will be
|
||||
/// ignored(the message array will have 3 elements instead of 4).
|
||||
/// @param method The message name, an arbitrary string
|
||||
/// @param arg The message argument
|
||||
/// @param packer Where the notification will be packed to
|
||||
void msgpack_rpc_notification(String type, Object data, msgpack_packer *pac)
|
||||
FUNC_ATTR_NONNULL_ARG(3);
|
||||
void msgpack_rpc_message(int type,
|
||||
uint64_t id,
|
||||
String method,
|
||||
Object arg,
|
||||
msgpack_packer *pac)
|
||||
FUNC_ATTR_NONNULL_ARG(5);
|
||||
|
||||
/// Dispatches to the actual API function after basic payload validation by
|
||||
/// `msgpack_rpc_call`. It is responsible for validating/converting arguments
|
||||
|
Loading…
Reference in New Issue
Block a user