Advertisement
Guest User

Very first sc sketch

a guest
Jun 22nd, 2011
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.77 KB | None | 0 0
  1. /* Service client sketch using libxmmsclient-sc.
  2.  * Queries the server for all available clients and prints their names.
  3.  *
  4.  * Illustrates some of the concepts discussed in the comments of my proposal
  5.  * as well as a few other ideas of my own.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <assert.h>
  10. #include <string.h>
  11.  
  12. #include <xmmsclient/xmmsclient.h>
  13.  
  14. /* Header for Service Clients
  15.  * Since libxmmsclient-sc and libxmmsclient would be so closely
  16.  * related, it might make more sense to implement service client
  17.  * functionality directly in the latter.
  18.  */
  19. #include <xmmsclient/xmmsclient-sc.h>
  20.  
  21. /* Metadata for this client */
  22. static const char *name = "scsketch";
  23. static int id;
  24.  
  25. static void
  26. print_clients (xmmsc_connection_t *conn)
  27. {
  28.     int client_id;
  29.     char *client_name;
  30.     xmmsc_result_t *clients_res, *name_res;
  31.     xmmsv_t *connected_clients, *client_list_entry;
  32.     xmmsv_list_iter_t *it;
  33.     xmmsv_t *client_name_v;
  34.  
  35.     /* This lists all clients that also registered for messages using
  36.      * xmmsc_sc_register.
  37.      * This information can be kept by the server, so this doesn't actually
  38.      * involve conversation between clients.
  39.      */
  40.     clients_res = xmmsc_sc_list_clients (conn);
  41.     xmmsc_result_wait (clients_res);
  42.  
  43.     /* The return value could be a list of ids. */
  44.     connected_clients = xmmsc_result_get_value (clients_res);
  45.  
  46.     /* So we can loop through the list and query for client names. */
  47.     xmmsv_get_list_iter (connected_clients, &it);
  48.     while (xmmsv_list_iter_valid (it)) {
  49.         xmmsv_list_iter_entry (it, &client_list_entry);
  50.         xmmsv_get_int (client_list_entry, &client_id);
  51.  
  52.         /* This illustrates an introspection call for libxmmsclient-sc.
  53.          * The call to xmmsc_sc_get_name results in a message being sent
  54.          * to the queried client (identified by client_id) via
  55.          * xmmsc_broadcast_client_to_client_message.
  56.          * This broadcast reaches the callback set up by libxmmsclient-sc
  57.          * on the other client, which answers with its name.
  58.          * All other clients get the message as well, since this is a
  59.          * broadcast. However, their libxmmsclient-sc callback will simply
  60.          * fail to match their id with the destiny id in the message and
  61.          * ignore the broadcast.
  62.          */
  63.         name_res = xmmsc_sc_get_name (connection, client_id);
  64.         xmmsc_result_wait (name_res);
  65.  
  66.         /* Each message is identified by a random message id generated by
  67.          * the sender and passed along by the server to the receiver.
  68.          * The sender id and the random message id, thus, uniquely
  69.          * identify a message in the recipient side.
  70.          * The answer is expected to contain the same message id.
  71.          */
  72.  
  73.         client_name_v = xmmsc_result_get_value (name_res);
  74.         xmmsv_get_string (client_name_v, &client_name);
  75.  
  76.         printf ("%s", client_name);
  77.  
  78.         /* The client itself is listed too.
  79.          * Since there may be other clients with the same name, an id
  80.          * match implies name match, but not the other way around.
  81.          */
  82.         if (client_id == id) {
  83.             assert (!strcmp (name, client_name));
  84.             printf (" (hey, that's me!)");
  85.         }
  86.  
  87.         printf ("\n");
  88.  
  89.         xmmsc_result_unref (name_res);
  90.         xmmsv_list_iter_next (it);
  91.     }
  92.  
  93.     xmmsc_result_unref (clients_res);
  94.     return;
  95. }
  96.  
  97. int
  98. main (int argc, char **argv)
  99. {
  100.     xmmsc_connection_t *connection;
  101.     xmmsc_result_t *res;
  102.     xmmsv_t *my_id;
  103.  
  104.     /* Connect as usual.
  105.      * Error checking omitted for this example
  106.      */
  107.     connection = xmmsc_init (name);
  108.     xmmsc_connect (connection, getenv ("XMMS_PATH"));
  109.  
  110.     /* Register for communication with other clients.
  111.      * Under the hood, libxmmsclient-sc sets up its callback for
  112.      * xmmsc_broadcast_client_to_client_message, which is responsible both
  113.      * for answering to introspection calls (such as get_version) and for
  114.      * forwarding method calls to the corresponding functions provided by
  115.      * the client.
  116.      */
  117.     res = xmmsc_sc_register (connection);
  118.     xmmsc_result_wait (res);
  119.  
  120.     /* xmmsc_sc_register could either return NONE or the id assigned to
  121.      * this client by the server.
  122.      */
  123.     my_id = xmmsc_result_get_value (res);
  124.  
  125.     /* As for the other metadata (such as version or category), they could
  126.      * be registered separately and kept by libxmmsclient-sc, using
  127.      * functions like xmmsc_sc_set_version. Using this approach,
  128.      * introspection calls could be answered directly by libxmmsclient-sc.
  129.      * An alternative would be for the client to register accessor methods,
  130.      * so that libxmmsclient-sc can dispatch introspection calls to them.
  131.      * Either way, it should probably be possible for a client to not
  132.      * register any metadata other than its name, since it doesn't make
  133.      * sense for a client that doesn't offer services (such as this one)
  134.      * to register them.
  135.      */
  136.     xmmsv_get_int (my_id, &id);
  137.     xmmsc_result_unref (res);
  138.  
  139.     /* Print the names of all connected clients. */
  140.     print_names (connection);
  141.  
  142.     xmmsc_unref (connection);
  143.  
  144.     return EXIT_SUCCESS;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement