// Constructors internal Session(Domain domain, SessionConfiguration configuration, bool activate) : base(domain) { Guid = Guid.NewGuid(); IsDebugEventLoggingEnabled = OrmLog.IsLogged(LogLevel.Debug); // Just to cache this value // Both Domain and Configuration are valid references here; // Configuration is already locked Configuration = configuration; Name = configuration.Name; identifier = Interlocked.Increment(ref lastUsedIdentifier); CommandTimeout = configuration.DefaultCommandTimeout; allowSwitching = configuration.Supports(SessionOptions.AllowSwitching); // Handlers Handlers = domain.Handlers; Handler = CreateSessionHandler(); // Caches, registry EntityStateCache = CreateSessionCache(configuration); EntityChangeRegistry = new EntityChangeRegistry(this); EntitySetChangeRegistry = new EntitySetChangeRegistry(this); ReferenceFieldsChangesRegistry = new ReferenceFieldsChangesRegistry(this); entitySetsWithInvalidState = new HashSet <EntitySetBase>(); // Events EntityEvents = new EntityEventBroker(); Events = new SessionEventAccessor(this, false); SystemEvents = new SessionEventAccessor(this, true); // Etc. PairSyncManager = new SyncManager(this); RemovalProcessor = new RemovalProcessor(this); pinner = new Pinner(this); Operations = new OperationRegistry(this); NonPairedReferencesRegistry = new NonPairedReferenceChangesRegistry(this); CommandProcessorContextProvider = new CommandProcessorContextProvider(this); // Validation context ValidationContext = Configuration.Supports(SessionOptions.ValidateEntities) ? (ValidationContext) new RealValidationContext() : new VoidValidationContext(); // Creating Services Services = CreateServices(); disposableSet = new DisposableSet(); remapper = new KeyRemapper(this); disableAutoSaveChanges = !configuration.Supports(SessionOptions.AutoSaveChanges); // Perform activation if (activate) { ActivateInternally(); } // Query endpoint SystemQuery = Query = new QueryEndpoint(new QueryProvider(this)); }
/// <summary> /// Removes the specified set of entities. /// </summary> /// <typeparam name="T">Entity type.</typeparam> /// <param name="entities">The entities.</param> /// <exception cref="ReferentialIntegrityException"> /// Entity is associated with another entity with <see cref="OnRemoveAction.Deny"/> on-remove action. /// </exception> public void Remove <T>([InstantHandle] IEnumerable <T> entities) where T : IEntity { using (var tx = OpenAutoTransaction()) { RemovalProcessor.Remove(entities.Cast <Entity>().ToList(), EntityRemoveReason.User); tx.Complete(); } }
/// <summary> /// Processes changes /// </summary> private void ProcessChanges(bool inPlayMode) { /* Calculating the single step change */ _stepDelta = HierarchyComparer.Compare( _oldHierarchy, _newHierarchy ); #if DEBUG if (DebugMode) { Debug.Log(_stepDelta); } #endif //Debug.Log(delta); /** * 2. Handle additions * a) Instantiate component * b) Record transform addition * */ if (inPlayMode) { /** * 1. PLAY mode * Leaving the processing to persistence logic * */ /** * In play mode we need a full delta, so we will be able to re-apply it * after the play mode is stopped * Tracking full delta with each change, because we don't know when * will be the last chance to track it before stopping the play mode * */ _fullDelta = HierarchyComparer.Compare( _originalHierarchy, _newHierarchy ); /** * IMPORTANT: * This was the source of the quite performance killing recursive bug * If this processing take place in play mode, OnHierarchyChange fires in each consequent frame, without ever stopping * TODO: do a special logic for reordering items in play mode * */ AdditionProcessor.Process(_stepDelta.TopLevelAdditions, _stepDelta.Additions); RemovalProcessor.Process(_stepDelta.Removals); MovesProcessor.Process(_stepDelta.Moves); /** * Accumulate delta * */ PersistenceManager.Instance.Delta = _fullDelta; //.Reset(); // TEMP -> create a direct Delta setter //PersistenceManager.Instance.Delta.Accumulate(_fullDelta); } else { /** * 2. EDIT mode * In edit mode, so handling the ordering information immediatelly * Note: the ordering information is all that has to be processed when adding a new component * or a prefab in Edit mode - other things (parent-child relationship etc.) is handled by Unity * */ EditModeAdditionsProcessor.Process(_stepDelta.TopLevelAdditions); EditModeRemovalProcessor.Process(_stepDelta.TopLevelRemovals); EditModeMovesProcessor.Process(_stepDelta.Moves); } _stepDelta.Reset(); // save the current hierarchy _oldHierarchy = _newHierarchy; EditorState.Instance.Adapter = ComponentRegistry.Instance.Get(EditorState.Instance.AdapterId, true) as ComponentAdapter; ChangesProcessedSignal.Emit(); }