XMMS2
|
00001 /* XMMS2 - X Music Multiplexer System 00002 * Copyright (C) 2003-2009 XMMS2 Team 00003 * 00004 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!! 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 */ 00016 00017 00018 00019 00020 #ifndef __XMMS_OBJECT_H__ 00021 #define __XMMS_OBJECT_H__ 00022 00023 #include <glib.h> 00024 #include "xmms/xmms_error.h" 00025 #include "xmmsc/xmmsc_idnumbers.h" 00026 #include "xmmsc/xmmsv.h" 00027 #include "xmmsc/xmmsv_coll.h" 00028 00029 #define XMMS_OBJECT_MID 0x00455574 00030 00031 G_BEGIN_DECLS 00032 00033 struct xmms_object_St; 00034 typedef struct xmms_object_St xmms_object_t; 00035 typedef struct xmms_object_cmd_desc_St xmms_object_cmd_desc_t; 00036 00037 typedef void (*xmms_object_destroy_func_t) (xmms_object_t *object); 00038 00039 /** @addtogroup Object 00040 * @{ 00041 */ 00042 struct xmms_object_St { 00043 guint32 id; 00044 GMutex *mutex; 00045 00046 GTree *signals; 00047 GTree *cmds; 00048 00049 gint ref; 00050 xmms_object_destroy_func_t destroy_func; 00051 }; 00052 00053 00054 /* Convenience wrapper to create #xmmsv_t from GLib types. */ 00055 xmmsv_t *xmms_convert_and_kill_list (GList *list); 00056 xmmsv_t *xmms_convert_and_kill_dict (GTree *dict); 00057 xmmsv_t *xmms_convert_and_kill_string (gchar *str); 00058 xmmsv_t *xmms_convert_and_kill_bin (GString *gs); 00059 00060 int xmms_bin_to_gstring (xmmsv_t *value, GString **gs); 00061 int dummy_identity (xmmsv_t *value, xmmsv_t **arg); 00062 gboolean check_string_list (xmmsv_t *list); 00063 00064 00065 /** @} */ 00066 00067 typedef void (*xmms_object_handler_t) (xmms_object_t *object, xmmsv_t *data, gpointer userdata); 00068 00069 #define XMMS_OBJECT_CMD_MAX_ARGS 6 00070 typedef struct { 00071 xmmsv_t *values[XMMS_OBJECT_CMD_MAX_ARGS]; 00072 xmmsv_t *retval; 00073 xmms_error_t error; 00074 } xmms_object_cmd_arg_t; 00075 00076 typedef void (*xmms_object_cmd_func_t) (xmms_object_t *object, xmms_object_cmd_arg_t *arg); 00077 00078 struct xmms_object_cmd_desc_St { 00079 xmms_object_cmd_func_t func; 00080 xmmsv_type_t retval; 00081 xmmsv_type_t args[XMMS_OBJECT_CMD_MAX_ARGS]; 00082 }; 00083 00084 #define XMMS_OBJECT(p) ((xmms_object_t *)p) 00085 #define XMMS_IS_OBJECT(p) (XMMS_OBJECT (p)->id == XMMS_OBJECT_MID) 00086 00087 void xmms_object_cleanup (xmms_object_t *object); 00088 00089 void xmms_object_connect (xmms_object_t *object, guint32 signalid, 00090 xmms_object_handler_t handler, gpointer userdata); 00091 00092 void xmms_object_disconnect (xmms_object_t *object, guint32 signalid, 00093 xmms_object_handler_t handler, gpointer userdata); 00094 00095 void xmms_object_emit (xmms_object_t *object, guint32 signalid, xmmsv_t *data); 00096 00097 void xmms_object_emit_f (xmms_object_t *object, guint32 signalid, 00098 xmmsv_type_t type, ...); 00099 00100 void xmms_object_cmd_arg_init (xmms_object_cmd_arg_t *arg); 00101 00102 void xmms_object_cmd_add (xmms_object_t *object, guint cmdid, const xmms_object_cmd_desc_t *desc); 00103 00104 void xmms_object_cmd_call (xmms_object_t *object, guint cmdid, xmms_object_cmd_arg_t *arg); 00105 00106 /* Some minor macro-magic. XMMS_CMD_DEFINE and XMMS_CMD_FUNC 00107 * are the only ones to be used directly */ 00108 00109 #define __XMMS_CMD_INIT_ARG_FULL(argn, argtypecode, extract_func) \ 00110 argtypecode argval##argn; \ 00111 g_return_if_fail (extract_func (arg->values[argn], &argval##argn)); 00112 00113 #define __XMMS_CMD_INIT_ARG(argn, argtype, argtypecode) \ 00114 __XMMS_CMD_INIT_ARG_FULL(argn, argtypecode, xmmsv_get_##argtype) 00115 00116 #define __XMMS_CMD_INIT_ARG_NONE(a) 00117 #define __XMMS_CMD_INIT_ARG_STRING(a) __XMMS_CMD_INIT_ARG(a, string, const gchar *) 00118 #define __XMMS_CMD_INIT_ARG_INT32(a) __XMMS_CMD_INIT_ARG(a, int, gint) 00119 #define __XMMS_CMD_INIT_ARG_COLL(a) __XMMS_CMD_INIT_ARG(a, coll, xmmsv_coll_t *) 00120 #define __XMMS_CMD_INIT_ARG_BIN(a) __XMMS_CMD_INIT_ARG_FULL(a, GString *, xmms_bin_to_gstring) 00121 #define __XMMS_CMD_INIT_ARG_LIST(a) __XMMS_CMD_INIT_ARG_FULL(a, xmmsv_t *, dummy_identity) 00122 #define __XMMS_CMD_INIT_ARG_DICT(a) __XMMS_CMD_INIT_ARG_FULL(a, xmmsv_t *, dummy_identity) 00123 00124 #define __XMMS_CMD_PRINT_ARG_NONE(a) 00125 #define __XMMS_CMD_PRINT_ARG_STRING(a) , argval##a 00126 #define __XMMS_CMD_PRINT_ARG_INT32(a) , argval##a 00127 #define __XMMS_CMD_PRINT_ARG_COLL(a) , argval##a 00128 #define __XMMS_CMD_PRINT_ARG_BIN(a) , argval##a 00129 #define __XMMS_CMD_PRINT_ARG_LIST(a) , argval##a 00130 #define __XMMS_CMD_PRINT_ARG_DICT(a) , argval##a 00131 00132 #define __XMMS_CMD_DO_RETVAL_NONE() arg->retval = xmmsv_new_none(); 00133 #define __XMMS_CMD_DO_RETVAL_DICT() arg->retval = xmms_convert_and_kill_dict 00134 #define __XMMS_CMD_DO_RETVAL_INT32() arg->retval = xmmsv_new_int 00135 #define __XMMS_CMD_DO_RETVAL_LIST() arg->retval = xmms_convert_and_kill_list 00136 #define __XMMS_CMD_DO_RETVAL_STRING() arg->retval = xmms_convert_and_kill_string 00137 #define __XMMS_CMD_DO_RETVAL_COLL() arg->retval = xmmsv_new_coll 00138 #define __XMMS_CMD_DO_RETVAL_BIN() arg->retval = 00139 00140 #define __XMMS_CMD_DO_RETTYPE_NONE() void 00141 #define __XMMS_CMD_DO_RETTYPE_STRING() char * 00142 #define __XMMS_CMD_DO_RETTYPE_INT32() gint32 00143 #define __XMMS_CMD_DO_RETTYPE_COLL(a) xmmsv_coll_t * 00144 #define __XMMS_CMD_DO_RETTYPE_BIN(a) xmmsv_t * 00145 #define __XMMS_CMD_DO_RETTYPE_LIST(a) GList * 00146 #define __XMMS_CMD_DO_RETTYPE_DICT(a) GTree * 00147 00148 #define __XMMS_CMD_DO_ARGTYPE_NONE 00149 #define __XMMS_CMD_DO_ARGTYPE_STRING , const char * 00150 #define __XMMS_CMD_DO_ARGTYPE_INT32 , gint32 00151 #define __XMMS_CMD_DO_ARGTYPE_COLL , xmmsv_coll_t * 00152 #define __XMMS_CMD_DO_ARGTYPE_BIN , GString * 00153 #define __XMMS_CMD_DO_ARGTYPE_LIST , xmmsv_t * 00154 #define __XMMS_CMD_DO_ARGTYPE_DICT , xmmsv_t * 00155 00156 00157 #define XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5, argtype6) \ 00158 \ 00159 static __XMMS_CMD_DO_RETTYPE_##_rettype() realfunc (argtype0 __XMMS_CMD_DO_ARGTYPE_##argtype1 __XMMS_CMD_DO_ARGTYPE_##argtype2 __XMMS_CMD_DO_ARGTYPE_##argtype3 __XMMS_CMD_DO_ARGTYPE_##argtype4 __XMMS_CMD_DO_ARGTYPE_##argtype5 __XMMS_CMD_DO_ARGTYPE_##argtype6, xmms_error_t *); \ 00160 \ 00161 static void \ 00162 __int_xmms_cmd_##cmdid (xmms_object_t *object, xmms_object_cmd_arg_t *arg) \ 00163 { \ 00164 g_return_if_fail (XMMS_IS_OBJECT (object)); \ 00165 __XMMS_CMD_INIT_ARG_##argtype1 (0) \ 00166 __XMMS_CMD_INIT_ARG_##argtype2 (1) \ 00167 __XMMS_CMD_INIT_ARG_##argtype3 (2) \ 00168 __XMMS_CMD_INIT_ARG_##argtype4 (3) \ 00169 __XMMS_CMD_INIT_ARG_##argtype5 (4) \ 00170 __XMMS_CMD_INIT_ARG_##argtype6 (5) \ 00171 __XMMS_CMD_DO_RETVAL_##_rettype() (realfunc ((argtype0)object __XMMS_CMD_PRINT_ARG_##argtype1(0) __XMMS_CMD_PRINT_ARG_##argtype2(1) __XMMS_CMD_PRINT_ARG_##argtype3(2) __XMMS_CMD_PRINT_ARG_##argtype4(3) __XMMS_CMD_PRINT_ARG_##argtype5(4) __XMMS_CMD_PRINT_ARG_##argtype6(5), &arg->error)); \ 00172 } \ 00173 static const xmms_object_cmd_desc_t __int_xmms_cmd_desc_##cmdid = { __int_xmms_cmd_##cmdid, XMMSV_TYPE_##_rettype, {XMMSV_TYPE_##argtype1, XMMSV_TYPE_##argtype2, XMMSV_TYPE_##argtype3, XMMSV_TYPE_##argtype4, XMMSV_TYPE_##argtype5, XMMSV_TYPE_##argtype6} } 00174 00175 00176 #define XMMS_CMD_DEFINE(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, NONE, NONE, NONE, NONE) 00177 #define XMMS_CMD_DEFINE3(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, NONE, NONE, NONE) 00178 #define XMMS_CMD_DEFINE4(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, NONE, NONE) 00179 #define XMMS_CMD_DEFINE5(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5) XMMS_CMD_DEFINE6(cmdid, realfunc, argtype0, _rettype, argtype1, argtype2, argtype3, argtype4, argtype5, NONE) 00180 00181 #define XMMS_CMD_FUNC(cmdid) &__int_xmms_cmd_desc_##cmdid 00182 00183 00184 void __int_xmms_object_unref (xmms_object_t *object); 00185 xmms_object_t *__int_xmms_object_new (gint size, xmms_object_destroy_func_t destfunc); 00186 00187 #define xmms_object_ref(obj) do { \ 00188 if (obj && XMMS_IS_OBJECT (obj)) { \ 00189 g_atomic_int_inc (&(XMMS_OBJECT (obj)->ref)); \ 00190 } \ 00191 } while (0) 00192 00193 #define xmms_object_unref(obj) do { \ 00194 if (obj && XMMS_IS_OBJECT (obj)) { \ 00195 __int_xmms_object_unref (XMMS_OBJECT (obj)); \ 00196 } \ 00197 } while (0) 00198 00199 #define xmms_object_new(objtype,destroyfunc) (objtype *) __int_xmms_object_new (sizeof (objtype), destroyfunc) 00200 00201 G_END_DECLS 00202 00203 #endif /* __XMMS_OBJECT_H__ */