public bool Save()
        {
            bool success = true;

            using (m_savingLock.AcquireExclusiveUsing())
            {
                MySandboxGame.Log.WriteLine("Session snapshot save - START");
                using (var indent = MySandboxGame.Log.IndentUsing(LoggingOptions.NONE))
                {
                    Debug.Assert(!string.IsNullOrWhiteSpace(TargetDir), "TargetDir should always be correctly set!");

                    Directory.CreateDirectory(TargetDir);

                    MySandboxGame.Log.WriteLine("Checking file access for files in target dir.");
                    if (!CheckAccessToFiles())
                    {
                        return(false);
                    }

                    var saveAbsPath = SavingDir;
                    if (Directory.Exists(saveAbsPath))
                    {
                        Directory.Delete(saveAbsPath, true);
                    }
                    Directory.CreateDirectory(saveAbsPath);

                    try
                    {
                        ulong sectorSizeInBytes     = 0;
                        ulong checkpointSizeInBytes = 0;
                        ulong voxelSizeInBytes      = 0;
                        success = MyLocalCache.SaveSector(SectorSnapshot, SavingDir, Vector3I.Zero, out sectorSizeInBytes) &&
                                  MyLocalCache.SaveCheckpoint(CheckpointSnapshot, SavingDir, out checkpointSizeInBytes) &&
                                  MyLocalCache.SaveLastLoadedTime(TargetDir, DateTime.Now);
                        if (success)
                        {
                            foreach (var entry in CompressedVoxelSnapshots)
                            {
                                voxelSizeInBytes += (ulong)entry.Value.Length;
                                success           = success && SaveVoxelSnapshot(entry.Key, entry.Value);
                            }
                        }
                        if (success && Sync.IsServer)
                        {
                            success = MyLocalCache.SaveLastSessionInfo(TargetDir);
                        }

                        if (success)
                        {
                            SavedSizeInBytes = sectorSizeInBytes + checkpointSizeInBytes + voxelSizeInBytes;
                        }
                    }
                    catch (Exception ex)
                    {
                        MySandboxGame.Log.WriteLine("There was an error while saving snapshot.");
                        MySandboxGame.Log.WriteLine(ex);
                        ReportFileError(ex);
                        success = false;
                    }

                    if (success)
                    {
                        HashSet <string> saveFiles = new HashSet <string>();
                        foreach (var filepath in Directory.GetFiles(saveAbsPath))
                        {
                            string filename = Path.GetFileName(filepath);

                            var targetFile = Path.Combine(TargetDir, filename);
                            if (File.Exists(targetFile))
                            {
                                File.Delete(targetFile);
                            }

                            File.Move(filepath, targetFile);
                            saveFiles.Add(filename);
                        }

                        // Clean leftovers from previous saves
                        foreach (var filepath in Directory.GetFiles(TargetDir))
                        {
                            string filename = Path.GetFileName(filepath);
                            if (saveFiles.Contains(filename) || filename == MyTextConstants.SESSION_THUMB_NAME_AND_EXTENSION)
                            {
                                continue;
                            }

                            File.Delete(filepath);
                        }

                        Directory.Delete(saveAbsPath);
                    }
                    else
                    {
                        // We don't delete previous save, just the new one.
                        if (Directory.Exists(saveAbsPath))
                        {
                            Directory.Delete(saveAbsPath, true);
                        }
                    }
                }
                MySandboxGame.Log.WriteLine("Session snapshot save - END");
            }
            return(success);
        }
