From 09605cec03ea23e87ee285fd950a23ce8d23678d Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 20 Jun 2014 10:53:02 -0300 Subject: 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 --- src/nvim/api/vim.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/nvim/api') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e7261e1096..fbeb42cf4b 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -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); -- cgit From ea7a389ec77c0031160ce860129101c603d8e0ec Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 20 Jun 2014 10:53:05 -0300 Subject: channel: Implement the 'channel_send_call' function This function is used to send RPC calls to clients. In contrast to `channel_send_event`, this function will block until the client sends a response(But it will continue processing requests from that client). The RPC call stack has a maximum depth of 20. --- src/nvim/api/private/helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api') diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 30301e9368..d5ebc93f7c 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -341,7 +341,7 @@ String cstr_to_string(const char *str) }; } -static bool object_to_vim(Object obj, typval_T *tv, Error *err) +bool object_to_vim(Object obj, typval_T *tv, Error *err) { tv->v_type = VAR_UNKNOWN; tv->v_lock = 0; -- cgit From 296da85198a7d5da36dbb2e6f213edb5da511635 Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Mon, 23 Jun 2014 11:52:42 -0300 Subject: channel/msgpack_rpc: Refactor API dispatching This is how API dispatching worked before this commit: - The generated `msgpack_rpc_dispatch` function receives a the `msgpack_packer` argument. - The response is incrementally built while validating/calling the API. - Return values/errors are also packed into the `msgpack_packer` while the final response is being calculated. Now the `msgpack_packer` argument is no longer provided, and the `msgpack_rpc_dispatch` function returns `Object`/`Error` values to `msgpack_rpc_call`, which will use those values to build the response in a single pass. This was done because the new `channel_send_call` function created the possibility of having recursive API invocations, and this wasn't possible when sharing a single `msgpack_sbuffer` across call frames(it was shared implicitly through the `msgpack_packer` instance). Since we only start to build the response when the necessary information has been computed, it's now safe to share a single `msgpack_sbuffer` instance across all channels and API invocations. Some other changes also had to be performed: - Handling of the metadata discover was moved to `msgpack_rpc_call` - Expose more types as subtypes of `Object`, this was required to forward the return value from `msgpack_rpc_dispatch` to `msgpack_rpc_call` - Added more helper macros for casting API types to `Object` any --- src/nvim/api/private/defs.h | 18 ++++++++++++++- src/nvim/api/private/helpers.c | 2 ++ src/nvim/api/private/helpers.h | 51 +++++++++++++++++++++++++++++++++++------- 3 files changed, 62 insertions(+), 9 deletions(-) (limited to 'src/nvim/api') diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index ee0fc02c4d..b049412014 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -65,8 +65,16 @@ typedef enum { kObjectTypeInteger, kObjectTypeFloat, kObjectTypeString, + kObjectTypeBuffer, + kObjectTypeWindow, + kObjectTypeTabpage, kObjectTypeArray, - kObjectTypeDictionary + kObjectTypeDictionary, + kObjectTypePosition, + kObjectTypeStringArray, + kObjectTypeBufferArray, + kObjectTypeWindowArray, + kObjectTypeTabpageArray, } ObjectType; struct object { @@ -76,8 +84,16 @@ struct object { Integer integer; Float floating; String string; + Buffer buffer; + Window window; + Tabpage tabpage; Array array; Dictionary dictionary; + Position position; + StringArray stringarray; + BufferArray bufferarray; + WindowArray windowarray; + TabpageArray tabpagearray; } data; }; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index d5ebc93f7c..024f0c2405 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -426,6 +426,8 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err) } tv->vval.v_dict->dv_refcount++; break; + default: + abort(); } return true; diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index e1e1a35490..f1b9dc3bc8 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -14,7 +14,9 @@ err->set = true; \ } while (0) -#define BOOL_OBJ(b) ((Object) { \ +#define OBJECT_OBJ(o) o + +#define BOOLEAN_OBJ(b) ((Object) { \ .type = kObjectTypeBoolean, \ .data.boolean = b \ }) @@ -26,26 +28,59 @@ #define STRING_OBJ(s) ((Object) { \ .type = kObjectTypeString, \ - .data.string = cstr_to_string(s) \ + .data.string = s \ }) -#define STRINGL_OBJ(d, s) ((Object) { \ - .type = kObjectTypeString, \ - .data.string = (String) { \ - .size = s, \ - .data = xmemdup(d, s) \ - }}) +#define BUFFER_OBJ(s) ((Object) { \ + .type = kObjectTypeBuffer, \ + .data.buffer = s \ + }) + +#define WINDOW_OBJ(s) ((Object) { \ + .type = kObjectTypeWindow, \ + .data.window = s \ + }) + +#define TABPAGE_OBJ(s) ((Object) { \ + .type = kObjectTypeTabpage, \ + .data.tabpage = s \ + }) #define ARRAY_OBJ(a) ((Object) { \ .type = kObjectTypeArray, \ .data.array = a \ }) +#define STRINGARRAY_OBJ(a) ((Object) { \ + .type = kObjectTypeStringArray, \ + .data.stringarray = a \ + }) + +#define BUFFERARRAY_OBJ(a) ((Object) { \ + .type = kObjectTypeBufferArray, \ + .data.bufferarray = a \ + }) + +#define WINDOWARRAY_OBJ(a) ((Object) { \ + .type = kObjectTypeWindowArray, \ + .data.windowarray = a \ + }) + +#define TABPAGEARRAY_OBJ(a) ((Object) { \ + .type = kObjectTypeTabpageArray, \ + .data.tabpagearray = a \ + }) + #define DICTIONARY_OBJ(d) ((Object) { \ .type = kObjectTypeDictionary, \ .data.dictionary = d \ }) +#define POSITION_OBJ(p) ((Object) { \ + .type = kObjectTypePosition, \ + .data.position = p \ + }) + #define NIL ((Object) {.type = kObjectTypeNil}) #define PUT(dict, k, v) \ -- cgit