Advertisement
Guest User

more detailed sc sketch

a guest
Jun 21st, 2011
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.86 KB | None | 0 0
  1. /**** LIBXMMSCLIENT: ****/
  2.  
  3. /* Extend xmmsc_result_t with msg_id and sender fields, which are
  4.  * passed to extended notifiers.
  5.  * Both should be zero for non-c2c results.
  6.  */
  7. typedef int (*xmmsc_extended_notifier_t) (xmmsv_t *, int msg_id, int sender_id, void *udata);
  8. void xmmsc_result_extended_notifier_set (xmmsc_result_t *, extended_notifier_t f, void *udata);
  9.  
  10. xmmsc_result_t *xmmsc_broadcast_c2c_message (void);
  11. xmmsc_result_t *xmmsc_broadcast_c2c_client_disconnect (void);
  12.  
  13. xmmsc_result_t *xmmsc_c2c_send (int dest, bool expect_reply, xmmsv_t *value);
  14. xmmsc_result_t *xmmsc_c2c_reply (int orig_msg, bool expect_reply, xmmsv_t *value);
  15.  
  16. /* Convenience wrappers around c2c_send and c2c_reply that build the xmmsv_t
  17.  * from the given C type. Analogous to xmms_object_emit_f.
  18.  */
  19. xmmsc_result_t *xmmsc_c2c_send_f (int dest, bool expect_reply, xmmsv_type_t type, ...);
  20. xmmsc_result_t *xmmsc_c2c_reply_f (int orig_msg, bool expect_reply, xmmsv_type_t type, ...);
  21.  
  22. /* Do we really need these?
  23.  * What will their results be associated with?
  24.  * Aren't they equivalent to looping over dests[] or orig_msgs[] and caling
  25.  * c2c_send or c2c_reply?
  26.  */
  27. xmmsc_result_t *xmmsc_c2c_send_multi (int dests[], ...);
  28. xmmsc_result_t *xmmsc_c2c_reply_multi (int orig_msgs[], ...);
  29.  
  30. /**** LIBXMMSCLIENT-SC: ****/
  31.  
  32. /* Since it will be possible for a client to setup the c2c_message broadcast to
  33.  * receive arbitrary messages there should be some kind of protocol that
  34.  * indicates whether a given message should be parsed by libxmmsclient-sc or
  35.  * ignored by it (and left for other callbacks to treat).
  36.  * We could make, for instance, libxmmsclient-sc expect dictionaries with two
  37.  * special keys, one of them used to indicate a command (method-call,
  38.  * introspection...) and the other used to indicate the arguments for the
  39.  * command.
  40.  * The format of the arguments should also be well defined for each of the
  41.  * commands.
  42.  */
  43.  
  44. typedef enum {
  45.     XMMSC_SC_CALL,
  46.     XMMSC_SC_INTROSPECT
  47. } xmmsc_sc_commands_t;
  48.  
  49. #define XMMSC_SC_COMMAND_KEY "libxmmsclient-sc-command"
  50. #define XMMSC_SC_ARGS_KEY "libxmmsclient-sc-args"
  51.  
  52. xmmsc_result_t *
  53. xmmsc_sc_method_call (int dest, char *name, xmmsv_t *args) {
  54.     /* The 'call' command expects as argument a dictionary containing
  55.      * "name" : method name, "args" : list of arguments, and an optional
  56.      * "version". */
  57.     info = xmmsv_build_dict (XMMSV_DICT_ENTRY_STRING ("method", name),
  58.                              XMMSV_DICT_ENTRY (xmmsv_ref (args)),
  59.                              XMMSV_DICT_END);
  60.  
  61.     msg = xmmsv_build_dict (XMMSV_DICT_ENTRY_INT (XMMSC_SC_COMMAND_KEY, XMMSC_SC_CALL),
  62.                             XMMSV_DICT_ENTRY (XMMSC_SC_ARGS_KEY, info),
  63.                             XMMSV_DICT_END);
  64.     return xmmsc_c2c_message (dest, 1, msg);
  65. }
  66.  
  67. xmmsc_result_t *
  68. xmmsc_sc_method_call_version (int dest, int version, char *name, xmmsv_t *args) {
  69.     /* Same as sc_method_call except with version added to the dict */
  70. }
  71.  
  72. /* xmmsc_sc_method_call_f (dest, version, name, type1, arg1, type2, arg2, ...)
  73.  * may be desirable too. */
  74.  
  75. xmmsc_result_t *
  76. xmmsc_sc_introspect (int dest, char *property) {
  77.     /* The introspect command expects a property as argument. */
  78.     msg = xmmsv_build_dict (XMMSV_DICT_ENTRY_INT (XMMSC_SC_COMMAND_KEY, XMMSC_SC_INTROSPECT),
  79.                             XMMSV_DICT_ENTRY_STRING (XMMSC_SC_ARGS_KEY, property));
  80.     return xmmsc_c2c_message (dest, 1, msg);
  81. }
  82.  
  83. int
  84. sc_on_client_disconnect (xmmsv_t *disconnected_client_id, sc_description_t *udata) {
  85.     /* Remove client from all broadcast lists */
  86. }
  87.  
  88. int
  89. sc_on_return (xmmsv_t *val) {
  90.     if (xmmsv_is_error (val)) {
  91.         /* Display the error. */
  92.     }
  93.     return 0; /* or 1 */
  94. }
  95.  
  96. void
  97. xmmsc_sc_return (int orig_msg, xmmsv_t *value) {
  98.     /* Expect no more replies */
  99.     res = xmmsc_c2c_reply (orig_msg, 0, value);
  100.  
  101.     xmmsc_result_notifier_set (res, sc_on_return, NULL);
  102.     xmmsc_result_unref (res);
  103. }
  104.  
  105. int
  106. sc_receive (xmmsv_t *val, int msgid, int sender, sc_description_t *udata) {
  107.     int command;
  108.     xmmsv_t *command_args;
  109.  
  110.     /* Try to parse val to get command and command_args using the XMMSC_SC_*_KEY
  111.      * keys.
  112.      * If both are missing, ignore the message and let any other callbacks get
  113.      * it.
  114.      */
  115.  
  116.     switch (command) {
  117.         case XMMSC_SC_CALL:
  118.             /* Check version if present;
  119.              * Extract method name and args from command_args;
  120.              * Find method in method list, return error if not found;
  121.              * Deserialize args into C types and check against method signature?
  122.              * Call method and return its result.
  123.              */
  124.  
  125.         case XMMSC_SC_INTROSPECT:
  126.             /* Get property from command_args;
  127.              * Look up property in the service's description and return it.
  128.              */
  129.  
  130.         case XMMSC_SC_BROADCAST_SUBSCRIBE:
  131.             /* Add msgid to some list so we can reply later
  132.              * One problem: the server will remove the msgid from the pool of
  133.              * pending messages after the first reply, so subsequent broadcasts
  134.              * will fail.
  135.              * This may require adding a new command to the courier object so
  136.              * that it doesn't forget the message id after a reply. */
  137.  
  138.         default:
  139.             /* Wrong type! Respond with an error */
  140.     }
  141.  
  142.     return 1; /* Receive more method calls */
  143. }
  144.  
  145. void
  146. xmmsc_sc_send_broadcast (char *name, xmmsv_t *value) {
  147.     /* Look up the list of subscriber msg_ids, send them a reply. Don't expect a counter-reply. */
  148. }
  149.  
  150. /***** CLIENT USING SERVICE: *****/
  151. res = xmmsc_sc_method_call (dest, name, args);
  152. xmmsc_result_wait (res);
  153. val = xmmsc_result_get_value (res);
  154. /* now val is the return value of the method call or an error from the daemon */
  155.  
  156. /**** SERVICE CLIENT: ****/
  157. desc->version = ...;
  158. desc->methods = ...;
  159. desc->broadcasts = ...;
  160.  
  161. /* somewhere internally */
  162. res = xmmsc_broadcast_c2c_message ();
  163. xmmsc_result_extended_notifier_set (res, sc_receive, desc);
  164. xmmsc_result_unref (res);
  165.  
  166. res = xmmsc_broadcast_c2c_client_disconnect ();
  167. xmmsc_result_notifier_set (res, sc_on_client_disconnect, desc);
  168. xmmsc_result_unref (res);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement