示例#1
0
        public void InitFromGrids(MyObjectBuilder_CubeGrid primaryGrid, ICollection <MyObjectBuilder_CubeGrid> allGrids)
        {
            try
            {
                if (!m_lock.TryAcquireExclusive())
                {
                    m_lock.AcquireExclusive();
                    if (m_initFromGrid)
                    {
                        return;
                    }
                }
                // References to BlockInfo aren't threadsafe, so create a new one for this purpose.
                var blockInfo = new BlockSetInfo();
                ComputeBlockMap(primaryGrid, allGrids, blockInfo);
                ComputeReservedSpace(primaryGrid, allGrids, blockInfo);
                ComputeMountPoints(primaryGrid, allGrids, blockInfo);
                blockInfo.UpdateCache();
                BlockSetInfo = blockInfo;

                m_initFromGrid = true;
            }
            finally
            {
                m_lock.ReleaseExclusive();
            }
        }
示例#2
0
 private static void Loop()
 {
     if (Lock.TryAcquireExclusive())
     {
         WriteItems();
         Lock.ReleaseExclusive();
     }
 }
示例#3
0
 private static void ReleaseLock()
 {
     while (_lock?.TryAcquireExclusive() == false)
     {
         _lock?.ReleaseExclusive();
     }
     _lock?.ReleaseExclusive();
 }
示例#4
0
        public void Update100()
        {
            if (m_beaconLight != null && m_beaconLight.Intensity != 0f)
            {
                m_beaconLight.GlareIntensity     = 0f;
                m_beaconLight.Intensity          = 0f;
                m_beaconLight.ReflectorIntensity = 0f;
                m_beaconLight.UpdateLight();
            }

            if (myLock.TryAcquireExclusive())
            {
                if (m_node == null)
                {
                    if (!Registrar.TryGetValue(Entity, out m_node))
                    {
                        Log.DebugLog("failed to get node");
                        return;
                    }
                }
                if (m_node.Storage == null)
                {
                    Log.DebugLog("no storage");
                    return;
                }

                // actions on main thread
                CheckCustomInfo();
                //if (myLastSeen.Count > 0)
                //{
                //	Log.DebugLog("sending to storage: " + myLastSeen.Count);
                //	m_node.Storage.Receive(myLastSeen);
                //}

                myThread.EnqueueAction(Update_OnThread);
            }
        }
示例#5
0
        private void CommitInternal()
        {
            Debug.Assert(!EnableAsserts || OwnerThread == Thread.CurrentThread);
            Debug.Assert(m_currentProfilingStack.Count == 0, "CommitFrame cannot be called when there are some opened blocks, it must be outside blocks!");
            m_currentProfilingStack.Clear();

            if (m_blocksToAdd.Count > 0)
            {
                using (m_historyLock.AcquireExclusiveUsing())
                {
                    foreach (var block in m_blocksToAdd)
                    {
                        if (block.Value.Parent != null)
                        {
                            block.Value.Parent.Children.Add(block.Value);
                        }
                        else
                        {
                            m_rootBlocks.Add(block.Value);
                        }

                        m_profilingBlocks.Add(block.Key, block.Value);
                    }
                    m_blocksToAdd.Clear();
                    Interlocked.Exchange(ref m_remainingWindow, UPDATE_WINDOW - 1); // We have lock, no one is in draw, reset window
                }
            }
            else if (m_historyLock.TryAcquireExclusive())
            {
                Interlocked.Exchange(ref m_remainingWindow, UPDATE_WINDOW - 1); // We have lock, no one is in draw, reset window
                m_historyLock.ReleaseExclusive();
            }
            else if (Interlocked.Decrement(ref m_remainingWindow) < 0)
            {
                // Window is empty, wait for lock and reset it
                using (m_historyLock.AcquireExclusiveUsing())
                {
                    Interlocked.Exchange(ref m_remainingWindow, UPDATE_WINDOW - 1); // We have lock, no one is in draw, reset window
                }
            }

            int callCount = 0;

            m_levelLimit = m_newLevelLimit;

            int writeFrame = (m_lastFrameIndex + 1) % MyProfiler.MAX_FRAMES;

            foreach (MyProfiler.MyProfilerBlock profilerBlock in m_profilingBlocks.Values)
            {
                callCount += profilerBlock.NumCalls;

                profilerBlock.ManagedMemory[writeFrame] = profilerBlock.ManagedDeltaMB;
                if (MemoryProfiling)
                {
                    profilerBlock.ProcessMemory[writeFrame] = profilerBlock.ProcessDeltaMB;
                }
                profilerBlock.NumCallsArray[writeFrame] = profilerBlock.NumCalls;
                profilerBlock.CustomValues[writeFrame]  = profilerBlock.CustomValue;
                profilerBlock.Miliseconds[writeFrame]   = (float)profilerBlock.Elapsed.Miliseconds;

                // Unused
                profilerBlock.averageMiliseconds = 0.9f * profilerBlock.averageMiliseconds + 0.1f * (float)profilerBlock.Elapsed.Miliseconds;
                //profilerBlock.NumChildCalls = profilerBlock.GetNumChildCalls();

                profilerBlock.Clear();
            }

            TotalCalls[writeFrame] = callCount;
            m_lastFrameIndex       = writeFrame;
        }
