OpenSync 0.22

osengine/osengine_flags.c

00001 /*
00002  * libosengine - A synchronization engine for the opensync framework
00003  * Copyright (C) 2004-2005  Armin Bauer <armin.bauer@opensync.org>
00004  * 
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  * 
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00018  * 
00019  */
00020  
00021 #include "engine.h"
00022 #include "engine_internals.h"
00023 
00024 OSyncFlag *osync_flag_new(OSyncFlag *parent)
00025 {
00026         OSyncFlag *flag = g_malloc0(sizeof(OSyncFlag));
00027         flag->is_set = FALSE;
00028         if (parent) {
00029                 flag->comb_flag = parent;
00030                 parent->num_not_set++;
00031                 osync_flag_calculate_comb(parent);
00032         }
00033         return flag;
00034 }
00035 
00036 void osync_flag_free(OSyncFlag *flag)
00037 {
00038         g_free(flag);
00039 }
00040 
00041 OSyncFlag *osync_comb_flag_new(osync_bool any, osync_bool default_val)
00042 {
00043         OSyncFlag *flag = osync_flag_new(NULL);
00044         flag->is_comb = TRUE;
00045         flag->is_any = any;
00046         flag->default_val = default_val;
00047         flag->is_set = default_val;
00048         return flag;
00049 }
00050 
00051 void osync_flag_attach(OSyncFlag *flag, OSyncFlag *target)
00052 {
00053         if (flag->comb_flag)
00054                 return;
00055         g_assert(target->is_comb);
00056         flag->comb_flag = target;
00057         if (flag->is_set) {
00058                 target->num_set++;
00059         } else {
00060                 target->num_not_set++;
00061         }
00062         osync_flag_calculate_comb(target);
00063 }
00064 
00065 osync_bool osync_flag_is_attached(OSyncFlag *flag)
00066 {
00067         if (flag->comb_flag)
00068                 return TRUE;
00069         return FALSE;
00070 }
00071 
00072 void osync_flag_detach(OSyncFlag *flag)
00073 {
00074         OSyncFlag *target = flag->comb_flag;
00075         if (!target)
00076                 return;
00077         if (flag->is_set) {
00078                 target->num_set--;
00079         } else {
00080                 target->num_not_set--;
00081         }
00082         flag->comb_flag = NULL;
00083         osync_flag_calculate_comb(target);
00084 }
00085 
00086 void osync_flag_set_pos_trigger(OSyncFlag *flag, OSyncFlagTriggerFunc func, void *data1, void *data2)
00087 {
00088         flag->pos_trigger_func = func;
00089         flag->pos_user_data1 = data1;
00090         flag->pos_user_data2 = data2;
00091 }
00092 
00093 void osync_flag_set_neg_trigger(OSyncFlag *flag, OSyncFlagTriggerFunc func, void *data1, void *data2)
00094 {
00095         flag->neg_trigger_func = func;
00096         flag->neg_user_data1 = data1;
00097         flag->neg_user_data2 = data2;
00098 }
00099 
00100 void osync_flag_calculate_comb(OSyncFlag *flag)
00101 {
00102         if (!flag->is_comb)
00103                 return;
00104         
00105         if (!flag->num_not_set && !flag->num_set) {
00106                 if (flag->default_val)
00107                         osync_flag_set(flag);
00108                 else
00109                         osync_flag_unset(flag);
00110                 return;
00111         }
00112         
00113         if (!flag->is_any) {
00114                 if (!flag->num_not_set && flag->num_set) {
00115                         osync_flag_set(flag);
00116                 } else {
00117                         osync_flag_unset(flag);
00118                 }
00119         } else {
00120                 if (flag->num_set) {
00121                         osync_flag_set(flag);
00122                 } else {
00123                         osync_flag_unset(flag);
00124                 }
00125         }
00126 }
00127 
00128 osync_bool osync_flag_is_set(OSyncFlag *flag)
00129 {
00130         if (flag->is_set == TRUE && flag->is_changing == FALSE)
00131                 return TRUE;
00132         return FALSE;
00133 }
00134 
00135 osync_bool osync_flag_is_not_set(OSyncFlag *flag)
00136 {
00137         if (flag->is_set == FALSE && flag->is_changing == FALSE)
00138                 return TRUE;
00139         return FALSE;
00140 }
00141 
00142 void osync_comb_flag_update(OSyncFlag *combflag, OSyncFlag *flag, osync_bool prev_state)
00143 {
00144         if (prev_state == flag->is_set)
00145                 return;
00146         if (flag->is_set) {
00147                 combflag->num_not_set--;
00148                 combflag->num_set++;
00149         } else {
00150                 combflag->num_not_set++;
00151                 combflag->num_set--;
00152         }
00153 }
00154 
00155 void osync_flag_changing(OSyncFlag *flag)
00156 {
00157         flag->is_changing = TRUE;
00158 }
00159 
00160 void osync_flag_cancel(OSyncFlag *flag)
00161 {
00162         flag->is_changing = FALSE;
00163 }
00164 
00165 void osync_flag_unset(OSyncFlag *flag)
00166 {
00167         osync_bool oldstate = flag->is_set;
00168         flag->is_set = FALSE;
00169         flag->is_changing = FALSE;
00170         osync_flag_calc_trigger(flag, oldstate);
00171         if (flag->comb_flag) {
00172                 osync_comb_flag_update(flag->comb_flag, flag, oldstate);
00173                 osync_flag_calculate_comb(flag->comb_flag);
00174         }
00175 }
00176 
00177 void osync_flag_set(OSyncFlag *flag)
00178 {
00179         osync_bool oldstate = flag->is_set;
00180         flag->is_set = TRUE;
00181         flag->is_changing = FALSE;
00182         osync_flag_calc_trigger(flag, oldstate);
00183         if (flag->comb_flag) {
00184                 osync_comb_flag_update(flag->comb_flag, flag, oldstate);
00185                 osync_flag_calculate_comb(flag->comb_flag);
00186         }
00187 }
00188 
00189 void osync_flag_set_state(OSyncFlag *flag, osync_bool state)
00190 {
00191         osync_bool oldstate = flag->is_set;
00192         flag->is_set = state;
00193         flag->is_changing = FALSE;
00194         if (flag->comb_flag) {
00195                 osync_comb_flag_update(flag->comb_flag, flag, oldstate);
00196         }
00197         if (flag->is_comb) {
00198                 //flag->num_not_set = 0;
00199                 //flag->num_set = 0;
00200         }
00201 }
00202 
00203 osync_bool osync_flag_get_state(OSyncFlag *flag)
00204 {
00205         return flag->is_set;
00206 }
00207 
00208 void osync_flag_calc_trigger(OSyncFlag *flag, osync_bool oldstate)
00209 {
00210         if (flag->is_set != oldstate) {
00211                 if (flag->is_set == TRUE) {
00212                         if (flag->pos_trigger_func) {
00213                                 flag->pos_trigger_func(flag->pos_user_data1, flag->pos_user_data2);
00214                         }
00215                 } else {
00216                         if (flag->neg_trigger_func) {
00217                                 flag->neg_trigger_func(flag->neg_user_data1, flag->neg_user_data2);
00218                         }
00219                 }
00220         }
00221 }