9 #include "unireplicategen.h"
10 #include "wvmoniker.h"
11 #include "wvstringlist.h"
13 #include "wvlinkerhack.h"
19 #define DPRINTF(format, args...) fprintf(stderr, format ,##args);
21 #define DPRINTF if (0) printf
29 DPRINTF(
"encoded_monikers = %s\n", s.cstr());
32 DPRINTF(
"monikers = %s\n", monikers.
join(
",").
cstr());
34 WvStringList::Iter i(monikers);
35 for (i.rewind(); i.next(); )
40 gens.append(gen,
false);
52 UniReplicateGen::UniReplicateGen() : processing_callback(false)
57 UniReplicateGen::UniReplicateGen(
const IUniConfGenList &_gens,
58 bool auto_free) : processing_callback(false)
60 IUniConfGenList::Iter i(_gens);
62 for (i.rewind(); i.next(); )
64 Gen *gen =
new Gen(i.ptr(), auto_free);
67 gens.append(gen,
true);
68 gen->gen->add_callback(
this,
69 wv::bind(&UniReplicateGen::deltacallback,
78 UniReplicateGen::~UniReplicateGen()
80 GenList::Iter i(gens);
81 for (i.rewind(); i.next(); )
82 i->gen->del_callback(
this);
86 void UniReplicateGen::prepend(
IUniConfGen *_gen,
bool auto_free)
88 Gen *gen =
new Gen(_gen, auto_free);
91 gens.prepend(gen,
true);
92 gen->gen->add_callback(
this, wv::bind(&UniReplicateGen::deltacallback,
100 void UniReplicateGen::append(
IUniConfGen *_gen,
bool auto_free)
102 Gen *gen =
new Gen(_gen, auto_free);
105 gens.append(gen,
true);
106 gen->gen->add_callback(
this, wv::bind(&UniReplicateGen::deltacallback,
116 return first_ok() != NULL;
124 replicate_if_any_have_become_ok();
126 GenList::Iter i(gens);
127 for (i.rewind(); i.next(); )
129 if (!i->gen->refresh())
139 replicate_if_any_have_become_ok();
141 GenList::Iter i(gens);
142 for (i.rewind(); i.next(); )
149 void UniReplicateGen::deltacallback(Gen *src_gen,
const UniConfKey &key,
152 DPRINTF(
"UniReplicateGen::deltacallback(%s, %s)\n",
155 if (!processing_callback)
157 DPRINTF(
"UniReplicateGen::deltacallback(): !processing_callback\n");
159 processing_callback =
true;
161 GenList::Iter j(gens);
162 for (j.rewind(); j.next(); )
167 if (j.ptr() != src_gen)
169 DPRINTF(
"UniReplicateGen::deltacallback: %p->set(%s, %s)\n",
171 j->gen->set(key, value);
177 processing_callback =
false;
181 DPRINTF(
"UniReplicateGen::deltacallback(): processing_callback\n");
188 DPRINTF(
"UniReplicateGen::set(%s, %s)\n",
191 replicate_if_any_have_become_ok();
193 Gen *first = first_ok();
195 first->gen->set(key, value);
197 DPRINTF(
"UniReplicateGen::set: first == NULL\n");
203 DPRINTF(
"UniReplicateGen::setv\n");
205 replicate_if_any_have_become_ok();
207 Gen *first = first_ok();
209 first->gen->setv(pairs);
211 DPRINTF(
"UniReplicateGen::setv: first == NULL\n");
219 replicate_if_any_have_become_ok();
221 Gen *first = first_ok();
224 WvString result = first->gen->get(key);
228 if (!result && !first->isok())
230 Gen *new_first = first_ok();
231 if (new_first == first)
239 return WvString::null;
246 replicate_if_any_have_become_ok();
248 Gen *first = first_ok();
250 return first->gen->iterator(key);
256 UniReplicateGen::Gen *UniReplicateGen::first_ok()
const
258 GenList::Iter j(gens);
259 for (j.rewind(); j.next(); )
269 void UniReplicateGen::replicate(
const UniConfKey &key)
271 DPRINTF(
"UniReplicateGen::replicate(%s)\n", key.
printable().
cstr());
275 Gen *first = first_ok();
277 GenList::Iter j(gens);
278 for (j.rewind(); j.next(); )
280 DPRINTF(
"UniReplicateGen::replicate: %p\n", j.ptr());
284 DPRINTF(
"UniReplicateGen::replicate: !isok()\n");
291 DPRINTF(
"UniReplicateGen::replicate: no iterator\n");
297 DPRINTF(
"UniReplicateGen::replicate: key=%s, value=%s\n",
300 if (j.ptr() == first)
302 DPRINTF(
"UniReplicateGen::replicate: deltacallback()\n");
303 deltacallback(first, i->
key(), i->
value());
307 if (!first->gen->exists(i->
key()))
309 DPRINTF(
"UniReplicateGen::replicate: !exists()\n");
310 first->gen->set(i->
key(), i->
value());
314 DPRINTF(
"UniReplicateGen::replicate: exists()\n");
324 DPRINTF(
"UniReplicateGen::replicate: done\n");
327 void UniReplicateGen::replicate_if_any_have_become_ok()
329 bool should_replicate =
false;
331 GenList::Iter j(gens);
332 for (j.rewind(); j.next(); )
334 if (!j->was_ok && j->gen->isok())
338 should_replicate =
true;
342 if (should_replicate)
344 DPRINTF(
"UniReplicateGen::replicate_if_any_have_become_ok: replicating\n");
virtual WvString value() const =0
Returns the value of the current key.
A UniConf generator that replicates generators between an ordered list of inner generators,...
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
virtual UniConfKey key() const =0
Returns the current key.
WvString printable() const
Returns the canonical string representation of the path.
void unhold_delta()
Resumes notifications when each hold_delta() has been matched.
WvString is an implementation of a simple and efficient printable-string class.
An abstract data container that backs a UniConf tree.
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
virtual bool refresh()
Refreshes information about a key recursively.
const char * cstr() const
return a (const char *) for this string.
WvString join(const char *joinchars=" ") const
concatenates all elements of the list seperating on joinchars
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
virtual unsigned int release()=0
Indicate that you are finished using this object.
virtual void commit()
Commits any changes.
void delta(const UniConfKey &key, WvStringParm value)
Call this when a key's value or children have possibly changed.
virtual void rewind()=0
Rewinds the iterator.
virtual bool next()=0
Seeks to the next element in the sequence.
virtual bool isok()
Determines if the generator is usable and working properly.
This is a WvList of WvStrings, and is a really handy way to parse strings.
void wvtcl_decode(WvList< WvString > &l, WvStringParm _s, const WvStringMask &splitchars=WVTCL_SPLITCHARS, bool do_unescape=true)
split a tcl-style list.
virtual unsigned int addRef()=0
Indicate you are using this object.
void hold_delta()
Pauses notifications until matched with a call to unhold_delta().
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
An abstract iterator over keys and values in a generator.