LocationEnvironment.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / System.Activities / System / Activities / Runtime / LocationEnvironment.cs / 1305376 / LocationEnvironment.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.Activities.Runtime 
{
    using System; 
    using System.Collections.ObjectModel; 
    using System.Runtime;
    using System.Runtime.Serialization; 
    using System.Collections.Generic;

    [DataContract]
    sealed class LocationEnvironment : ActivityInstanceMap.IActivityReference 
    {
        bool isDisposed; 
        bool hasHandles; 
        ActivityExecutor executor;
        [DataMember(EmitDefaultValue = false)] 
        Location[] locations;
        [DataMember(EmitDefaultValue = false)]
        bool hasMappableLocations;
        [DataMember(EmitDefaultValue = false)] 
        LocationEnvironment parent;
 
        [DataMember(EmitDefaultValue = false)] 
        Location singleLocation;
 
        // This list keeps track of handles that are created and initialized.
        [DataMember(EmitDefaultValue = false)]
        List handles;
 
        // We store refCount - 1 because it is more likely to
        // be zero and skipped by serialization 
        [DataMember(EmitDefaultValue = false)] 
        int referenceCountMinusOne;
 
        [DataMember(EmitDefaultValue = false)]
        bool hasOwnerCompleted;

        internal LocationEnvironment(ActivityExecutor executor, Activity definition) 
        {
            this.executor = executor; 
            this.Definition = definition; 
        }
 
        internal LocationEnvironment(ActivityExecutor executor, Activity definition, LocationEnvironment parent, int capacity)
            : this(executor, definition)
        {
            this.parent = parent; 

            Fx.Assert(capacity > 0, "must have a positive capacity if using this overload"); 
            if (capacity > 1) 
            {
                this.locations = new Location[capacity]; 
            }
        }

        internal Activity Definition 
        {
            get; 
            private set; 
        }
 
        internal LocationEnvironment Parent
        {
            get
            { 
                return this.parent;
            } 
        } 

        internal bool HasHandles 
        {
            get
            {
                return this.hasHandles; 
            }
        } 
 
        MappableObjectManager MappableObjectManager
        { 
            get
            {
                return this.executor.MappableObjectManager;
            } 
        }
 
        internal bool ShouldDispose 
        {
            get 
            {
                return this.referenceCountMinusOne == -1;
            }
        } 

        internal bool HasOwnerCompleted 
        { 
            get
            { 
                return this.hasOwnerCompleted;
            }
        }
 
        Activity ActivityInstanceMap.IActivityReference.Activity
        { 
            get 
            {
                return this.Definition; 
            }
        }

        internal List Handles 
        {
            get { return this.handles; } 
        } 

        void ActivityInstanceMap.IActivityReference.Load(Activity activity, ActivityInstanceMap instanceMap) 
        {
            this.Definition = activity;
        }
 
        // Note that the owner should never call this as the first
        // AddReference is assumed 
        internal void AddReference() 
        {
            this.referenceCountMinusOne++; 
        }

        internal void RemoveReference(bool isOwner)
        { 
            if (isOwner)
            { 
                this.hasOwnerCompleted = true; 
            }
 
            Fx.Assert(this.referenceCountMinusOne >= 0, "We must at least have 1 reference (0 for refCountMinusOne)");
            this.referenceCountMinusOne--;
        }
 
        internal void OnDeserialized(ActivityExecutor executor, ActivityInstance handleScope)
        { 
            this.executor = executor; 

            // The instance map Load might have already set the definition to the correct one. 
            // If not then we assume the definition is the same as the handle scope.
            if (this.Definition == null)
            {
                this.Definition = handleScope.Activity; 
            }
 
            ReinitializeHandles(handleScope); 
        }
 
        internal void ReinitializeHandles(ActivityInstance handleScope)
        {
            // Need to reinitialize the handles in the list.
            if (this.handles != null) 
            {
                int count = this.handles.Count; 
                for (int i=0;i < count;i++) 
                {
                    this.handles[i].Reinitialize(handleScope); 
                    this.hasHandles = true;
                }
            }
        } 

        internal void Dispose() 
        { 
            Fx.Assert(this.ShouldDispose, "We shouldn't be calling Dispose when we have existing references.");
            Fx.Assert(!this.hasHandles, "We should have already uninitialized the handles and set our hasHandles variable to false."); 
            Fx.Assert(!this.isDisposed, "We should not already be disposed.");

            this.isDisposed = true;
 
            CleanupMappedLocations();
        } 
 
        internal void AddHandle(Handle handleToAdd)
        { 
            if (this.handles == null)
            {
                this.handles = new List();
            } 
            this.handles.Add(handleToAdd);
            this.hasHandles = true; 
        } 

        void CleanupMappedLocations() 
        {
            if (this.hasMappableLocations)
            {
                if (this.singleLocation != null) 
                {
                    Fx.Assert(this.singleLocation.CanBeMapped, "Can only have mappable locations for a singleton if its mappable."); 
                    this.MappableObjectManager.Unregister(this.singleLocation); 
                }
                else if (this.locations != null) 
                {
                    for (int i = 0; i < this.locations.Length; i++)
                    {
                        Location location = this.locations[i]; 

                        if (location.CanBeMapped) 
                        { 
                            this.MappableObjectManager.Unregister(location);
                        } 
                    }
                }
            }
        } 

        internal void UninitializeHandles(ActivityInstance scope) 
        { 
            if (this.hasHandles)
            { 
                HandleInitializationContext context = null;

                try
                { 
                    UninitializeHandles(scope, this.Definition.RuntimeVariables, ref context);
                    UninitializeHandles(scope, this.Definition.ImplementationVariables, ref context); 
 
                    this.hasHandles = false;
                } 
                finally
                {
                    if (context != null)
                    { 
                        context.Dispose();
                    } 
                } 
            }
        } 

        void UninitializeHandles(ActivityInstance scope, IList variables, ref HandleInitializationContext context)
        {
            for (int i = 0; i < variables.Count; i++) 
            {
                Variable variable = variables[i]; 
                Fx.Assert(variable.Owner == this.Definition, "We should only be targeting the vairables at this scope."); 

                if (variable.IsHandle) 
                {
                    Location location = GetSpecificLocation(variable.Id);

                    if (location != null) 
                    {
                        Handle handle = (Handle)location.Value; 
 
                        if (handle != null)
                        { 
                            if (context == null)
                            {
                                context = new HandleInitializationContext(this.executor, scope);
                            } 

                            handle.Uninitialize(context); 
                        } 

                        location.Value = null; 
                    }
                }
            }
        } 

        internal void DeclareHandle(LocationReference locationReference, Location location, ActivityInstance activityInstance) 
        { 
            this.hasHandles = true;
 
            Declare(locationReference, location, activityInstance);
        }

        internal void DeclareTemporaryLocation(LocationReference locationReference, ActivityInstance activityInstance, bool bufferGetsOnCollapse) 
            where T : Location
        { 
            Location locationToDeclare = new Location(); 
            locationToDeclare.SetTemporaryResolutionData(this, bufferGetsOnCollapse);
 
            this.Declare(locationReference, locationToDeclare, activityInstance);
        }

        internal void Declare(LocationReference locationReference, Location location, ActivityInstance activityInstance) 
        {
            Fx.Assert((locationReference.Id == 0 && this.locations == null) || (locationReference.Id >= 0 && this.locations != null && locationReference.Id < this.locations.Length), "The environment should have been created with the appropriate capacity."); 
            Fx.Assert(location != null, ""); 

            if (location.CanBeMapped) 
            {
                this.hasMappableLocations = true;
                this.MappableObjectManager.Register(location, this.Definition, locationReference, activityInstance);
            } 

            if (this.locations == null) 
            { 
                Fx.Assert(this.singleLocation == null, "We should not have had a single location if we are trying to declare one.");
                Fx.Assert(locationReference.Id == 0, "We should think the id is zero if we are setting the single location."); 

                this.singleLocation = location;
            }
            else 
            {
                Fx.Assert(this.locations[locationReference.Id] == null, "We should not have had a location at the spot we are replacing."); 
 
                this.locations[locationReference.Id] = location;
            } 
        }

        internal Location GetSpecificLocation(int id)
        { 
            return GetSpecificLocation(id) as Location;
        } 
 
        internal Location GetSpecificLocation(int id)
        { 
            Fx.Assert(id >= 0 && ((this.locations == null && id == 0) || (this.locations != null && id < this.locations.Length)), "Id needs to be within bounds.");

            if (this.locations == null)
            { 
                return this.singleLocation;
            } 
            else 
            {
                return this.locations[id]; 
            }
        }

        // called for asynchronous argument resolution to collapse Location> to Location in the environment 
        internal void CollapseTemporaryResolutionLocations()
        { 
            if (this.locations == null) 
            {
                if (this.singleLocation != null && 
                    object.ReferenceEquals(this.singleLocation.TemporaryResolutionEnvironment, this))
                {
                    if (this.singleLocation.Value == null)
                    { 
                        this.singleLocation = (Location)this.singleLocation.CreateDefaultValue();
                    } 
                    else 
                    {
                        this.singleLocation = ((Location)this.singleLocation.Value).CreateReference(this.singleLocation.BufferGetsOnCollapse); 
                    }
                }
            }
            else 
            {
                for (int i = 0; i < this.locations.Length; i++) 
                { 
                    Location referenceLocation = this.locations[i];
 
                    if (referenceLocation != null &&
                        object.ReferenceEquals(referenceLocation.TemporaryResolutionEnvironment, this))
                    {
                        if (referenceLocation.Value == null) 
                        {
                            this.locations[i] = (Location)referenceLocation.CreateDefaultValue(); 
                        } 
                        else
                        { 
                            this.locations[i] = ((Location)referenceLocation.Value).CreateReference(referenceLocation.BufferGetsOnCollapse);
                        }
                    }
                } 
            }
        } 
 
        // Gets the location at this scope.  The caller verifies that ref.owner == this.definition.
        internal bool TryGetLocation(int id, out Location value) 
        {
            ThrowIfDisposed();

            value = null; 

            if (this.locations == null) 
            { 
                if (id == 0)
                { 
                    value = this.singleLocation;
                }
            }
            else 
            {
                if (this.locations.Length > id) 
                { 
                    value = this.locations[id];
                } 
            }

            return value != null;
        } 

        internal bool TryGetLocation(int id, Activity environmentOwner, out Location value) 
        { 
            ThrowIfDisposed();
 
            LocationEnvironment targetEnvironment = this;

            while (targetEnvironment != null && targetEnvironment.Definition != environmentOwner)
            { 
                targetEnvironment = targetEnvironment.Parent;
            } 
 
            if (targetEnvironment == null)
            { 
                value = null;
                return false;
            }
 
            value = null;
 
            if (id == 0 && targetEnvironment.locations == null) 
            {
                value = targetEnvironment.singleLocation; 
            }
            else if (targetEnvironment.locations != null && targetEnvironment.locations.Length > id)
            {
                value = targetEnvironment.locations[id]; 
            }
 
            return value != null; 
        }
 
        void ThrowIfDisposed()
        {
            if (isDisposed)
            { 
                throw FxTrace.Exception.AsError(
                    new ObjectDisposedException(this.GetType().FullName, SR.EnvironmentDisposed)); 
            } 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK