00001
00002
00003
00004
00005
00006
00007
00008
#include "uniconfroot.h"
00009
00010
00011
00012
00013 void UniConfRoot::add_callback(
void *cookie,
const UniConfKey &key,
00014
const UniConfCallback &callback,
bool recurse)
00015 {
00016
UniWatchInfo *w =
new UniWatchInfo(cookie, recurse, callback);
00017
00018
UniWatchInfoTree *node = &watchroot;
00019
UniConfKey::Iter i(key);
00020
for (i.
rewind(); i.
next(); )
00021 {
00022
UniWatchInfoTree *prev = node;
00023 node = node->
findchild(i());
00024
if (!node)
00025 node =
new UniWatchInfoTree(prev, i());
00026 }
00027 node->
watches.append(w,
true);
00028 }
00029
00030
00031 void UniConfRoot::del_callback(
void *cookie,
const UniConfKey &key,
00032
bool recurse)
00033 {
00034
UniWatchInfoTree *node = watchroot.
find(key);
00035
if (node)
00036 {
00037 UniWatchInfoList::Iter i(node->
watches);
00038
for (i.rewind(); i.next(); )
00039 {
00040
00041
if (i->cookie == cookie && i->recurse == recurse)
00042 {
00043 i.xunlink();
00044
break;
00045 }
00046 }
00047
00048 prune(node);
00049 }
00050 }
00051
00052
00053 void UniConfRoot::add_setbool(
const UniConfKey &key,
bool *flag,
bool recurse)
00054 {
00055
add_callback(flag, key,
00056
WvBoundCallback<UniConfCallback, bool *>
00057 (&
UniConfRoot::setbool_callback, flag),
00058 recurse);
00059 }
00060
00061
00062 void UniConfRoot::del_setbool(
const UniConfKey &key,
bool *flag,
bool recurse)
00063 {
00064
del_callback(flag, key, recurse);
00065 }
00066
00067
00068
void UniConfRoot::check(
UniWatchInfoTree *node,
00069
const UniConfKey &key,
int segleft)
00070 {
00071 UniWatchInfoList::Iter i(node->
watches);
00072
for (i.rewind(); i.next(); )
00073 {
00074
if (!i->recursive() && segleft > 0)
00075
continue;
00076
00077 i->notify(UniConf(
this, key.
removelast(segleft)), key.
last(segleft));
00078 }
00079 }
00080
00081
00082
void UniConfRoot::deletioncheck(
UniWatchInfoTree *node,
const UniConfKey &key)
00083 {
00084 UniWatchInfoTree::Iter i(*node);
00085
for (i.rewind(); i.next(); )
00086 {
00087
UniWatchInfoTree *w = i.ptr();
00088
UniConfKey subkey(key, w->
key());
00089
00090
00091
check(w, subkey, 0);
00092 deletioncheck(w, subkey);
00093 }
00094 }
00095
00096
00097
void UniConfRoot::prune(
UniWatchInfoTree *node)
00098 {
00099
while (node != & watchroot && ! node->
isessential())
00100 {
00101
UniWatchInfoTree *next = node->
parent();
00102
delete node;
00103 node = next;
00104 }
00105 }
00106
00107
00108
void UniConfRoot::gen_callback(
const UniConfKey &key,
WvStringParm value,
00109
void *userdata)
00110 {
00111 hold_delta();
00112
UniWatchInfoTree *node = & watchroot;
00113
int segs = key.
numsegments();
00114
00115
00116
check(node, key, segs);
00117
00118
00119
for (
int s = 0; s < segs; )
00120 {
00121 node = node->
findchild(key.
segment(s));
00122 s++;
00123
if (!node)
00124
goto done;
00125
check(node, key, segs - s);
00126 }
00127
00128
00129
if (value.
isnull())
00130 deletioncheck(node, key);
00131
00132 done:
00133 unhold_delta();
00134 }