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 Sat Mar 13 14:55:20 2004 for WvStreams by doxygen 1.3.6-20040222