another sc sketch or something
pasted by nesciens [options]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | /**** LIBXMMSCLIENT: ****/ /* Extend xmmsc_result_t with msg_id and sender */ int xmmsc_result_get_msg_id (xmmsc_result_t *res); int xmmsc_result_get_sender (xmmsc_result_t *res); typedef struct { int msg_id; int sender; } extra_t; typedef int (*extended_notifier_t) (xmmsv_t *, extra_t *); 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 (); /* expect_reply and last are booleans */ xmmsc_result_t *xmmsc_c2c_send (int dest, int expect_reply, xmmsv_t *value); xmmsc_result_t *xmmsc_c2c_reply (int orig_msg, int expect_reply, int last, xmmsv_t *value); xmmsc_result_t *xmmsc_c2c_send_multi (int dests[], ...); xmmsc_result_t *xmmsc_c2c_reply_multi (int orig_msgs[], ...); /**** LIBXMMSCLIENT-SC: ****/ xmmsc_result_t * sc_method_call (int dest, char *name, xmmsv_t *args) { val = xmmsv_build_dict (XMMSV_DICT_ENTRY_STRING ("type", "method-call"), XMMSV_DICT_ENTRY_STRING ("method", name), XMMSV_DICT_ENTRY ("args", xmmsv_ref (args), XMMSV_DICT_END); return xmmsc_c2c_message (dest, 1, val); } xmmsc_result_t * 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 */ } int sc_on_return (xmmsv_t *val) { if (xmmsv_is_error (val)) { /* Display the error. */ } return 0; /* or 1 */ } void sc_return (int orig_msg, xmmsv_t *value) { /* expect no more reply, send no more reply */ res = xmmsc_c2c_reply (orig_msg, 0, 1, value); xmmsc_result_notifier_set (res, sc_on_return, NULL); xmmsc_result_unref (res); } /* Is extra.msg_id is 0, we cannot reply */ int sc_receive (xmmsv_t *val, extra_t *extra, sc_description_t *udata) { if (udata->version && xmmsv_dict_get_int (val, "version", &version) && version != udata->version) { ret = xmmsv_new_error ("Wrong version!"); sc_return (extra->msg_id, ret); xmmsv_unref (ret); return 1; } xmmsv_dict_get_string (val, "type", &type); if (strcmp (type, "method-call") == 0) { xmmsv_dict_get_string (val, "method", method); xmmsv_dict_get (val, "args", args); /* Walk through methodlist. Call method when matching. If none, set ret to an errorvalue */ res = sc_return (extra->msg_id, ret); xmmsv_unref (ret); } else (strcmp (type, "broadcast-subscribe") == 0) { /* add msg_id to some list */ } else (strcmp (type, "version")) { /* or other introspection */ res = sc_return_int (extra.msg_id, udata->version); } else { /* Wrong type! Respond with an error */ } return 1; /* Receive more method calls */ } void 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. */ } int sc_on_client_disconnect (xmmsv_t *val, udata) { /* For each msg_id in val["outstanding"], remove from broadcast lists. */ } /***** CLIENT USING SERVICE: *****/ res = 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); |