void GC_Object::PulseNotify(NotifyType type, void *param) { ++_notifyProtectCount; for( Notify *n = _firstNotify; n; n = n->next ) { if( type == n->type && !n->IsRemoved() ) { ((n->subscriber)->*n->handler)(this, param); } } --_notifyProtectCount; if( 0 == _notifyProtectCount ) { for( Notify *prev = NULL, *n = _firstNotify; n; ) { if( n->IsRemoved() ) { Notify *&pp = prev ? prev->next : _firstNotify; pp = n->next; delete n; n = pp; } else { prev = n; n = n->next; } } } }
void GC_Object::Serialize(SaveFile &f) { assert(0 == _notifyProtectCount); f.Serialize(_flags); // // name // if( CheckFlags(GC_FLAG_OBJECT_NAMED) ) { if( f.loading() ) { string_t name; f.Serialize(name); assert( 0 == g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)].count(this) ); assert( 0 == g_level->_nameToObjectMap.count(name) ); g_level->_objectToStringMaps[FastLog2(GC_FLAG_OBJECT_NAMED)][this] = name; g_level->_nameToObjectMap[name] = this; } else { string_t name = GetName(); f.Serialize(name); } } // // events // if( f.loading() ) { DWORD tmp = _flags & GC_FLAG_OBJECT_EVENTS_TS_FIXED; SetFlags(GC_FLAG_OBJECT_EVENTS_TS_FIXED, false); SetEvents(tmp); } // // notifications // size_t count = 0; if( const Notify *n = _firstNotify ) do { count += !n->IsRemoved(); } while( n = n->next ); f.Serialize(count); if( f.loading() ) { assert(NULL == _firstNotify); for( size_t i = 0; i < count; i++ ) { _firstNotify = new Notify(_firstNotify); _firstNotify->Serialize(f); } } else { for( Notify *n = _firstNotify; n; n = n->next ) { if( !n->IsRemoved() ) n->Serialize(f); } } }