Пример #2
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.AddOrInsert(block.Value, block.Value.ForceOrder);
                        }
                        else
                        {
                            m_rootBlocks.AddOrInsert(block.Value, block.Value.ForceOrder);
                        }

                        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 (MyProfilerBlock profilerBlock in m_profilingBlocks.Values)
            {
                callCount += profilerBlock.NumCalls;

                profilerBlock.ManagedMemoryBytes[writeFrame] = profilerBlock.DeltaManagedB;
                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();

                if (ENABLE_PROFILER_LOG)
                {
                    if (profilerBlock.Elapsed.Miliseconds > LOG_THRESHOLD_MS)
                    {
                        m_logWriter.Write(DateTime.Now.ToString());
                        m_logWriter.Write("; ");
                        m_logWriter.Write(((int)profilerBlock.Elapsed.Miliseconds).ToString());
                        m_logWriter.Write("; ");
                        m_logWriter.Write(profilerBlock.Name);
                        MyProfilerBlock tempBlock = profilerBlock;
                        while (tempBlock.Parent != null)
                        {
                            tempBlock = tempBlock.Parent;
                            m_logWriter.Write(" <- " + tempBlock.Name);
                        }
                        m_logWriter.WriteLine("");
                    }
                }

                profilerBlock.Clear();
            }

            TotalCalls[writeFrame] = callCount;
            m_lastFrameIndex       = writeFrame;
        }
Пример #3
0
        public bool DoWork(int expectedID)
        {
            using (executionLock.AcquireExclusiveUsing())
            {
                if (expectedID < runCount)
                {
                    return(true);
                }
                if (work == null)
                {
                    return(false);
                }
                if (executing == work.Options.MaximumThreads)
                {
                    return(false);
                }
                executing++;
            }

            // associate the current task with this thread, so that Task.CurrentTask gives the correct result
            Stack <Task> tasks = null;

            if (!runningTasks.TryGet(Thread.CurrentThread, out tasks))
            {
                tasks = new Stack <Task>();
                runningTasks.Add(Thread.CurrentThread, tasks);
            }
            tasks.Push(new Task(this));

            // execute the task
            try { work.DoWork(); }
            catch (Exception e)
            {
                if (exceptionBuffer == null)
                {
                    var newExceptions = new List <Exception>();
                    Interlocked.CompareExchange(ref exceptionBuffer, newExceptions, null);
                }

                lock (exceptionBuffer)
                    exceptionBuffer.Add(e);
            }

            if (tasks != null)
            {
                tasks.Pop();
            }

            using (executionLock.AcquireExclusiveUsing())
            {
                executing--;
                if (executing == 0)
                {
                    if (exceptionBuffer != null)
                    {
                        exceptions.Add(runCount, exceptionBuffer.ToArray());
                    }

                    // wait for all children to complete
                    foreach (var child in children)
                    {
                        child.Wait();
                    }

                    runCount++;

                    // open the reset event, so tasks waiting on this one can continue
                    resetEvent.Set();

                    // wait for waiting tasks to all exit
                    while (waitCount > 0)
                    {
                        ;
                    }

                    if (Callback == null)
                    {
                        Requeue();
                    }
                    else
                    {
                        // if we have a callback, then queue for execution
                        CompletionCallbacks.Enqueue(this);
                    }

                    return(true);
                }
                return(false);
            }
        }
Пример #4
0
        public static MyStorageBase LoadFromFile(string absoluteFilePath, Dictionary <byte, byte> modifiers = null)
        {
            //get hash code
            MyVoxelObjectDefinition definition = new MyVoxelObjectDefinition(absoluteFilePath, modifiers);

            int sh = definition.GetHashCode();

            MyStorageBase result = null;

            if (UseStorageCache)
            {
                result = m_storageCache.Read(sh);
                if (result != null)
                {
                    result.Shared = true;
                    return(result);
                }
            }

            const string loadingMessage = "Loading voxel storage from file '{0}'";

            if (!MyFileSystem.FileExists(absoluteFilePath))
            {
                var oldPath = Path.ChangeExtension(absoluteFilePath, "vox");
                MySandboxGame.Log.WriteLine(string.Format(loadingMessage, oldPath));
                if (!MyFileSystem.FileExists(oldPath))
                {
                    //Debug.Fail("Voxel map could not be loaded! " + absoluteFilePath);
                    return(null);
                }
                UpdateFileFormat(oldPath);
            }
            else
            {
                MySandboxGame.Log.WriteLine(string.Format(loadingMessage, absoluteFilePath));
            }
            Debug.Assert(absoluteFilePath.EndsWith(MyVoxelConstants.FILE_EXTENSION));


            byte[] compressedData = null;
            using (var file = MyFileSystem.OpenRead(absoluteFilePath))
            {
                compressedData = new byte[file.Length];
                file.Read(compressedData, 0, compressedData.Length);
            }

            // JC: with Parallelization, it was crashing the game here, without lock
            using (m_loadCompressLock.AcquireExclusiveUsing())
            {
                result = Load(compressedData);
            }

            //change materials
            if (definition.Changes != null)
            {
                result.ChangeMaterials(definition.Changes);
            }

            if (UseStorageCache)
            {
                m_storageCache.Write(sh, result);
                result.Shared = true;
            }
            else
            {
                m_storageCache.Reset();
            }

            return(result);
        }