示例#6
0
        /// <summary>
        /// Rebuilds our conveyor dictionary.  This lets us check if two entities are connected by conveyors quickly.
        /// </summary>
        /// <param name="entities"></param>
        public static void RebuildConveyorList(HashSet <IMyEntity> entities)
        {
            if (!m_busyLock.TryAcquireExclusive())
            {
                Logging.Instance.WriteLine(string.Format("REBUILD Busy.  Last Rebuild: {0}s", (DateTime.Now - m_lastRebuild).TotalSeconds));
                return;
            }

            m_lastRebuild = DateTime.Now;
            DateTime start = DateTime.Now;

            try
            {
                m_conveyorCache.Clear();
                m_conveyorConnected.Clear();
                foreach (IMyEntity entity in entities)
                {
                    if (!(entity is IMyCubeGrid))
                    {
                        continue;
                    }

                    MyCubeGrid grid = (MyCubeGrid)entity;
                    if (grid.Closed || grid.Physics == null)
                    {
                        continue;
                    }

                    MyObjectBuilder_CubeGrid gridObject = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder();

                    if (gridObject == null || gridObject.ConveyorLines == null)
                    {
                        continue;
                    }

                    foreach (MyObjectBuilder_ConveyorLine line in gridObject.ConveyorLines)
                    {
                        IMySlimBlock slimBlockStart = grid.GetCubeBlock((Vector3I)line.StartPosition);
                        if (slimBlockStart == null || slimBlockStart.FatBlock == null || !slimBlockStart.FatBlock.IsFunctional)
                        {
                            continue;
                        }

                        IMySlimBlock slimBlockEnd = grid.GetCubeBlock((Vector3I)line.EndPosition);
                        if (slimBlockEnd == null || slimBlockEnd.FatBlock == null || !slimBlockEnd.FatBlock.IsFunctional)
                        {
                            continue;
                        }

                        ConnectConveyorBlocks(slimBlockStart, slimBlockEnd);
                    }

                    if (m_conveyorConnected.ContainsKey(grid.EntityId))
                    {
                        long[] connectedBlockId = m_conveyorConnected[grid.EntityId];
                        m_conveyorConnected.Remove(grid.EntityId);
                        ConnectConveyorBlocks(connectedBlockId);
                    }
                }

                foreach (KeyValuePair <long, long[]> p in m_conveyorConnected)
                {
                    ConnectConveyorBlocks(p.Value);
                }

                var creatingCache = new Dictionary <long, HashSet <long> >(m_conveyorCache);
                using (m_lock.AcquireExclusiveUsing())
                {
                    m_creatingCache = creatingCache;
                }
            }
            catch (Exception ex)
            {
                Logging.Instance.WriteLine(String.Format("RebuildConveyorList: {0}", ex.ToString()));
            }
            finally
            {
                m_busyLock.ReleaseExclusive();
                Logging.Instance.WriteLine(string.Format("REBUILD Inventory: {0}ms", (DateTime.Now - start).TotalMilliseconds));
            }
        }
