Beispiel #1
0
 /// <summary>Initialize the <see cref="RootBuildHandle"/> for all <see cref="EngineRegistry.Engines"/></summary>
 internal static void InitializeEngineBuildHandles()
 {
     foreach (var engine in EngineRegistry.Engines)
     {
         engine.RootBuildHandle = EngineBuildHandle.Create(EngineIdResolver(null, engine.Name));
     }
 }
Beispiel #2
0
        void SerializeExtern <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s)
            where TDoc : class
            where TCursor : class
        {
/*			var prototype = KSoft.Debug.TypeCheck.CastReference<BlamEngineSystem>(s.Owner);
 *                      if (s.IsReading)
 *                              Prototype = prototype;
 *                      else
 *                              Contract.Assert(prototype == Prototype);*/

            EngineBuildHandle.Serialize(s, ref mRootBuildHandleBaseline);

            using (s.EnterUserDataBookmark(this))
            {
                SerializeExternBody(s);
            }

            if (s.IsReading)
            {
                int expected_engine_index = Engine.RootBuildHandle.EngineIndex;
                int actual_engine_index   = RootBuildHandle.EngineIndex;
                KSoft.Debug.ValueCheck.AreEqual(
                    string.Format("{0} definition for {1} uses wrong engine id",
                                  GetType().Name, Engine.Name),
                    expected_engine_index, actual_engine_index);
            }
        }
Beispiel #3
0
        public static void Serialize <TDoc, TCursor>(IO.TagElementStream <TDoc, TCursor, string> s,
                                                     ref BlamEngineTargetHandle value)
            where TDoc : class
            where TCursor : class
        {
            bool reading = s.IsReading;

            var build = reading
                                ? EngineBuildHandle.None
                                : value.Build;
            var platform_index = reading
                                ? TypeExtensions.kNone
                                : value.TargetPlatformIndex;
            var rsrc_model_index = reading
                                ? TypeExtensions.kNone
                                : value.ResourceModelIndex;

            EngineBuildHandle.Serialize(s, ref build);
            if (!build.IsNone)
            {
                if (EngineTargetPlatform.SerializeId(s, "targetPlatform", ref platform_index, true))
                {
                    EngineRegistry.SerializeResourceModelId(s, "resourceModel", ref rsrc_model_index, true);
                }
            }

            if (reading)
            {
                value = new BlamEngineTargetHandle(build, platform_index, rsrc_model_index);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Creates an engine target handle using the build handlew, but with the platform and resource model set to NONE
        /// </summary>
        /// <param name="buildHandle"></param>
        /// <returns></returns>
        public static BlamEngineTargetHandle FromBuildHandleOnly(EngineBuildHandle buildHandle)
        {
            int target_platform_index = TypeExtensions.kNone;
            int resource_model_index  = TypeExtensions.kNone;

            return(new BlamEngineTargetHandle(buildHandle, target_platform_index, resource_model_index));
        }
Beispiel #5
0
        internal async Task RemoveReferenceAsync(EngineBuildHandle buildHandle)
        {
            Contract.Requires <ArgumentNullException>(!buildHandle.IsNone);

            bool unload_externs          = !Prototype.SystemMetadata.KeepExternsLoaded;
            var  update_refs_side_effect = UpdateReferenceSideEffect.None;

            if (Prototype.SystemRequiresReferenceTracking)
            {
                update_refs_side_effect = UpdateReferencesByBuild(-1, buildHandle);
                unload_externs          = mReferencesByBuildCounts.Count == 0;

                // This will remove the EngineSystem from the active systems, meaning UnloadExterns will be safe
                // to call without locking or such as nothing can call LoadExterns on this object anymore
                if (unload_externs)
                {
                    Engine.CloseSystem(this);
                    mActiveInBlamEngine = false;
                }
            }
            else
            {
                update_refs_side_effect = UpdateReferencesByBuild(-1, buildHandle);
                unload_externs          = update_refs_side_effect == UpdateReferenceSideEffect.OldBuildUnreferenced;

                // This will remove the EngineSystem from the active systems, meaning UnloadExterns will be safe
                // to call without locking or such as nothing can call LoadExterns on this object anymore
                if (unload_externs)
                {
                    Engine.CloseSystem(this);
                    mActiveInBlamEngine = false;
                }
            }

            if (unload_externs)
            {
                // mExternIOTask should previously be a Task for LoadExterns
                bool didntTimeout = WaitForExternsIO();
                Contract.Assert(didntTimeout);

                if (mExternIOTask != null)
                {
                    throw new InvalidOperationException(string.Format(Util.InvariantCultureInfo,
                                                                      "Tried to perform an externs IO task while one was in flight under {0}",
                                                                      this.Prototype.Engine));
                }

                mExternIOTask = Task.Run((Action)UnloadExternsBegin);
                await mExternIOTask.ConfigureAwait(false);

                mExternIOTask = null;
            }

            // #REVIEW_BLAM: also don't do this if Prototype.SystemRequiresReferenceTracking==false?
            // reminder: we're calling this AFTER externs are unloaded...be sure your dispose code handles this
            if (update_refs_side_effect == UpdateReferenceSideEffect.OldBuildUnreferenced)
            {
                DisposeFromOldBuildReference(buildHandle);
            }
        }
        EngineSystemReference(bool dummy)
        {
            Util.MarkUnusedVariable(ref dummy);

            mSystem      = null;
            mBuildHandle = EngineBuildHandle.None;
        }
Beispiel #7
0
        public BlamEngineTargetHandle(EngineBuildHandle buildHandle, int platformIndex, int resourceModelIndex)
        {
            Contract.Requires <ArgumentOutOfRangeException>(EngineTargetPlatform.IsValidIndex(platformIndex));
            Contract.Requires <ArgumentOutOfRangeException>(EngineRegistry.IsValidResourceModelIndex(resourceModelIndex) ||
                                                            (platformIndex.IsNone() && resourceModelIndex.IsNone()));

            InitializeHandle(out mHandle, buildHandle, platformIndex, resourceModelIndex);
        }
Beispiel #8
0
        /// <summary>Tries to get an <see cref="EngineSystemBase"/> associated with a registered engine</summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="forBuild">The build requesting this system</param>
        /// <returns><see cref="EngineSystemReference{T}.None"/> if the engine doesn't support the requested system</returns>
        public static EngineSystemReference <T> TryGetSystem <T>(EngineBuildHandle forBuild)
            where T : EngineSystemBase
        {
            Contract.Requires <ArgumentNullException>(!forBuild.IsNone);

            var engine = Engines[forBuild.EngineIndex];

            return(engine.TryGetSystem <T>(forBuild));
        }
 /// <summary>Initialize the <see cref="BranchHandle"/> and the handles for all <see cref="Revisions"/></summary>
 /// <param name="engineIndex"></param>
 /// <param name="branchIndex"></param>
 internal void InitializeBuildHandles(int engineIndex, int branchIndex)
 {
     BranchHandle = EngineBuildHandle.Create(engineIndex, branchIndex);
     foreach (var revisn in Revisions)
     {
         int revisn_index = RevisionIdResolver(this, revisn.Version);
         var handle       = EngineBuildHandle.Create(engineIndex, branchIndex, revisn_index);
         revisn.InitializeBuildHandle(handle);
     }
 }
Beispiel #10
0
        public EngineSystemReference <T> GetSystem <T>(EngineBuildHandle forBuild)
            where T : EngineSystemBase
        {
            Contract.Requires <ArgumentNullException>(!forBuild.IsNone);
            Contract.Requires(forBuild.EngineIndex == RootBuildHandle.EngineIndex);

            var system_guid = EngineSystemAttribute.GetSystemGuid <T>();
            var system      = (T)GetSystem(system_guid, forBuild);

            return(new EngineSystemReference <T>(system, forBuild));
        }
Beispiel #11
0
        /// <summary>Only call me if you are <see cref="EngineSystemAttribute.NewInstance"/></summary>
        /// <param name="prototype">The <see cref="BlamEngineSystem"/> used to describe this instance</param>
        internal void InitializeForNewInstance(BlamEngineSystem prototype)
        {
            Prototype                = prototype;
            mActiveInBlamEngine      = true;
            mRootBuildHandleBaseline = Prototype.Engine.RootBuildHandle;

            // ReSharper disable once InconsistentlySynchronizedField - method is construction, don't need a lock
            if (Prototype.SystemRequiresReferenceTracking)
            {
                mReferencesByBuildCounts = new Dictionary <EngineBuildHandle, int>();
            }
        }
Beispiel #12
0
        internal EngineSystemReference(EngineSystemBase system, EngineBuildHandle buildHandle)
        {
            Contract.Assume(system != null);
            Contract.Assume(!buildHandle.IsNone);

            mSystem      = system;
            mBuildHandle = buildHandle;

#pragma warning disable 4014
            system.AddReferenceAsync(buildHandle);
#pragma warning restore 4014
        }
Beispiel #13
0
        int UpdateReferencesByHandle(int amount, EngineBuildHandle handle, ref UpdateReferenceSideEffect sideEffect)
        {
            if (Prototype.SystemRequiresReferenceTracking)
            {
                if (!handle.IsNone)
                {
                    int ref_count;
                    if (!mReferencesByBuildCounts.TryGetValue(handle, out ref_count))
                    {
                        mReferencesByBuildCounts[handle] = 0;
                    }

                    int ref_count_update = ref_count + amount;
                    if (sideEffect == UpdateReferenceSideEffect.None)
                    {
                        if (ref_count_update == 0)                              // the update closed all existing references...
                        {
                            sideEffect = UpdateReferenceSideEffect.OldBuildUnreferenced;
                        }
                        else if (ref_count == 0)                                // existing count is 0, this is the first reference
                        {
                            sideEffect = UpdateReferenceSideEffect.NewBuildReferenced;
                        }
                    }

                    return(mReferencesByBuildCounts[handle] = ref_count_update);
                }
            }
            else
            {
                int ref_count        = Interlocked.CompareExchange(ref mNonBuildSpecificReferences, 0, 0);
                int ref_count_update = Interlocked.Add(ref mNonBuildSpecificReferences, amount);
                if (sideEffect == UpdateReferenceSideEffect.None)
                {
                    if (ref_count_update == 0)                          // the update closed all existing references...
                    {
                        sideEffect = UpdateReferenceSideEffect.OldBuildUnreferenced;
                    }
                    else if (ref_count == 0)                            // existing count is 0, this is the first reference
                    {
                        sideEffect = UpdateReferenceSideEffect.NewBuildReferenced;
                    }
                }

                return(ref_count_update);
            }

            return(0);
        }
Beispiel #14
0
        UpdateReferenceSideEffect UpdateReferencesByBuild(int amount, EngineBuildHandle buildHandle)
        {
            var side_effect = UpdateReferenceSideEffect.None;

            if (Prototype.SystemRequiresReferenceTracking)
            {
                EngineBuildHandle engine, branch;
                buildHandle.ExtractHandles(out engine, out branch);

                int revisn_count, branch_count, engine_count;
                lock (mReferencesByBuildCounts)
                {
                    revisn_count = UpdateReferencesByHandle(amount, buildHandle, ref side_effect);
                    branch_count = UpdateReferencesByHandle(amount, branch, ref side_effect);
                    engine_count = UpdateReferencesByHandle(amount, engine, ref side_effect);
                }

                // Validate that a RemoveReference hasn't made a count go negative (ie, there was an extra call)
                if (amount < 0)
                {
                    if (revisn_count < 0 || branch_count < 0 || engine_count < 0)
                    {
                        throw new InvalidOperationException(string.Format(
                                                                "Extra or bad RemoveReference call detected for {0} using the handle {1}",
                                                                Prototype, buildHandle.ToDisplayString()));
                    }
                }
            }
            else
            {
                int new_count = UpdateReferencesByHandle(amount, EngineBuildHandle.None, ref side_effect);

                // Validate that a RemoveReference hasn't made a count go negative (ie, there was an extra call)
                if (amount < 0)
                {
                    if (new_count < 0)
                    {
                        throw new InvalidOperationException(string.Format(
                                                                "Extra or bad RemoveReference call detected for {0}",
                                                                Prototype));
                    }
                }
            }

            return(side_effect);
        }
Beispiel #15
0
        EngineSystemBase GetSystem(Values.KGuid systemGuid, EngineBuildHandle forBuild)
        {
            if (!SupportsSystem(systemGuid))
            {
                string system_display_name = EngineRegistry.GetSystemDebugDisplayString(systemGuid);

                string msg = string.Format("{0} doesn't support the system {1}",
                                           forBuild.ToDisplayString(), system_display_name);

                throw new InvalidOperationException(msg);
            }

            var system_metadata = EngineRegistry.TryGetRegisteredSystem(systemGuid);

            Contract.Assume(system_metadata != null);

            return(GetNewOrExistingSystem(system_metadata));
        }
Beispiel #16
0
        //internal uint Handle { get { return mHandle; } }

        static void InitializeHandle(out uint handle,
                                     EngineBuildHandle buildHandle, int platformIndex, int resourceModelIndex)
        {
            if (platformIndex.IsNone() && resourceModelIndex.IsNone())
            {
                resourceModelIndex = 0;
            }

            var encoder = new Bitwise.HandleBitEncoder();

            EngineRegistry.BitEncodeResourceModelIndex(ref encoder, resourceModelIndex);
            EngineTargetPlatform.BitEncodeIndex(ref encoder, platformIndex);
            encoder.Encode32(buildHandle.Handle, EngineBuildHandle.Bitmask);

            Contract.Assert(encoder.UsedBitCount == BlamEngineTargetHandle.BitCount);

            handle = encoder.GetHandle32();
        }
Beispiel #17
0
        internal async Task AddReferenceAsync(EngineBuildHandle buildHandle)
        {
            Contract.Requires <ArgumentNullException>(!buildHandle.IsNone);
            Contract.Assert(mActiveInBlamEngine);

            // #REVIEW_BLAM: this isn't an optimal setup
            bool load_externs            = true;
            var  update_refs_side_effect = UpdateReferenceSideEffect.None;

            if (Prototype.SystemRequiresReferenceTracking)
            {
                load_externs            = mReferencesByBuildCounts.Count == 0;
                update_refs_side_effect = UpdateReferencesByBuild(+1, buildHandle);
            }
            else
            {
                update_refs_side_effect = UpdateReferencesByBuild(+1, buildHandle);
                load_externs            = update_refs_side_effect == UpdateReferenceSideEffect.NewBuildReferenced;
            }

            if (load_externs)
            {
                Contract.Assert(mExternIOTask == null);
                if (mExternIOTask != null)
                {
                    throw new InvalidOperationException(string.Format(Util.InvariantCultureInfo,
                                                                      "Tried to perform an externs IO task while one was in flight under {0}",
                                                                      this.Prototype.Engine));
                }

                mExternIOTask = Task.Run((Action)LoadExternsBegin);
                await mExternIOTask.ConfigureAwait(false);

                mExternIOTask = null;
            }

            // #REVIEW_BLAM: also don't do this if Prototype.SystemRequiresReferenceTracking==false?
            if (update_refs_side_effect == UpdateReferenceSideEffect.NewBuildReferenced)
            {
                InitializeForNewBuildReference(buildHandle);
            }
        }
Beispiel #18
0
 EngineSystemReference(bool dummy)
 {
     mSystem      = null;
     mBuildHandle = EngineBuildHandle.None;
 }
Beispiel #19
0
 /// <summary>Create a new reference to this system using an existing build handle</summary>
 /// <param name="buildHandle">The engine build which is in need of this system</param>
 /// <returns></returns>
 public EngineSystemReference NewReference(EngineBuildHandle buildHandle) =>
 new EngineSystemReference(this, buildHandle);
Beispiel #20
0
 /// <summary>Create a new reference to this system using an existing build handle</summary>
 /// <param name="buildHandle">The engine build which is in need of this system</param>
 /// <returns></returns>
 public EngineSystemReference NewReference(EngineBuildHandle buildHandle)
 {
     return(new EngineSystemReference(this, buildHandle));
 }
Beispiel #21
0
 /// <summary>Handle a specific build being referenced for the first time</summary>
 /// <param name="newBuildHandle">Handle that caused a build reference to be first created</param>
 protected virtual void InitializeForNewBuildReference(EngineBuildHandle newBuildHandle)
 {
 }
Beispiel #22
0
 /// <summary>Handle a specific build being unreferenced for the last time</summary>
 /// <param name="oldBuildHandle">Handle that caused a build reference to be disposed</param>
 protected virtual void DisposeFromOldBuildReference(EngineBuildHandle oldBuildHandle)
 {
 }
 /// <summary>Initialize the <see cref="BuildHandle"/></summary>
 /// <param name="handle"></param>
 internal void InitializeBuildHandle(EngineBuildHandle handle)
 {
     BuildHandle = handle;
 }