Пример #5
0
 /// <summary>
 /// Add a block to the profile.
 /// </summary>
 private void Grid_OnBlockAdded(IMySlimBlock slim)
 {
     using (lock_SlimBlocks.AcquireExclusiveUsing())
         SlimBlocks.mutable().Add(slim);
 }
Пример #6
0
 public static void RegisterSerializer <T>(Serializer <T> serializer)
 {
     using (Lock.AcquireExclusiveUsing())
         Serializers[typeof(T)] = serializer;
 }
Пример #7
0
 public ProceduralRoom()
 {
     Owner = null;
     using (MaxIDLock.AcquireExclusiveUsing())
         RoomID = MaxID++;
 }
Пример #8
0
        public bool DoWork(int expectedID)
        {
            using (executionLock.AcquireExclusiveUsing())
            {
                if (expectedID < runCount)
                {
                    return(true);
                }
                if (work == null)
                {
                    return(false);
                }
                if (executing == work.Options.MaximumThreads)
                {
                    return(false);
                }
                executing++;
            }

            // associate the current task with this thread, so that Task.CurrentTask gives the correct result
            Stack <Task> tasks = null;

            if (!runningTasks.TryGet(Thread.CurrentThread, out tasks))
            {
                tasks = new Stack <Task>();
                runningTasks.Add(Thread.CurrentThread, tasks);
            }
            tasks.Push(new Task(this));

            // execute the task
            try
            {
                // Set work data to running if able
                if (WorkData != null)
                {
                    WorkData.WorkState = ParallelTasks.WorkData.WorkStateEnum.RUNNING;
                }

                work.DoWork(WorkData);

                // Set work data to succeeded if able and not failed
                if (WorkData != null && WorkData.WorkState == ParallelTasks.WorkData.WorkStateEnum.RUNNING)
                {
                    WorkData.WorkState = ParallelTasks.WorkData.WorkStateEnum.SUCCEEDED;
                }
            }
            catch (Exception e)
            {
                if (exceptionBuffer == null)
                {
                    var newExceptions = new List <Exception>();
                    Interlocked.CompareExchange(ref exceptionBuffer, newExceptions, null);
                }

                lock (exceptionBuffer)
                    exceptionBuffer.Add(e);
            }

            if (tasks != null)
            {
                tasks.Pop();
            }

            using (executionLock.AcquireExclusiveUsing())
            {
                executing--;
                if (executing == 0)
                {
                    if (exceptionBuffer != null)
                    {
#if UNSHARPER
                        //workaround for volatile int to const int& casting problem in c++.
                        int val = runCount;
                        exceptions.Add(val, exceptionBuffer.ToArray());
#else
                        exceptions.Add(runCount, exceptionBuffer.ToArray());
#endif
                    }
                    // wait for all children to complete
                    foreach (var child in children)
                    {
                        child.Wait();
                    }

                    runCount++;

                    // open the reset event, so tasks waiting on this one can continue
                    resetEvent.Set();

                    // wait for waiting tasks to all exit
                    while (waitCount > 0)
                    {
                        ;
                    }

                    if (Callback == null && DataCallback == null)
                    {
                        Requeue();
                    }
                    else
                    {
                        // if we have a callback, then queue for execution
                        CompletionCallbacks.Add(this);
                    }

                    return(true);
                }
                return(false);
            }
        }