示例#7
0
        /// <summary>
        /// Test a path between current position and destination.
        /// </summary>
        private void TestPath(Vector3D destination, MyEntity ignoreEntity, byte runId, bool isAlternate, bool tryAlternates, bool slowDown = false)
        {
            m_logger.debugLog("m_navBlock == null", Logger.severity.FATAL, condition: m_navBlock == null);

            if (runId != m_runId)
            {
                m_logger.debugLog("destination changed, abort", Logger.severity.DEBUG);
                return;
            }

            if (!lock_testPath.TryAcquireExclusive())
            {
                m_logger.debugLog("Already running, requeue (destination:" + destination + ", ignoreEntity: " + ignoreEntity.getBestName() + ", runId :" + runId
                                  + ", isAlternate: " + isAlternate + ", tryAlternates: " + tryAlternates + ", slowDown: " + slowDown + ")");
                LockedQueue <Action> queue = isAlternate ? m_pathLow : m_pathHigh;
                queue.Enqueue(() => TestPath(destination, ignoreEntity, runId, isAlternate, tryAlternates));
                return;
            }
            try
            {
                if (m_grid != m_navBlock.Grid)
                {
                    m_logger.debugLog("Grid has changed, from " + m_grid.getBestName() + " to " + m_navBlock.Grid.getBestName() + ", nav block: " + m_navBlock.Block.getBestName(), Logger.severity.WARNING);
                    return;
                }
                m_logger.debugLog("Running, (destination:" + destination + ", ignoreEntity: " + ignoreEntity.getBestName() + ", runId :" + runId
                                  + ", isAlternate: " + isAlternate + ", tryAlternates: " + tryAlternates + ", slowDown: " + slowDown + ")");

                MyEntity obstructing;
                Vector3? pointOfObstruction;

                if (!isAlternate && !m_ignoreAsteroid)
                {
                    if (slowDown)
                    {
                        if ((m_planetCheckSpeed.CurrentState & PlanetChecker.State.Blocked) != 0)
                        {
                            float speed = Vector3.Distance(m_planetCheckSpeed.ObstructionPoint, m_navBlock.WorldPosition) * 0.1f;
                            if (speed < 1f)
                            {
                                speed = 1f;
                            }
                            m_navSet.Settings_Task_NavWay.SpeedTarget = speed;
                            m_logger.debugLog("Path blocked by planet, set SpeedTarget to " + speed + ", obstructed by planet", Logger.severity.TRACE);
                            return;
                        }
                    }
                    else
                    {
                        if ((m_planetCheckDest.CurrentState & PlanetChecker.State.Blocked) != 0 &&
                            // planet checker is using an older displacement so verify that obstruction is closer than destination
                            Vector3D.DistanceSquared(m_navBlock.WorldPosition, m_planetCheckDest.ObstructionPoint) < Vector3D.DistanceSquared(m_navBlock.WorldPosition, destination))
                        {
                            m_logger.debugLog("path blocked by planet, to destination: " + (destination - m_navBlock.WorldPosition) + ", to obstruction: " + (m_planetCheckDest.ObstructionPoint - m_navBlock.WorldPosition));

                            if (m_pathState < PathState.Searching)
                            {
                                m_pathState = PathState.Searching;
                            }
                            obstructing = m_planetCheckDest.gravcomp;

                            Vector3 direction = Vector3.Normalize(m_navBlock.WorldPosition - obstructing.GetCentre());
                            pointOfObstruction = m_planetCheckDest.ObstructionPoint + direction * 1e3f;

                            float distance = Vector3.Distance(m_navBlock.WorldPosition, pointOfObstruction.Value);

                            MoveObstruction = obstructing;
                            m_pathHigh.Clear();
                            ClearAltPath();
                            if ((m_planetCheckDest.CurrentState & PlanetChecker.State.BlockedPath) != 0)
                            {
                                FindAlternate_AroundObstruction(pointOfObstruction.Value - m_navBlock.WorldPosition, new Vector3[] { direction }, 1e4f, runId);
                            }
                            else                             // blocked by gravity
                            {
                                FindAlternate_AroundObstruction(pointOfObstruction.Value - m_navBlock.WorldPosition, new Vector3[] { direction }, 1e6f, runId);
                            }
                            m_pathLow.Enqueue(() => {
                                if (m_altPath_AlternatesFound != 0)
                                {
                                    SetWaypoint();
                                }
                                RunItem();
                            });
                            m_pathLow.Enqueue(() => m_pathState = PathState.Path_Blocked);

                            return;
                        }
                    }
                }

                // for alternates, check that it can be better than current value
                if (isAlternate)
                {
                    float distToWaypointSquared = (float)Vector3D.DistanceSquared(m_navBlock.WorldPosition, destination);
                    if (distToWaypointSquared * WaypointDistanceBias * WaypointDistanceBias > m_altPath_PathValue * m_altPath_PathValue)
                    {
                        m_logger.debugLog("no point in checking alternate path, bias is too high", Logger.severity.TRACE);
                        m_logger.debugLog("no alternate, yet path value is set", Logger.severity.ERROR, condition: m_altPath_AlternatesFound == 0);
                        IncrementAlternatesFound();
                        return;
                    }
                }

                if (m_pathChecker.TestFast(m_navBlock, destination, m_ignoreAsteroid, ignoreEntity, m_landing))
                {
                    m_logger.debugLog("path is clear (fast)", Logger.severity.TRACE);
                    PathClear(ref destination, runId, isAlternate, slowDown);
                    return;
                }

                if (m_pathChecker.TestSlow(out obstructing, out pointOfObstruction))
                {
                    m_logger.debugLog("path is clear (slow)", Logger.severity.TRACE);
                    PathClear(ref destination, runId, isAlternate, slowDown);
                    return;
                }

                if (runId != m_runId)
                {
                    m_logger.debugLog("destination changed, abort", Logger.severity.DEBUG);
                    return;
                }

                if (slowDown)
                {
                    float speed = Vector3.Distance(pointOfObstruction.Value, m_navBlock.WorldPosition) * 0.1f;
                    if (speed < 1f)
                    {
                        speed = 1f;
                    }
                    IMyEntity destEntity = m_navSet.Settings_Current.DestinationEntity;
                    if (destEntity != null)
                    {
                        destEntity = destEntity.GetTopMostParent();
                    }
                    if (obstructing.GetTopMostParent() == destEntity)
                    {
                        m_navSet.Settings_Task_NavWay.SpeedMaxRelative = speed;
                        m_logger.debugLog("Set SpeedMaxRelative to " + speed + ", obstructing: " + obstructing.getBestName() + ", DestinationEntity: " + m_navSet.Settings_Current.DestinationEntity.getBestName(), Logger.severity.TRACE);
                    }
                    else
                    {
                        m_navSet.Settings_Task_NavWay.SpeedTarget = speed;
                        m_logger.debugLog("Set SpeedTarget to " + speed + ", obstructing: " + obstructing.getBestName() + ", DestinationEntity: " + m_navSet.Settings_Current.DestinationEntity.getBestName(), Logger.severity.TRACE);
                    }
                    return;
                }

                if (m_pathState < PathState.Searching)
                {
                    m_pathState = PathState.Searching;
                }

                m_logger.debugLog("path is blocked by " + obstructing.getBestName() + " at " + pointOfObstruction + ", ignoreEntity: " + ignoreEntity.getBestName(), isAlternate ? Logger.severity.TRACE : Logger.severity.DEBUG);
                m_logger.debugLog("grid: " + obstructing.GetTopMostParent().DisplayName, isAlternate ? Logger.severity.TRACE : Logger.severity.DEBUG, condition: obstructing is IMyCubeBlock);

                if (isAlternate && m_altPath_AlternatesFound != 0)
                {
                    IncrementAlternatesFound();
                }

                if (tryAlternates)
                {
                    //float angle = m_navSet.Settings_Current.DistanceAngle;
                    //if (angle > 0.1f && CanRotate)
                    //{
                    //	m_logger.debugLog("wait for rotation", "TestPath()");
                    //	return;
                    //}

                    if (m_navSet.Settings_Task_NavEngage.NavigatorMover != m_navSet.Settings_Current.NavigatorMover)
                    {
                        m_logger.debugLog("obstructed while flying to a waypoint, throwing it out and starting over", Logger.severity.DEBUG);
                        m_navSet.OnTaskComplete_NavWay();
                        return;
                    }

                    ClearAltPath();
                    MoveObstruction = obstructing;
                    TryAlternates(runId, pointOfObstruction.Value, obstructing);
                }
            }
            finally
            {
                lock_testPath.ReleaseExclusive();
                RunItem();
            }
        }
