index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000005.html
glib
&raquo
dir_000006.html
examples
&raquo
dir_000011.html
statemachine
statemachine.c
00001
#include <stdio.h>
00002
#include <stdlib.h>
00003
#include "statemachine.h"
00004
00005
static
void
clear_pending_tasks (
structSMObject.html
SMObject
*object);
00006
static
void
state_change (
structSMObject.html
SMObject
*object, SMObjectState new_state);
00007
static
void
sm_object_set_property (GObject *object,
00008                                     guint prop_id,
00009
const
GValue *value,
00010                                     GParamSpec *pspec);
00011
static
void
sm_object_get_property (GObject *object,
00012                                     guint prop_id,
00013                                     GValue *value,
00014                                     GParamSpec *pspec);
00015
enum
00016 {
00017   PROP_0,
00018   PROP_NAME,
00019 };
00020
00021
enum
00022 {
00023   STATE_CHANGED,
00024   ACQUISITION_FAILED,
00025   ACQUISITION_PROGRESS,
00026   LAST_SIGNAL
00027 };
00028
00029
static
guint sm_object_signals[LAST_SIGNAL] = { 0 };
00030
00031 G_DEFINE_TYPE(
structSMObject.html
SMObject
, sm_object, G_TYPE_OBJECT)
00032
00033 static
void
00034 sm_object_init (
structSMObject.html
SMObject
*obj)
00035 {
00036   obj->state = SM_OBJECT_STATE_SHUTDOWN;
00037 }
00038
00039
static
void
00040 sm_object_class_init (
structSMObjectClass.html
SMObjectClass
*klass)
00041 {
00042   GObjectClass *object_class;
00043
00044   object_class = G_OBJECT_CLASS (klass);
00045
00046   object_class->set_property = sm_object_set_property;
00047   object_class->get_property = sm_object_get_property;
00048
00049   g_object_class_install_property (object_class,
00050                                    PROP_NAME,
00051                                    g_param_spec_string (
"name"
,
00052
"name"
,
00053
"name"
,
00054
group__DBusMacros.html#ga4
NULL
,
00055                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
00056   sm_object_signals[STATE_CHANGED] =
00057     g_signal_new (
"state-changed"
,
00058                   G_OBJECT_CLASS_TYPE (klass),
00059                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00060                   0,
00061
group__DBusMacros.html#ga4
NULL
,
group__DBusMacros.html#ga4
NULL
,
00062                   g_cclosure_marshal_VOID__STRING,
00063                   G_TYPE_NONE, 1, G_TYPE_STRING);
00064   sm_object_signals[ACQUISITION_PROGRESS] =
00065     g_signal_new (
"acquisition-progress"
,
00066                   G_OBJECT_CLASS_TYPE (klass),
00067                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00068                   0,
00069
group__DBusMacros.html#ga4
NULL
,
group__DBusMacros.html#ga4
NULL
,
00070                   g_cclosure_marshal_VOID__DOUBLE,
00071                   G_TYPE_NONE, 1, G_TYPE_DOUBLE);
00072   sm_object_signals[ACQUISITION_FAILED] =
00073     g_signal_new (
"acquisition-failed"
,
00074                   G_OBJECT_CLASS_TYPE (klass),
00075                   G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
00076                   0,
00077
group__DBusMacros.html#ga4
NULL
,
group__DBusMacros.html#ga4
NULL
,
00078                   g_cclosure_marshal_VOID__VOID,
00079                   G_TYPE_NONE, 0);
00080 }
00081
00082
/* This should really be standard. */
00083
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
00084
00085 GQuark
00086 sm_error_quark (
void
)
00087 {
00088
static
GQuark ret = 0;
00089
if
(!ret)
00090     ret = g_quark_from_static_string (
"SMObjectErrorQuark"
);
00091
return
ret;
00092 }
00093
00094 GType
00095 sm_object_state_get_type (
void
)
00096 {
00097
static
GType etype = 0;
00098
00099
if
(etype == 0)
00100     {
00101
static
const
GEnumValue values[] =
00102         {
00103
00104           ENUM_ENTRY (SM_OBJECT_STATE_SHUTDOWN,
"Shutdown"
),
00105           ENUM_ENTRY (SM_OBJECT_STATE_INITIALIZED,
"Loading"
),
00106           ENUM_ENTRY (SM_OBJECT_STATE_ACQUIRED,
"Acquired"
),
00107           ENUM_ENTRY (SM_OBJECT_STATE_OPERATING,
"Operating"
),
00108           { 0, 0, 0 }
00109         };
00110
00111       etype = g_enum_register_static (
"SMObjectState"
, values);
00112     }
00113
00114
return
etype;
00115 }
00116
00117 GType
00118 sm_error_get_type (
void
)
00119 {
00120
static
GType etype = 0;
00121
00122
if
(etype == 0)
00123     {
00124
static
const
GEnumValue values[] =
00125         {
00126
00127           ENUM_ENTRY (SM_ERROR_INVALID_STATE,
"InvalidState"
),
00128           ENUM_ENTRY (SM_ERROR_NAME_IN_USE,
"NameInUse"
),
00129           { 0, 0, 0 }
00130         };
00131
00132       g_assert (SM_NUM_ERRORS == G_N_ELEMENTS (values) - 1);
00133
00134       etype = g_enum_register_static (
"SMError"
, values);
00135     }
00136
00137
return
etype;
00138 }
00139
00140
static
void
00141 sm_object_set_property (GObject *object,
00142                         guint prop_id,
00143
const
GValue *value,
00144                         GParamSpec *pspec)
00145 {
00146
structSMObject.html
SMObject
*sm = SM_OBJECT (object);
00147
00148
switch
(prop_id)
00149     {
00150
case
PROP_NAME:
00151       sm->
structSMObject.html#o1
name
= g_strdup (g_value_get_string (value));
00152
break
;
00153
default
:
00154       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00155
break
;
00156     }
00157 }
00158
00159
static
void
00160 sm_object_get_property (GObject *object,
00161                         guint prop_id,
00162                         GValue *value,
00163                         GParamSpec *pspec)
00164 {
00165
structSMObject.html
SMObject
*sm= SM_OBJECT (object);
00166
00167
switch
(prop_id)
00168     {
00169
case
PROP_NAME:
00170       g_value_set_string (value, sm->
structSMObject.html#o1
name
);
00171
break
;
00172
default
:
00173       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00174
break
;
00175     }
00176 }
00177
00178
static
const
char
*
00179 state_to_string (SMObjectState state)
00180 {
00181   GEnumValue *value;
00182   GEnumClass *prop_class;
00183
const
char
*ret;
00184
00185   prop_class = g_type_class_ref (SM_TYPE_OBJECT_STATE);
00186   value = g_enum_get_value (prop_class, state);
00187   ret = value->value_nick;
00188
00189   g_type_class_unref (prop_class);
00190
return
ret;
00191 }
00192
00193
static
void
00194 queue_task (
structSMObject.html
SMObject
*object, guint delay, GSourceFunc func)
00195 {
00196   guint id;
00197
id
= g_timeout_add (delay, func, object);
00198   object->
structSMObject.html#o4
pending_tasks
= g_slist_prepend (object->
structSMObject.html#o4
pending_tasks
, GUINT_TO_POINTER (
id
));
00199 }
00200
00201
static
gboolean
00202 idle_state_change (gpointer data)
00203 {
00204
structSMObject.html
SMObject
*object = data;
00205
00206   g_print (
"doing idle state change for %s to %s\n"
,
00207            object->
structSMObject.html#o1
name
, state_to_string (object->
structSMObject.html#o5
requested_state
));
00208   state_change (object, object->
structSMObject.html#o5
requested_state
);
00209
return
group__DBusMacros.html#ga3
FALSE
;
00210 }
00211
00212
static
gboolean
00213 idle_further_acquire (gpointer data)
00214 {
00215
structSMObject.html
SMObject
*object = data;
00216
00217   g_print (
"doing idle acquisition for machine %s\n"
, object->
structSMObject.html#o1
name
);
00218   object->
structSMObject.html#o3
acquisition_progress
+= g_random_double_range (0.20, 0.7);
00219
if
(object->
structSMObject.html#o3
acquisition_progress
> 1.0)
00220     {
00221       object->
structSMObject.html#o3
acquisition_progress
= 1.0;
00222
return
group__DBusMacros.html#ga3
FALSE
;
00223     }
00224
else
00225     {
00226       g_signal_emit (object, sm_object_signals[ACQUISITION_PROGRESS], 0, object->
structSMObject.html#o3
acquisition_progress
);
00227
return
group__DBusMacros.html#ga2
TRUE
;
00228     }
00229 }
00230
00231
static
void
00232 clear_pending_tasks (
structSMObject.html
SMObject
*object)
00233 {
00234   GSList *tmp;
00235
for
(tmp = object->
structSMObject.html#o4
pending_tasks
; tmp; tmp = tmp->next)
00236     g_source_remove (GPOINTER_TO_UINT (tmp->data));
00237   g_slist_free (object->
structSMObject.html#o4
pending_tasks
);
00238   object->
structSMObject.html#o4
pending_tasks
=
group__DBusMacros.html#ga4
NULL
;
00239 }
00240
00241
static
void
00242 state_change (
structSMObject.html
SMObject
*object, SMObjectState new_state)
00243 {
00244   g_signal_emit (object, sm_object_signals[STATE_CHANGED], 0,
00245                  state_to_string (new_state));
00246
00247   clear_pending_tasks (object);
00248
00249
if
(new_state == SM_OBJECT_STATE_ACQUIRED)
00250     {
00251       object->
structSMObject.html#o3
acquisition_progress
= 0.0;
00252       queue_task (object, 1000, idle_further_acquire);
00253     }
00254
else
if
(new_state == SM_OBJECT_STATE_INITIALIZED)
00255     {
00256
if
(g_random_int_range (0, 2) == 0)
00257         {
00258           object->
structSMObject.html#o5
requested_state
= SM_OBJECT_STATE_ACQUIRED;
00259           queue_task (object, 3000, idle_state_change);
00260         }
00261     }
00262
00263   object->
structSMObject.html#o2
state
= new_state;
00264 }
00265
00266 gboolean
00267 sm_object_get_info (
structSMObject.html
SMObject
*object,
char
**name,
char
**state, GError **error)
00268 {
00269   *name= g_strdup (object->
structSMObject.html#o1
name
);
00270   *state = g_strdup (state_to_string (object->
structSMObject.html#o2
state
));
00271
return
group__DBusMacros.html#ga2
TRUE
;
00272 }
00273
00274 gboolean
00275 sm_object_start (
structSMObject.html
SMObject
*object, GError **error)
00276 {
00277
if
(object->
structSMObject.html#o2
state
!= SM_OBJECT_STATE_SHUTDOWN)
00278     {
00279       g_set_error (error,
00280                    SM_ERROR,
00281                    SM_ERROR_INVALID_STATE,
00282
"%s"
,
00283
"Can't start from non-shutdown state"
);
00284
return
group__DBusMacros.html#ga3
FALSE
;
00285     }
00286   state_change (object, SM_OBJECT_STATE_INITIALIZED);
00287
return
group__DBusMacros.html#ga2
TRUE
;
00288 }
00289
00290 gboolean
00291 sm_object_shutdown (
structSMObject.html
SMObject
*object, GError **error)
00292 {
00293
if
(object->
structSMObject.html#o2
state
== SM_OBJECT_STATE_SHUTDOWN)
00294     {
00295       g_set_error (error,
00296                    SM_ERROR,
00297                    SM_ERROR_INVALID_STATE,
00298
"%s"
,
00299
"Can't shutdown from shutdown state"
);
00300
return
group__DBusMacros.html#ga3
FALSE
;
00301     }
00302   state_change (object, SM_OBJECT_STATE_SHUTDOWN);
00303
return
group__DBusMacros.html#ga2
TRUE
;
00304 }
00305
00306 gboolean
00307 sm_object_reinitialize (
structSMObject.html
SMObject
*object, GError **error)
00308 {
00309
if
(object->
structSMObject.html#o2
state
!= SM_OBJECT_STATE_ACQUIRED
00310       && object->
structSMObject.html#o2
state
!= SM_OBJECT_STATE_OPERATING)
00311     {
00312       g_set_error (error,
00313                    SM_ERROR,
00314                    SM_ERROR_INVALID_STATE,
00315
"Can't reinitialize from state %d"
,
00316                    object->
structSMObject.html#o2
state
);
00317
return
group__DBusMacros.html#ga3
FALSE
;
00318     }
00319   state_change (object, SM_OBJECT_STATE_INITIALIZED);
00320
return
group__DBusMacros.html#ga2
TRUE
;
00321 }
00322
00323 gboolean
00324 sm_object_reacquire (
structSMObject.html
SMObject
*object, GError **error)
00325 {
00326
if
(object->
structSMObject.html#o2
state
== SM_OBJECT_STATE_ACQUIRED)
00327     {
00328       g_set_error (error,
00329                    SM_ERROR,
00330                    SM_ERROR_INVALID_STATE,
00331
"Can't reacquire from state %d"
,
00332                    object->
structSMObject.html#o2
state
);
00333
return
group__DBusMacros.html#ga3
FALSE
;
00334     }
00335   state_change (object, SM_OBJECT_STATE_ACQUIRED);
00336
return
group__DBusMacros.html#ga2
TRUE
;
00337 }
00338
00339 gboolean
00340 sm_object_get_acquiring_progress (
structSMObject.html
SMObject
*object, gdouble *out, GError **error)
00341 {
00342
if
(object->
structSMObject.html#o2
state
!= SM_OBJECT_STATE_ACQUIRED)
00343     {
00344       g_set_error (error,
00345                    SM_ERROR,
00346                    SM_ERROR_INVALID_STATE,
00347
"Can't get progress from state %d"
,
00348                    object->
structSMObject.html#o2
state
);
00349
return
group__DBusMacros.html#ga3
FALSE
;
00350     }
00351   *out = object->
structSMObject.html#o3
acquisition_progress
;
00352
return
group__DBusMacros.html#ga2
TRUE
;
00353 }
Generated on Tue Sep 13 01:28:08 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
