/// <summary> /// For each property in updatedProperties, (1) if the value in local sop/sp's /// data is different than that in SyncInfo, and what's in SyncInfo /// has an older timestamp, then update that property's value and syncInfo /// in SyncInfo; (2) otherwise, skip the property and do nothing. /// </summary> /// <param name="part"></param> /// <param name="updatedProperties"></param> /// <returns>The list properties among updatedProperties whose value have been copied over to SyncInfo.</returns> public HashSet <SyncableProperties.Type> UpdateSyncInfoByLocal(UUID uuid, HashSet <SyncableProperties.Type> updatedProperties) { SyncInfoBase thisSyncInfo = null; bool found = false; lock (m_syncLock){ found = m_syncedUUIDs.TryGetValue(uuid, out thisSyncInfo); } if (found) { // DebugLog.WarnFormat("[SYNC INFO MANAGER] UpdateSyncInfoByLocal SyncInfo for {0} FOUND.", uuid); return(thisSyncInfo.UpdatePropertiesByLocal(uuid, updatedProperties, RegionSyncModule.NowTicks(), m_regionSyncModule.SyncID)); } // DebugLog.WarnFormat("[SYNC INFO MANAGER] UpdateSyncInfoByLocal SyncInfo for {0} NOT FOUND.", uuid); return(new HashSet <SyncableProperties.Type>()); }
//TODO: might return status such as Updated, Unchanged, etc to caller public HashSet <SyncableProperties.Type> UpdatePropertiesBySync(UUID uuid, HashSet <SyncedProperty> syncedProperties) { long recvTS = RegionSyncModule.NowTicks(); HashSet <SyncableProperties.Type> propertiesUpdated = new HashSet <SyncableProperties.Type>(); List <SyncedProperty> updatedSyncedProperties = new List <SyncedProperty>(); lock (m_syncLock) { foreach (SyncedProperty syncedProperty in syncedProperties) { bool updated = false; SyncableProperties.Type property = syncedProperty.Property; //Compare if the value of the property in this SyncInfo is different than the value in local scene SyncedProperty currentlySyncedProperty; CurrentlySyncedProperties.TryGetValue(property, out currentlySyncedProperty); // If synced property is not in cache, add it now. if (currentlySyncedProperty == null) { //could happen if PhysActor is just created (object stops being phantom) if (SyncableProperties.PhysActorProperties.Contains(property)) { CurrentlySyncedProperties.Add(property, syncedProperty); } else { DebugLog.WarnFormat("{0}: UpdatePropertiesBySync: No record of property {1} for uuid {2}", LogHeader, property, uuid); } } else { try { //Compare timestamp and update SyncInfo if necessary updated = currentlySyncedProperty.CompareAndUpdateSyncInfoBySync(syncedProperty, recvTS); //If updated, update the property value in scene object/presence if (updated) { //SetPropertyValue(property); updatedSyncedProperties.Add(currentlySyncedProperty); propertiesUpdated.Add(property); } } catch (Exception e) { DebugLog.ErrorFormat("{0}: UpdatePropertiesBySync: Error in updating property {1}: {2}", LogHeader, property, e.Message); } } } } //Now we only need to read from the SyncInfo, so moving the SetPropertyValue out of lock, to avoid potential deadlocks //which might happen due to side effects of "set" functions of a SOp or SP property foreach (SyncedProperty updatedProperty in updatedSyncedProperties) { SetPropertyValue(updatedProperty); } PostUpdateBySync(propertiesUpdated); return(propertiesUpdated); }