Ejemplo n.º 1
0
        internal void Initialize(bool addToWorld = true)
        {
            created = true;

            // Make sure traits are usable for condition notifiers
            foreach (var t in TraitsImplementing <INotifyCreated>())
            {
                t.Created(this);
            }

            var allObserverNotifiers = new HashSet <VariableObserverNotifier>();

            foreach (var provider in TraitsImplementing <IObservesVariables>())
            {
                foreach (var variableUser in provider.GetVariableObservers())
                {
                    allObserverNotifiers.Add(variableUser.Notifier);
                    foreach (var variable in variableUser.Variables)
                    {
                        var cs = conditionStates.GetOrAdd(variable);
                        cs.Notifiers.Add(variableUser.Notifier);

                        // Initialize conditions that have not yet been granted to 0
                        // NOTE: Some conditions may have already been granted by INotifyCreated calling GrantCondition,
                        // and we choose to assign the token count to safely cover both cases instead of adding an if branch.
                        conditionCache[variable] = cs.Tokens.Count;
                    }
                }
            }

            // Update all traits with their initial condition state
            foreach (var notify in allObserverNotifiers)
            {
                notify(this, readOnlyConditionCache);
            }

            // TODO: Some traits may need initialization after being notified of initial condition state.

            // TODO: A post condition initialization notification phase may allow queueing activities instead.
            // The initial activity should run before any activities queued by INotifyCreated.Created
            // However, we need to know which traits are enabled (via conditions), so wait for after the calls and insert the activity as the first
            ICreationActivity creationActivity = null;

            foreach (var ica in TraitsImplementing <ICreationActivity>())
            {
                if (!ica.IsTraitEnabled())
                {
                    continue;
                }

                if (creationActivity != null)
                {
                    throw new InvalidOperationException("More than one enabled ICreationActivity trait: {0} and {1}".F(creationActivity.GetType().Name, ica.GetType().Name));
                }

                var activity = ica.GetCreationActivity();
                if (activity == null)
                {
                    continue;
                }

                creationActivity = ica;

                activity.Queue(CurrentActivity);
                CurrentActivity = activity;
            }

            if (addToWorld)
            {
                World.Add(this);
            }
        }