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 }