Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**** LIBXMMSCLIENT: ****/
- /* Extend xmmsc_result_t with msg_id and sender fields, which are
- * passed to extended notifiers.
- * Both should be zero for non-c2c results.
- */
- typedef int (*xmmsc_extended_notifier_t) (xmmsv_t *, int msg_id, int sender_id, void *udata);
- void xmmsc_result_extended_notifier_set (xmmsc_result_t *, extended_notifier_t f, void *udata);
- xmmsc_result_t *xmmsc_broadcast_c2c_message (void);
- xmmsc_result_t *xmmsc_broadcast_c2c_client_disconnect (void);
- xmmsc_result_t *xmmsc_c2c_send (int dest, bool expect_reply, xmmsv_t *value);
- xmmsc_result_t *xmmsc_c2c_reply (int orig_msg, bool expect_reply, xmmsv_t *value);
- /* Convenience wrappers around c2c_send and c2c_reply that build the xmmsv_t
- * from the given C type. Analogous to xmms_object_emit_f.
- */
- xmmsc_result_t *xmmsc_c2c_send_f (int dest, bool expect_reply, xmmsv_type_t type, ...);
- xmmsc_result_t *xmmsc_c2c_reply_f (int orig_msg, bool expect_reply, xmmsv_type_t type, ...);
- /* Do we really need these?
- * What will their results be associated with?
- * Aren't they equivalent to looping over dests[] or orig_msgs[] and caling
- * c2c_send or c2c_reply?
- */
- xmmsc_result_t *xmmsc_c2c_send_multi (int dests[], ...);
- xmmsc_result_t *xmmsc_c2c_reply_multi (int orig_msgs[], ...);
- /**** LIBXMMSCLIENT-SC: ****/
- /* Since it will be possible for a client to setup the c2c_message broadcast to
- * receive arbitrary messages there should be some kind of protocol that
- * indicates whether a given message should be parsed by libxmmsclient-sc or
- * ignored by it (and left for other callbacks to treat).
- * We could make, for instance, libxmmsclient-sc expect dictionaries with two
- * special keys, one of them used to indicate a command (method-call,
- * introspection...) and the other used to indicate the arguments for the
- * command.
- * The format of the arguments should also be well defined for each of the
- * commands.
- */
- typedef enum {
- XMMSC_SC_CALL,
- XMMSC_SC_INTROSPECT
- } xmmsc_sc_commands_t;
- #define XMMSC_SC_COMMAND_KEY "libxmmsclient-sc-command"
- #define XMMSC_SC_ARGS_KEY "libxmmsclient-sc-args"
- xmmsc_result_t *
- xmmsc_sc_method_call (int dest, char *name, xmmsv_t *args) {
- /* The 'call' command expects as argument a dictionary containing
- * "name" : method name, "args" : list of arguments, and an optional
- * "version". */
- info = xmmsv_build_dict (XMMSV_DICT_ENTRY_STRING ("method", name),
- XMMSV_DICT_ENTRY (xmmsv_ref (args)),
- XMMSV_DICT_END);
- msg = xmmsv_build_dict (XMMSV_DICT_ENTRY_INT (XMMSC_SC_COMMAND_KEY, XMMSC_SC_CALL),
- XMMSV_DICT_ENTRY (XMMSC_SC_ARGS_KEY, info),
- XMMSV_DICT_END);
- return xmmsc_c2c_message (dest, 1, msg);
- }
- xmmsc_result_t *
- xmmsc_sc_method_call_version (int dest, int version, char *name, xmmsv_t *args) {
- /* Same as sc_method_call except with version added to the dict */
- }
- /* xmmsc_sc_method_call_f (dest, version, name, type1, arg1, type2, arg2, ...)
- * may be desirable too. */
- xmmsc_result_t *
- xmmsc_sc_introspect (int dest, char *property) {
- /* The introspect command expects a property as argument. */
- msg = xmmsv_build_dict (XMMSV_DICT_ENTRY_INT (XMMSC_SC_COMMAND_KEY, XMMSC_SC_INTROSPECT),
- XMMSV_DICT_ENTRY_STRING (XMMSC_SC_ARGS_KEY, property));
- return xmmsc_c2c_message (dest, 1, msg);
- }
- int
- sc_on_client_disconnect (xmmsv_t *disconnected_client_id, sc_description_t *udata) {
- /* Remove client from all broadcast lists */
- }
- int
- sc_on_return (xmmsv_t *val) {
- if (xmmsv_is_error (val)) {
- /* Display the error. */
- }
- return 0; /* or 1 */
- }
- void
- xmmsc_sc_return (int orig_msg, xmmsv_t *value) {
- /* Expect no more replies */
- res = xmmsc_c2c_reply (orig_msg, 0, value);
- xmmsc_result_notifier_set (res, sc_on_return, NULL);
- xmmsc_result_unref (res);
- }
- int
- sc_receive (xmmsv_t *val, int msgid, int sender, sc_description_t *udata) {
- int command;
- xmmsv_t *command_args;
- /* Try to parse val to get command and command_args using the XMMSC_SC_*_KEY
- * keys.
- * If both are missing, ignore the message and let any other callbacks get
- * it.
- */
- switch (command) {
- case XMMSC_SC_CALL:
- /* Check version if present;
- * Extract method name and args from command_args;
- * Find method in method list, return error if not found;
- * Deserialize args into C types and check against method signature?
- * Call method and return its result.
- */
- case XMMSC_SC_INTROSPECT:
- /* Get property from command_args;
- * Look up property in the service's description and return it.
- */
- case XMMSC_SC_BROADCAST_SUBSCRIBE:
- /* Add msgid to some list so we can reply later
- * One problem: the server will remove the msgid from the pool of
- * pending messages after the first reply, so subsequent broadcasts
- * will fail.
- * This may require adding a new command to the courier object so
- * that it doesn't forget the message id after a reply. */
- default:
- /* Wrong type! Respond with an error */
- }
- return 1; /* Receive more method calls */
- }
- void
- xmmsc_sc_send_broadcast (char *name, xmmsv_t *value) {
- /* Look up the list of subscriber msg_ids, send them a reply. Don't expect a counter-reply. */
- }
- /***** CLIENT USING SERVICE: *****/
- res = xmmsc_sc_method_call (dest, name, args);
- xmmsc_result_wait (res);
- val = xmmsc_result_get_value (res);
- /* now val is the return value of the method call or an error from the daemon */
- /**** SERVICE CLIENT: ****/
- desc->version = ...;
- desc->methods = ...;
- desc->broadcasts = ...;
- /* somewhere internally */
- res = xmmsc_broadcast_c2c_message ();
- xmmsc_result_extended_notifier_set (res, sc_receive, desc);
- xmmsc_result_unref (res);
- res = xmmsc_broadcast_c2c_client_disconnect ();
- xmmsc_result_notifier_set (res, sc_on_client_disconnect, desc);
- xmmsc_result_unref (res);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement