LMMS
Loading...
Searching...
No Matches
updatehandler.cpp
Go to the documentation of this file.
1//------------------------------------------------------------------------
2// Project : SDK Base
3// Version : 1.0
4//
5// Category : Helpers
6// Filename : base/source/updatehandler.cpp
7// Created by : Steinberg, 2008
8// Description :
9//
10//-----------------------------------------------------------------------------
11// LICENSE
12// (c) 2021, Steinberg Media Technologies GmbH, All Rights Reserved
13//-----------------------------------------------------------------------------
14// Redistribution and use in source and binary forms, with or without modification,
15// are permitted provided that the following conditions are met:
16//
17// * Redistributions of source code must retain the above copyright notice,
18// this list of conditions and the following disclaimer.
19// * Redistributions in binary form must reproduce the above copyright notice,
20// this list of conditions and the following disclaimer in the documentation
21// and/or other materials provided with the distribution.
22// * Neither the name of the Steinberg Media Technologies nor the names of its
23// contributors may be used to endorse or promote products derived from this
24// software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
34// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35// OF THE POSSIBILITY OF SUCH DAMAGE.
36//-----------------------------------------------------------------------------
37
40#include "base/source/fstring.h"
41
42#if SMTG_CPP11_STDLIBSUPPORT
43#include <unordered_map>
44#else
45#include <map>
46#endif
47#include <deque>
48#include <vector>
49#include <algorithm>
50
51#define NON_EXISTING_DEPENDENCY_CHECK 0 // not yet
52#define CLASS_NAME_TRACKED DEVELOPMENT
53
55
56namespace Steinberg {
57
58DEF_CLASS_IID (IUpdateManager)
60
61namespace Update {
62const uint32 kHashSize = (1 << 8); // must be power of 2 (16 bytes * 256 == 4096)
63const uint32 kMapSize = 1024 * 10;
64
65//------------------------------------------------------------------------
66inline uint32 hashPointer (void* p)
67{
68 return (uint32)((uint64 (p) >> 12) & (kHashSize - 1));
69}
70
71//------------------------------------------------------------------------
73{
74 FUnknown* result = nullptr;
75 if (unknown)
76 unknown->queryInterface (FUnknown::iid, (void**)&result);
77
78 return owned (result);
79}
80
81#if CLASS_NAME_TRACKED
82//------------------------------------------------------------------------
83struct Dependency
84{
85 Dependency (FUnknown* o, IDependent* d)
86 : obj (o), dep (d), objClass (nullptr), depClass (nullptr)
87 {
88 }
89
90 inline bool operator== (const Dependency& d) const { return obj == d.obj; }
91 inline bool operator!= (const Dependency& d) const { return obj != d.obj; }
92 inline bool operator< (const Dependency& d) const { return obj < d.obj; }
93 inline bool operator> (const Dependency& d) const { return obj > d.obj; }
94 FUnknown* obj;
95 IDependent* dep;
96
97 FClassID objClass;
98 FClassID depClass;
99};
100#endif
101
102//------------------------------------------------------------------------
104{
105 DeferedChange (FUnknown* o, int32 m = 0) : obj (o), msg (m) {}
108 inline bool operator== (const DeferedChange& d) const { return obj == d.obj; }
109 inline bool operator!= (const DeferedChange& d) const { return obj != d.obj; }
112};
113
114//------------------------------------------------------------------------
116{
118 : obj (o), dependents (d), count (c)
119 {
120 }
124 bool operator== (const UpdateData& d) const
125 {
126 return d.obj == obj && d.dependents == dependents;
127 }
128};
129
130//------------------------------------------------------------------------
131using DeferedChangeList = std::deque<DeferedChange>;
132using DeferedChangeListIterConst = DeferedChangeList::const_iterator;
133using DeferedChangeListIter = DeferedChangeList::iterator;
134
135using UpdateDataList = std::deque<UpdateData>;
136using UpdateDataListIterConst = UpdateDataList::const_iterator;
137
138#if CLASS_NAME_TRACKED
139using DependentList = std::vector<Dependency>;
140#else
141typedef std::vector<IDependent*> DependentList;
142#endif
143using DependentListIter = DependentList::iterator;
144using DependentListIterConst = DependentList::const_iterator;
145
146#if SMTG_CPP11_STDLIBSUPPORT
147using DependentMap = std::unordered_map<const FUnknown*, DependentList>;
148#else
149typedef std::map<const FUnknown*, DependentList> DependentMap;
150#endif
151using DependentMapIter = DependentMap::iterator;
152using DependentMapIterConst = DependentMap::const_iterator;
153
160
161//------------------------------------------------------------------------
163{
165 {
166 FObject* obj = FObject::unknownToObject (unknown);
167 if (obj)
168 obj->updateDone (message);
169 }
170}
171} // namespace Update
172
173//------------------------------------------------------------------------
175{
176 int32 total = 0;
177 Update::DependentMapIterConst iterMap = map.begin ();
178 while (iterMap != map.end ())
179 {
180 const Update::DependentList& list = iterMap->second;
181 Update::DependentListIterConst iterList = list.begin ();
182 while (iterList != list.end ())
183 {
184 total++;
185 ++iterList;
186 }
187 ++iterMap;
188 }
189 return total;
190}
191
192//------------------------------------------------------------------------
199
200//------------------------------------------------------------------------
202{
203 if (FObject::getUpdateHandler () == this)
205 delete table;
206 table = nullptr;
207}
208
209//------------------------------------------------------------------------
211{
213 if (!unknown || !_dependent)
214 return kResultFalse;
215
216 FGuard guard (lock);
217
218#if CLASS_NAME_TRACKED
219 Update::Dependency dependent (unknown, _dependent);
220
221 FObject* obj = FObject::unknownToObject (unknown);
222 if (obj)
223 dependent.objClass = obj->isA ();
224 obj = FObject::unknownToObject (_dependent);
225 if (obj)
226 dependent.depClass = obj->isA ();
227#else
228 IDependent* dependent = _dependent;
229#endif
230
231 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
232 Update::DependentMapIter it = map.find (unknown);
233 if (it == map.end ())
234 {
236 list.push_back (dependent);
237 map[unknown] = list;
238 }
239 else
240 {
241 (*it).second.push_back (dependent);
242 }
243
244 return kResultTrue;
245}
246
247//------------------------------------------------------------------------
249{
251 if (unknown == nullptr && dependent == nullptr)
252 return kResultFalse;
253
254 FGuard guard (lock);
255
256 Update::UpdateDataListIterConst iter = table->updateData.begin ();
257 while (iter != table->updateData.end ())
258 {
259 if ((*iter).obj == unknown || unknown == nullptr)
260 {
261 for (uint32 count = 0; count < (*iter).count; count++)
262 {
263 if ((*iter).dependents[count] == dependent)
264 (*iter).dependents[count] = nullptr;
265 }
266 }
267 ++iter;
268 }
269 // Remove all objects for the given dependent
270 if (unknown == nullptr)
271 {
272 for (uint32 j = 0; j < Update::kHashSize; j++)
273 {
274 Update::DependentMap& map = table->depMap[j];
275 Update::DependentMapIter iterMap = map.begin ();
276 while (iterMap != map.end ())
277 {
278 Update::DependentList& list = (*iterMap).second;
279 Update::DependentListIter iterList = list.begin ();
280 bool listIsEmpty = false;
281
282 while (iterList != list.end ())
283 {
284#if CLASS_NAME_TRACKED
285 if ((*iterList).dep == dependent)
286#else
287 if ((*iterList) == dependent)
288#endif
289 {
290 if (list.size () == 1u)
291 {
292 listIsEmpty = true;
293 break;
294 }
295 else
296 iterList = list.erase (iterList);
297 }
298 else
299 {
300 ++iterList;
301 }
302 }
303
304 if (listIsEmpty)
305 iterMap = map.erase (iterMap);
306 else
307 ++iterMap;
308 }
309 }
310 }
311 else
312 {
313 bool mustFlush = true;
314
315 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
316 Update::DependentMapIter iterList = map.find (unknown);
317
318#if NON_EXISTING_DEPENDENCY_CHECK
319 SMTG_ASSERT (iterList != map.end () && "ERROR: Trying to remove a non existing dependency!")
320#endif
321 if (iterList != map.end ())
322 {
323 if (dependent == nullptr) // Remove all dependents of object
324 {
325 map.erase (iterList);
326 }
327 else // Remove one dependent
328 {
329 int32 eraseCount = 0;
330 Update::DependentList& dependentlist = (*iterList).second;
331 Update::DependentListIter iterDependentlist = dependentlist.begin ();
332 while (iterDependentlist != dependentlist.end ())
333 {
334#if CLASS_NAME_TRACKED
335 if ((*iterDependentlist).dep == dependent)
336#else
337 if ((*iterDependentlist) == dependent)
338#endif
339 {
340 iterDependentlist = dependentlist.erase (iterDependentlist);
341 eraseCount++;
342 if (dependentlist.empty ())
343 {
344 map.erase (iterList);
345 break;
346 }
347 }
348 else
349 {
350 ++iterDependentlist;
351 mustFlush = false;
352 }
353 }
354 }
355 }
356 if (mustFlush)
357 cancelUpdates (unknown);
358 }
359
360 return kResultTrue;
361}
362
363//------------------------------------------------------------------------
365{
366 if (lockUpdates)
367 return kResultFalse;
369 if (!unknown)
370 return kResultFalse;
371
372 // to avoid crashes due to stack overflow, we reduce the amount of memory reserved for the
373 // dependents
374 IDependent* smallDependents[Update::kMapSize / 10]; // 8kB for x64
375 IDependent** dependents = smallDependents;
376 int32 maxDependents = Update::kMapSize / 10;
377 int32 count = 0;
378
379 {
380 FGuard guard (lock); // scope for lock
381
382 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
383 Update::DependentMapIterConst iterList = map.find (unknown);
384 if (iterList != map.end ())
385 {
386 const Update::DependentList& dependentlist = (*iterList).second;
387 Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
388 while (iterDependentlist != dependentlist.end ())
389 {
390#if CLASS_NAME_TRACKED
391 dependents[count] = (*iterDependentlist).dep;
392#else
393 dependents[count] = *iterDependentlist;
394#endif
395 count++;
396
397 if (count >= maxDependents)
398 {
399 if (dependents == smallDependents)
400 {
401 dependents = NEW IDependent*[Update::kMapSize];
402 memcpy (dependents, smallDependents, count * sizeof (dependents[0]));
403 maxDependents = Update::kMapSize;
404 }
405 else
406 {
407 SMTG_WARNING ("Dependency overflow")
408 break;
409 }
410 }
411 ++iterDependentlist;
412 }
413 }
414
415 // push update data on the stack
416 if (count > 0)
417 {
418 Update::UpdateData data (unknown, dependents, count);
419 table->updateData.push_back (data);
420 }
421 } // end scope
422
423 int32 i = 0;
424 while (i < count)
425 {
426 if (dependents[i])
427 dependents[i]->update (unknown, message);
428 i++;
429 }
430
431 if (dependents != smallDependents)
432 delete[] dependents;
433
434 // remove update data from the stack
435 if (count > 0)
436 {
437 FGuard guard (lock);
438
439 table->updateData.pop_back ();
440 }
441
442 // send update done message
443 if (suppressUpdateDone == false)
444 Update::updateDone (unknown, message);
445
446 return count > 0 ? kResultTrue : kResultFalse; // Object was found and has been updated
447}
448
449//------------------------------------------------------------------------
454
455//------------------------------------------------------------------------
457{
459 if (!unknown)
460 return kResultFalse;
461
462 FGuard guard (lock);
463
464 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
465 Update::DependentMapIterConst iterList = map.find (unknown);
466
467 bool hasDependency = (iterList != map.end ());
468 if (hasDependency == false)
469 {
470 Update::updateDone (unknown, message);
471 return kResultTrue;
472 }
473
474 bool found = false;
475 Update::DeferedChangeListIterConst iter = table->defered.begin ();
476 while (iter != table->defered.end ())
477 {
478 if ((*iter).obj == unknown && (*iter).msg == message)
479 {
480 found = true;
481 break;
482 }
483 ++iter;
484 }
485
486 if (!found)
487 {
488 Update::DeferedChange change (unknown, message);
489 table->defered.push_back (change);
490 }
491
492 return kResultTrue;
493}
494
495//------------------------------------------------------------------------
497{
498 Update::DeferedChangeList deferedAgain;
499 if (!unknown)
500 {
501 while (table->defered.empty () == false)
502 {
503 // Remove first from queue
504 lock.lock ();
505
506 FUnknown* obj = table->defered.front ().obj;
507 int32 msg = table->defered.front ().msg;
508 table->defered.pop_front ();
509
510 // check if this object is currently being updated. in this case, defer update again...
511 bool canSignal = true;
512 Update::UpdateDataListIterConst iter = table->updateData.begin ();
513 while (iter != table->updateData.end ())
514 {
515 if ((*iter).obj == obj)
516 {
517 canSignal = false;
518 break;
519 }
520 ++iter;
521 }
522 lock.unlock ();
523
524 if (canSignal)
525 {
526 triggerUpdates (obj, msg);
527 }
528 else
529 {
530 Update::DeferedChange change (obj, msg);
531 deferedAgain.push_back (change);
532 }
533 }
534 }
535 else
536 {
537 IPtr<FUnknown> object = Update::getUnknownBase (unknown);
538 Update::DeferedChange tmp (object);
539
540 while (true)
541 {
542 lock.lock ();
544 std::find (table->defered.begin (), table->defered.end (), tmp);
545 if (it == table->defered.end ())
546 {
547 lock.unlock ();
548 return kResultTrue;
549 }
550
551 if ((*it).obj != nullptr)
552 {
553 int32 msg = (*it).msg;
554 table->defered.erase (it);
555
556 // check if this object is currently being updated. in this case, defer update
557 // again...
558 bool canSignal = true;
559 Update::UpdateDataListIterConst iter = table->updateData.begin ();
560 while (iter != table->updateData.end ())
561 {
562 if ((*iter).obj == object)
563 {
564 canSignal = false;
565 break;
566 }
567 ++iter;
568 }
569 lock.unlock ();
570
571 if (canSignal)
572 {
573 triggerUpdates (object, msg);
574 }
575 else
576 {
577 Update::DeferedChange change (object, msg);
578 deferedAgain.push_back (change);
579 }
580 }
581 }
582 }
583
584 if (deferedAgain.empty () == false)
585 {
586 FGuard guard (lock);
587
588 Update::DeferedChangeListIterConst iter = deferedAgain.begin ();
589 while (iter != deferedAgain.end ())
590 {
591 table->defered.push_back (*iter);
592 ++iter;
593 }
594 }
595
596 return kResultTrue;
597}
598
599//------------------------------------------------------------------------
601{
603 if (!unknown)
604 return kResultFalse;
605
606 FGuard guard (lock);
607
608 Update::DeferedChange change (unknown, 0);
609 while (true)
610 {
611 auto iter = std::find (table->defered.begin (), table->defered.end (), change);
612 if (iter != table->defered.end ())
613 table->defered.erase (iter);
614 else
615 break;
616 }
617
618 return kResultTrue;
619}
620
621//------------------------------------------------------------------------
623{
624 FGuard guard (lock);
625 uint32 res = 0;
626
627 IPtr<FUnknown> unknown = Update::getUnknownBase (object);
628 if (unknown)
629 {
630 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
631 Update::DependentMapIter iterList = map.find (unknown);
632 if (iterList != map.end ())
633 return iterList->second.size ();
634 }
635 else
636 {
637 for (uint32 j = 0; j < Update::kHashSize; j++)
638 {
639 Update::DependentMap& map = table->depMap[j];
640 res += countEntries (map);
641 }
642 }
643 return res;
644}
645
646#if DEVELOPMENT
647//------------------------------------------------------------------------
648bool UpdateHandler::checkDeferred (FUnknown* object)
649{
650 IPtr<FUnknown> unknown = Update::getUnknownBase (object);
651
652 FGuard guard (lock);
653
654 Update::DeferedChange tmp (unknown);
656 std::find (table->defered.begin (), table->defered.end (), tmp);
657 if (it != table->defered.end ())
658 return true;
659
660 return false;
661}
662
663//------------------------------------------------------------------------
664bool UpdateHandler::hasDependencies (FUnknown* u)
665{
666 IPtr<FUnknown> unknown = Update::getUnknownBase (u);
667 if (!unknown)
668 return false;
669
670 FGuard guard (lock);
671
673 Update::DependentMapIterConst iterList = map.find (unknown);
674 bool hasDependency = (iterList != map.end ());
675
676 return hasDependency;
677}
678
679//------------------------------------------------------------------------
680void UpdateHandler::printForObject (FObject* obj) const
681{
682 IPtr<FUnknown> unknown = Update::getUnknownBase (obj);
683 if (!unknown)
684 return;
685
686 FUnknownPtr<IDependent> dep (obj);
687
688 bool header = false;
689
690 Update::DependentMap& map = table->depMap[Update::hashPointer (unknown)];
691 Update::DependentMapIterConst iterList = map.begin ();
692 while (iterList != map.end ())
693 {
694 const Update::DependentList& dependentlist = (*iterList).second;
695 Update::DependentListIterConst iterDependentlist = dependentlist.begin ();
696 while (iterDependentlist != dependentlist.end ())
697 {
698#if CLASS_NAME_TRACKED
699 if ((*iterList).first == unknown || (*iterDependentlist).dep == dep.getInterface ())
700 {
701 if (!header)
702 {
703 FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
704 obj->isA ());
705 header = true;
706 }
707 FDebugPrint ("%s %8" FORMAT_INT64A "\n <- %s %8" FORMAT_INT64A "\n",
708 (*iterDependentlist).depClass, (uint64) (*iterDependentlist).dep,
709 (*iterDependentlist).objClass, (uint64) ((*iterList).first));
710 }
711#else
712 if ((*iterList).first == unknown || (*iterDependentlist) == dep.getInterface ())
713 {
714 if (!header)
715 {
716 FDebugPrint ("Dependencies for object %8" FORMAT_INT64A " %s\n", (uint64)obj,
717 obj->isA ());
718 header = true;
719 }
720 FDebugPrint ("%8" FORMAT_INT64A "\n <- %8" FORMAT_INT64A "\n",
721 (uint64) (*iterDependentlist), (uint64) ((*iterList).first));
722 }
723#endif
724 ++iterDependentlist;
725 }
726
727 ++iterList;
728 }
729}
730#endif
731
732//------------------------------------------------------------------------
733} // namespace Steinberg
#define nullptr
Definition DistrhoDefines.h:75
static void message(int level, const char *fmt,...)
Definition adplugdb.cpp:120
Definition flock.h:134
Definition fobject.h:82
FObject()
default constructor...
Definition fobject.h:85
static void setUpdateHandler(IUpdateHandler *handler)
set method for the local attribute
Definition fobject.h:115
static FObject * unknownToObject(FUnknown *unknown)
pointer conversion from FUnknown to FObject
Definition fobject.h:136
static IUpdateHandler * getUpdateHandler()
get method for the local attribute
Definition fobject.h:116
virtual void updateDone(int32)
empty virtual method that should be overridden by derived classes
Definition fobject.h:112
virtual FClassID isA() const
a local alternative to getFClassID ()
Definition fobject.h:92
Definition funknown.h:361
static const FUID iid
Definition funknown.h:382
Definition iupdatehandler.h:76
virtual void PLUGIN_API update(FUnknown *changedUnknown, int32 message)=0
@ kDestroyed
Definition iupdatehandler.h:86
Definition smartpointer.h:44
tresult PLUGIN_API addDependent(FUnknown *object, IDependent *dependent) SMTG_OVERRIDE
Definition updatehandler.cpp:210
UpdateHandler()
Definition updatehandler.cpp:193
Update::Table * table
Definition updatehandler.h:132
static bool lockUpdates
Definition updatehandler.h:134
size_t countDependencies(FUnknown *object=nullptr)
Definition updatehandler.cpp:622
tresult PLUGIN_API triggerUpdates(FUnknown *object, int32 message) SMTG_OVERRIDE
Definition updatehandler.cpp:450
tresult PLUGIN_API triggerDeferedUpdates(FUnknown *object=nullptr) SMTG_OVERRIDE
Definition updatehandler.cpp:496
tresult PLUGIN_API removeDependent(FUnknown *object, IDependent *dependent) SMTG_OVERRIDE
Definition updatehandler.cpp:248
~UpdateHandler()
Definition updatehandler.cpp:201
tresult doTriggerUpdates(FUnknown *object, int32 message, bool suppressUpdateDone)
Definition updatehandler.cpp:364
Steinberg::Base::Thread::FLock lock
Definition updatehandler.h:131
tresult PLUGIN_API deferUpdates(FUnknown *object, int32 message) SMTG_OVERRIDE
Definition updatehandler.cpp:456
tresult PLUGIN_API cancelUpdates(FUnknown *object) SMTG_OVERRIDE
Definition updatehandler.cpp:600
unsigned * m
Definition inflate.c:1559
register unsigned j
Definition inflate.c:1576
unsigned d
Definition inflate.c:940
struct huft * u[BMAX]
Definition inflate.c:1583
register unsigned i
Definition inflate.c:1575
#define SMTG_WARNING(s)
Definition fdebug.h:197
#define NEW
Definition fdebug.h:212
#define SMTG_ASSERT(f)
Definition fdebug.h:196
#define DEF_CLASS_IID(ClassName)
Definition funknown.h:78
JSAMPIMAGE data
Definition jpeglib.h:945
const char * msg
Definition missing_descriptor.c:20
@ unknown
Definition VstPlugin.cpp:75
Definition updatehandler.cpp:61
const uint32 kHashSize
Definition updatehandler.cpp:62
std::deque< UpdateData > UpdateDataList
Definition updatehandler.cpp:135
void updateDone(FUnknown *unknown, int32 message)
Definition updatehandler.cpp:162
DeferedChangeList::const_iterator DeferedChangeListIterConst
Definition updatehandler.cpp:132
std::vector< IDependent * > DependentList
Definition updatehandler.cpp:141
uint32 hashPointer(void *p)
Definition updatehandler.cpp:66
std::map< const FUnknown *, DependentList > DependentMap
Definition updatehandler.cpp:149
IPtr< FUnknown > getUnknownBase(FUnknown *unknown)
Definition updatehandler.cpp:72
const uint32 kMapSize
Definition updatehandler.cpp:63
DependentMap::iterator DependentMapIter
Definition updatehandler.cpp:151
DependentMap::const_iterator DependentMapIterConst
Definition updatehandler.cpp:152
DependentList::const_iterator DependentListIterConst
Definition updatehandler.cpp:144
DependentList::iterator DependentListIter
Definition updatehandler.cpp:143
std::deque< DeferedChange > DeferedChangeList
Definition updatehandler.cpp:131
UpdateDataList::const_iterator UpdateDataListIterConst
Definition updatehandler.cpp:136
DeferedChangeList::iterator DeferedChangeListIter
Definition updatehandler.cpp:133
Definition baseiids.cpp:43
unsigned long long uint64
Definition ftypes.h:67
int int32
Definition ftypes.h:50
static int32 countEntries(Update::DependentMap &map)
Definition updatehandler.cpp:174
@ kResultFalse
Definition funknown.h:195
@ kResultTrue
Definition funknown.h:194
int32 tresult
Definition ftypes.h:76
FIDString FClassID
Definition fobject.h:52
IPtr< I > owned(I *p)
Definition smartpointer.h:241
unsigned int uint32
Definition ftypes.h:51
Definition updatehandler.cpp:104
DeferedChange(const DeferedChange &r)
Definition updatehandler.cpp:107
FUnknown * obj
Definition updatehandler.cpp:110
int32 msg
Definition updatehandler.cpp:111
~DeferedChange()
Definition updatehandler.cpp:106
DeferedChange(FUnknown *o, int32 m=0)
Definition updatehandler.cpp:105
bool operator!=(const DeferedChange &d) const
Definition updatehandler.cpp:109
bool operator==(const DeferedChange &d) const
Definition updatehandler.cpp:108
Definition updatehandler.cpp:155
DependentMap depMap[kHashSize]
Definition updatehandler.cpp:156
DeferedChangeList defered
Definition updatehandler.cpp:157
UpdateDataList updateData
Definition updatehandler.cpp:158
Definition updatehandler.cpp:116
FUnknown * obj
Definition updatehandler.cpp:121
bool operator==(const UpdateData &d) const
Definition updatehandler.cpp:124
uint32 count
Definition updatehandler.cpp:123
UpdateData(FUnknown *o, IDependent **d, uint32 c)
Definition updatehandler.cpp:117
IDependent ** dependents
Definition updatehandler.cpp:122
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
int r
Definition crypt.c:458
int result
Definition process.c:1455
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263