示例#8
0
        /// <summary>
        /// Run the autopilot
        /// </summary>
        private void UpdateThread()
        {
            if (!lock_execution.TryAcquireExclusive())
            {
                return;
            }
            try
            {
                if (Globals.UpdateCount > m_nextCustomInfo)
                {
                    m_nextCustomInfo = Globals.UpdateCount + 10ul;
                    UpdateCustomInfo();
                }

                switch (m_state)
                {
                case State.Disabled:
                    if (CheckControl())
                    {
                        m_state = State.Enabled;
                    }
                    return;

                case State.Enabled:
                    if (CheckControl())
                    {
                        break;
                    }
                    m_state = State.Disabled;
                    return;

                case State.Player:
                    // wait for player to give back control, do not reset
                    if (MyAPIGateway.Players.GetPlayerControllingEntity(m_controlledGrid) == null)
                    {
                        m_state = State.Enabled;
                    }
                    return;

                case State.Halted:
                    if (!m_block.AutopilotControl || Globals.ElapsedTime > m_endOfHalt)
                    {
                        m_state = State.Disabled;
                    }
                    return;

                case State.Closed:
                    return;

                default:
                    throw new Exception("Case not implemented: " + m_state);
                }

                if (MyAPIGateway.Players.GetPlayerControllingEntity(m_controlledGrid) != null)
                {
                    m_state = State.Player;
                    return;
                }

                EnemyFinder ef = m_navSet.Settings_Current.EnemyFinder;
                if (ef != null)
                {
                    ef.Update();
                }

                if (m_navSet.Settings_Current.WaitUntil > Globals.ElapsedTime)
                {
                    return;
                }

                if (MoveAndRotate())
                {
                    return;
                }

                if (m_autopilotActions != null)
                {
                    while (true)
                    {
                        if (!m_autopilotActions.MoveNext())
                        {
                            Log.DebugLog("finder: " + m_navSet.Settings_Current.EnemyFinder);
                            m_autopilotActions = null;
                            return;
                        }
                        m_autopilotActions.Current.Invoke(m_pathfinder);
                        if (m_navSet.Settings_Current.WaitUntil > Globals.ElapsedTime)
                        {
                            Log.DebugLog("now waiting until " + m_navSet.Settings_Current.WaitUntil);
                            return;
                        }
                        if (m_navSet.Settings_Current.NavigatorMover != null)
                        {
                            Log.DebugLog("now have a navigator mover: " + m_navSet.Settings_Current.NavigatorMover);
                            return;
                        }
                    }
                }

                if (RotateOnly())
                {
                    return;
                }

                TimeSpan nextInstructions = m_previousInstructions + TimeSpan.FromSeconds(m_navSet.Settings_Current.Complaint != InfoString.StringId.None || ef != null ? 60d : 1d);
                if (nextInstructions > Globals.ElapsedTime)
                {
                    Log.DebugLog("Delaying instructions until " + nextInstructions, Logger.severity.INFO);
                    m_navSet.Settings_Task_NavWay.WaitUntil = nextInstructions;
                    return;
                }
                Log.DebugLog("enqueing instructions", Logger.severity.DEBUG);
                m_previousInstructions = Globals.ElapsedTime;

                m_autopilotActions = m_commands.GetActions();

                if (m_autopilotActions == null || m_autopilotActions.IsEmpty)
                {
                    ReleaseControlledGrid();
                }
                m_navSet.OnStartOfCommands();
                m_mover.MoveAndRotateStop(false);

                if (m_commands.HasSyntaxErrors)
                {
                    m_navSet.Settings_Task_NavWay.WaitUntil = Globals.ElapsedTime + TimeSpan.FromMinutes(1d);
                }
            }
            catch (Exception ex)
            {
                Log.AlwaysLog("Commands: " + m_commands.Commands, Logger.severity.DEBUG);
                Log.AlwaysLog("Exception: " + ex, Logger.severity.ERROR);
                m_state = State.Halted;
            }
            finally
            { lock_execution.ReleaseExclusive(); }
        }