Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

uniconfroot.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * Defines the root management class for UniConf. To create any kind of 00006 * UniConf tree, you'll need one of these. 00007 */ 00008 #include "uniconfroot.h" 00009 00010 00011 /***** UniConfRoot *****/ 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 // remove the watch if it matches 00041 if (i->cookie == cookie && i->recurse == recurse) 00042 { 00043 i.xunlink(); 00044 break; 00045 } 00046 } 00047 // prune the branch if needed 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 // pretend that we wiped out just this key 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 // check root node 00116 check(node, key, segs); 00117 00118 // look for watches on key and its ancestors 00119 for (int s = 0; s < segs; ) 00120 { 00121 node = node->findchild(key.segment(s)); 00122 s++; 00123 if (!node) 00124 goto done; // no descendents so we can stop 00125 check(node, key, segs - s); 00126 } 00127 00128 // look for watches on descendents of key if node was deleted 00129 if (value.isnull()) 00130 deletioncheck(node, key); 00131 00132 done: 00133 unhold_delta(); 00134 }

Generated on Tue Oct 5 01:09:19 2004 for WvStreams by doxygen 1.3.7