示例#1
0
 public static void Log(this Object obj, string msg)
 {
     Debug.Log("[MKS] [" + (new StackTrace()).GetFrame(1).GetMethod().Name + "] " + msg);
 }
        public static List <BurstCompileTarget> FindExecuteMethods(AssembliesType assemblyTypes)
        {
            var methodsToCompile    = new List <BurstCompileTarget>();
            var methodsToCompileSet = new HashSet <MethodInfo>();

            var valueTypes          = new List <TypeToVisit>();
            var interfaceToProducer = new Dictionary <Type, Type>();

            var assemblyList = GetAssemblyList(assemblyTypes);
            //Debug.Log("Filtered Assembly List: " + string.Join(", ", assemblyList.Select(assembly => assembly.GetName().Name)));

            // Find all ways to execute job types (via producer attributes)
            var typesVisited = new HashSet <string>();
            var typesToVisit = new HashSet <string>();

            foreach (var assembly in assemblyList)
            {
                var types = new List <Type>();
                try
                {
                    types.AddRange(assembly.GetTypes());
                    // Collect all generic type instances (excluding indirect instances)
                    CollectGenericTypeInstances(assembly, types);
                }
                catch (Exception ex)
                {
                    Debug.LogWarning("Unexpected exception while collecting types in assembly `" + assembly.FullName + "` Exception: " + ex);
                }

                for (var i = 0; i < types.Count; i++)
                {
                    var t = types[i];
                    if (typesToVisit.Add(t.FullName))
                    {
                        // Because the list of types returned by CollectGenericTypeInstances does not detect nested generic classes that are not
                        // used explicitly, we need to create them if a declaring type is actually used
                        // so for example if we have:
                        // class MyClass<T> { class MyNestedClass { } }
                        // class MyDerived : MyClass<int> { }
                        // The CollectGenericTypeInstances will return typically the type MyClass<int>, but will not list MyClass<int>.MyNestedClass
                        // So the following code is correcting this in order to fully query the full graph of generic instance types, including indirect types
                        var nestedTypes = t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
                        foreach (var nestedType in nestedTypes)
                        {
                            if (t.IsGenericType && !t.IsGenericTypeDefinition)
                            {
                                var parentGenericTypeArguments = t.GetGenericArguments();
                                // Only create nested types that are closed generic types (full generic instance types)
                                // It happens if for example the parent class is `class MClass<T> { class MyNestedGeneric<T1> {} }`
                                // In that case, MyNestedGeneric<T1> is closed in the context of MClass<int>, so we don't process them
                                if (nestedType.GetGenericArguments().Length == parentGenericTypeArguments.Length)
                                {
                                    var instanceNestedType = nestedType.MakeGenericType(parentGenericTypeArguments);
                                    types.Add(instanceNestedType);
                                }
                            }
                            else
                            {
                                types.Add(nestedType);
                            }
                        }
                    }
                }

                foreach (var t in types)
                {
                    // If the type has been already visited, don't try to visit it
                    if (!typesVisited.Add(t.FullName) || (t.IsGenericTypeDefinition && !t.IsInterface))
                    {
                        continue;
                    }

                    try
                    {
                        // collect methods with types having a [BurstCompile] attribute
                        bool visitStaticMethods = HasBurstCompileAttribute(t);
                        bool isValueType        = false;

                        if (t.IsInterface)
                        {
                            object[] attrs = t.GetCustomAttributes(typeof(JobProducerTypeAttribute), false);
                            if (attrs.Length == 0)
                            {
                                continue;
                            }

                            JobProducerTypeAttribute attr = (JobProducerTypeAttribute)attrs[0];

                            interfaceToProducer.Add(t, attr.ProducerType);

                            //Debug.Log($"{t} has producer {attr.ProducerType}");
                        }
                        else if (t.IsValueType)
                        {
                            // NOTE: Make sure that we don't use a value type generic definition (e.g `class Outer<T> { struct Inner { } }`)
                            // We are only working on plain type or generic type instance!
                            if (!t.IsGenericTypeDefinition)
                            {
                                isValueType = true;
                            }
                        }

                        if (isValueType || visitStaticMethods)
                        {
                            valueTypes.Add(new TypeToVisit(t, visitStaticMethods));
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.LogWarning("Unexpected exception while inspecting type `" + t +
                                         "` IsConstructedGenericType: " + t.IsConstructedGenericType +
                                         " IsGenericTypeDef: " + t.IsGenericTypeDefinition +
                                         " IsGenericParam: " + t.IsGenericParameter +
                                         " Exception: " + ex);
                    }
                }
            }

            //Debug.Log($"Mapped {interfaceToProducer.Count} producers; {valueTypes.Count} value types");

            // Revisit all types to find things that are compilable using the above producers.
            foreach (var typePair in valueTypes)
            {
                var type = typePair.Type;

                // collect static [BurstCompile] methods
                if (typePair.CollectStaticMethods)
                {
                    try
                    {
                        var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
                        foreach (var method in methods)
                        {
                            if (HasBurstCompileAttribute(method))
                            {
                                var target = new BurstCompileTarget(method, type, null, true);
                                methodsToCompile.Add(target);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.LogException(ex);
                    }
                }

                // If the type is not a value type, we don't need to proceed with struct Jobs
                if (!type.IsValueType)
                {
                    continue;
                }

                // Otherwise try to find if we have an interface producer setup on the class
                foreach (var interfaceType in type.GetInterfaces())
                {
                    var genericLessInterface = interfaceType;
                    if (interfaceType.IsGenericType)
                    {
                        genericLessInterface = interfaceType.GetGenericTypeDefinition();
                    }

                    Type foundProducer;
                    if (interfaceToProducer.TryGetValue(genericLessInterface, out foundProducer))
                    {
                        var genericParams = new List <Type> {
                            type
                        };
                        if (interfaceType.IsGenericType)
                        {
                            genericParams.AddRange(interfaceType.GenericTypeArguments);
                        }

                        try
                        {
                            var executeType   = foundProducer.MakeGenericType(genericParams.ToArray());
                            var executeMethod = executeType.GetMethod("Execute");
                            if (executeMethod == null)
                            {
                                throw new InvalidOperationException($"Burst reflection error. The type `{executeType}` does not contain an `Execute` method");
                            }

                            // We will not try to record more than once a method in the methods to compile
                            // This can happen if a job interface is inheriting from another job interface which are using in the end the same
                            // job producer type
                            if (methodsToCompileSet.Add(executeMethod))
                            {
                                var target = new BurstCompileTarget(executeMethod, type, interfaceType, false);
                                methodsToCompile.Add(target);
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.LogException(ex);
                        }
                    }
                }
            }

            return(methodsToCompile);
        }
示例#3
0
 /// <summary>Generates the URL for a YouTube video thumbnail for the given id.</summary>
 public static string GenerateYouTubeThumbnailURL(string youTubeId)
 {
     Debug.Assert(youTubeId != null);
     return(@"https://img.youtube.com/vi/" + youTubeId + @"/hqdefault.jpg");
 }
示例#4
0
            protected override void OnUpdate()
            {
                k_LayoutSharedMeshData.Begin();

                int vertexCount           = 0;
                int boneInfluencesCount   = 0;
                int blendShapeVertexCount = 0;

                Parent.MeshHashToSharedBuffer.Clear();
                foreach (var meshData in Parent.UniqueSharedMeshData)
                {
                    Parent.MeshHashToSharedBuffer.Add(meshData.RenderMeshHash, new SharedMeshBufferIndex
                    {
                        GeometryIndex       = vertexCount,
                        BoneInfluencesIndex = boneInfluencesCount,
                        BlendShapeIndex     = blendShapeVertexCount
                    });

                    vertexCount           += meshData.VertexCount;
                    boneInfluencesCount   += meshData.BoneInfluencesCount;
                    blendShapeVertexCount += meshData.BlendShapeVertexCount;
                }

                Debug.Assert(vertexCount == Parent.m_ResizeBuffersSystem.totalSharedVertexCount, $"vertexCount: {vertexCount} is expected to be equal to totalVertexCount {Parent.m_ResizeBuffersSystem.totalSharedVertexCount}.");

                k_LayoutSharedMeshData.End();
                k_CollectSharedMeshData.Begin();

                foreach (var meshData in Parent.UniqueSharedMeshData)
                {
                    if (meshData.RenderMeshHash == 0)
                    {
                        continue;
                    }

                    var renderMesh  = Parent.m_MeshHashToRenderMesh[meshData.RenderMeshHash];
                    var bufferIndex = Parent.MeshHashToSharedBuffer[meshData.RenderMeshHash];

                    Parent.MeshBufferManager.FetchMeshData(renderMesh.mesh, bufferIndex.GeometryIndex);

                    if (meshData.HasSkinning)
                    {
                        Parent.SkinningBufferManager.FetchMeshData(renderMesh.mesh, bufferIndex.GeometryIndex, bufferIndex.BoneInfluencesIndex);
                    }

                    if (meshData.HasBlendShapes)
                    {
                        Parent.BlendShapeBufferManager.FetchMeshData(renderMesh.mesh, bufferIndex.GeometryIndex, bufferIndex.BlendShapeIndex);
                    }
                }

                k_CollectSharedMeshData.End();
                k_UploadSharedMeshData.Begin();

                Parent.MeshBufferManager.PushMeshData();
                Parent.BlendShapeBufferManager.PushSharedMeshData();
                Parent.SkinningBufferManager.PushSharedMeshData();

                k_UploadSharedMeshData.End();
                Parent.m_RebuildSharedMeshBuffers = false;
            }
示例#5
0
        public static FloatTensor Concatenate(FloatTensorFactory factory, FloatTensor[] tensors_inp, int axis, FloatTensor result = null)
        {
            FloatTensor first = tensors_inp[0];

            FloatTensor[] tensors = new FloatTensor[tensors_inp.Length - 1];
            for (int i = 0; i < tensors_inp.Length - 1; i++)
            {
                tensors[i] = tensors_inp[i + 1];
            }

            if (first.DataOnGpu)
            {
                throw new NotImplementedException("Can't concatenate GPU tensors yet");
            }

            int num_new_rows = 0;

            List <IntTensor> int_tensors_for_index_add = new List <IntTensor>();

            int[] first_indices = new int[first.Shape[axis]];
            for (int i = 0; i < first.Shape[axis]; i++)
            {
                first_indices[i] = i + num_new_rows;
            }
            int_tensors_for_index_add.Add(
                factory.ctrl.intTensorFactory.Create(_shape: new int[1] {
                first.Shape[axis]
            }, _data: first_indices));

            num_new_rows += first.Shape[axis];

            foreach (FloatTensor tensor in tensors)
            {
                if (tensor.Shape.Length != first.Shape.Length)
                {
                    throw new InvalidOperationException("Tensors do not have the same number of dimensions.");
                }

                for (int i = 0; i < tensor.Shape.Length; i++)
                {
                    if (i != axis)
                    {
                        if (tensor.Shape[i] != first.Shape[i])
                        {
                            throw new InvalidOperationException("Tensors do not have the same shape.");
                        }
                    }
                }

                if (tensor.DataOnGpu != first.DataOnGpu)
                {
                    throw new InvalidOperationException("All tensors must be on the same device...");
                }

                int[] indices = new int[tensor.Shape[axis]];
                for (int i = 0; i < tensor.Shape[axis]; i++)
                {
                    indices[i] = i + num_new_rows;
                }
                int_tensors_for_index_add.Add(
                    factory.ctrl.intTensorFactory.Create(_shape: new int[1] {
                    tensor.Shape[axis]
                }, _data: indices));


                num_new_rows += tensor.Shape[axis];
            }

            Debug.Log("Num new Rows:" + num_new_rows);

            int[] concat_shape = new int[first.Shape.Length];

            for (int i = 0; i < first.Shape.Length; i++)
            {
                if (i == axis)
                {
                    concat_shape[i] = num_new_rows;
                }
                else
                {
                    concat_shape[i] = first.Shape[i];
                }
            }

            result = first.HookGraph(ref result, tensor_inputs: tensors, creation_op: "concatenate_" + axis, inline: false, resultShape: concat_shape, indices: int_tensors_for_index_add.ToArray());

            if (axis != 0)
            {
                result.IndexAdd(int_tensors_for_index_add[0], axis, first, inline: true);

                for (int i = 0; i < tensors.Length; i++)
                {
                    result.IndexAdd(int_tensors_for_index_add[i + 1], axis, tensors[i], inline: true);
                }
            }
            else
            {
                //Debug.Log("Result Size:" + result.Size);
                //Debug.Log("First Size:" + first.Size);

                int result_i = 0;

                for (int i = 0; i < first.Data.Length; i++)
                {
                    result.Data[result_i] = first.Data[i];
                    result_i += 1;
                }

                foreach (FloatTensor tensor in tensors)
                {
                    //Debug.Log("Tensor Size:" + tensor.Size);
                    for (int i = 0; i < tensor.Data.Length; i++)
                    {
                        result.Data[result_i] = tensor.Data[i];
                        result_i += 1;
                    }
                }
            }
            return(result);
        }
示例#6
0
        private static void Init()
        {
            var projectDirectory = Directory.GetParent(Application.dataPath).FullName;

            var projectName = Path.GetFileName(projectDirectory);

            SlnFile = Path.GetFullPath($"{projectName}.sln");

            InitializeEditorInstanceJson();
            ResetDefaultFileExtensions();

            // process csproj files once per Unity process
            if (!RiderScriptableSingleton.Instance.CsprojProcessedOnce)
            {
                // Perform on next editor frame update, so we avoid this exception:
                // "Must set an output directory through SetCompileScriptsOutputDirectory before compiling"
                EditorApplication.update += SyncSolutionOnceCallBack;
            }

            var lifetimeDefinition = Lifetime.Define(Lifetime.Eternal);
            var lifetime           = lifetimeDefinition.Lifetime;

            AppDomain.CurrentDomain.DomainUnload += (EventHandler)((_, __) =>
            {
                ourLogger.Verbose("lifetimeDefinition.Terminate");
                lifetimeDefinition.Terminate();
            });

            if (PluginSettings.SelectedLoggingLevel >= LoggingLevel.VERBOSE)
            {
                Debug.Log($"Rider plugin initialized. LoggingLevel: {PluginSettings.SelectedLoggingLevel}. Change it in Unity Preferences -> Rider. Logs path: {LogPath}.");
            }

            var list = new List <ProtocolInstance>();

            CreateProtocolAndAdvise(lifetime, list, new DirectoryInfo(Directory.GetCurrentDirectory()).Name);

            // list all sln files in CurrentDirectory, except main one and create server protocol for each of them
            var currentDir    = new DirectoryInfo(Directory.GetCurrentDirectory());
            var solutionFiles = currentDir.GetFiles("*.sln", SearchOption.TopDirectoryOnly);

            foreach (var solutionFile in solutionFiles)
            {
                if (Path.GetFileNameWithoutExtension(solutionFile.FullName) != currentDir.Name)
                {
                    CreateProtocolAndAdvise(lifetime, list, Path.GetFileNameWithoutExtension(solutionFile.FullName));
                }
            }

            ourOpenAssetHandler = new OnOpenAssetHandler(ourRiderPathLocator, ourPluginSettings, SlnFile);
            ourLogger.Verbose("Writing Library/ProtocolInstance.json");
            var protocolInstanceJsonPath = Path.GetFullPath("Library/ProtocolInstance.json");

            File.WriteAllText(protocolInstanceJsonPath, ProtocolInstance.ToJson(list));

            AppDomain.CurrentDomain.DomainUnload += (sender, args) =>
            {
                ourLogger.Verbose("Deleting Library/ProtocolInstance.json");
                File.Delete(protocolInstanceJsonPath);
            };

            PlayModeSavedState = GetPlayModeState();
            SetupAssemblyReloadEvents();

            ourInitialized = true;
        }
        private static AllowedAssembly[] GetAssembliesInBuild()
        {
#if ACTK_DEBUG_VERBOSE
            sw.Stop();
            Debug.Log(ACTkConstants.LogPrefix + "Trying to guess which assemblies can get into the build...");
            sw.Start();
#endif
            var libraries = BuildPostProcessor.GetGuessedLibrariesForBuild();

#if ACTK_DEBUG_VERBOSE
            sw.Stop();
            Debug.Log(ACTkConstants.LogPrefix + "Total libraries candidates: " + libraries.Length);
            sw.Start();

            var invalidAssemblies = string.Empty;
#endif

            var result = new List <AllowedAssembly>();

            foreach (var libraryPath in libraries)
            {
#if ACTK_DEBUG_PARANIOD
                sw.Stop();
                Debug.Log(ACTkConstants.LogPrefix + "Checking library at the path: " + libraryPath);
                sw.Start();
#endif
                try
                {
                    var assName = AssemblyName.GetAssemblyName(libraryPath);
                    var name    = assName.Name;
                    var hash    = InjectionRoutines.GetAssemblyHash(assName);

                    var allowed = result.FirstOrDefault(allowedAssembly => allowedAssembly.name == name);
                    if (allowed != null)
                    {
                        allowed.AddHash(hash);
                    }
                    else
                    {
                        allowed = new AllowedAssembly(name, new[] { hash });
                        result.Add(allowed);
                    }
                }
                catch
                {
                    // not a valid IL assembly, skipping
#if ACTK_DEBUG_VERBOSE
                    invalidAssemblies += libraryPath + "\n";
#endif
                }
            }

#if ACTK_DEBUG_VERBOSE
            if (!string.IsNullOrEmpty(invalidAssemblies))
            {
                sw.Stop();
                Debug.Log(ACTkConstants.LogPrefix + "Not valid assemblies:\n" + invalidAssemblies);
                sw.Start();
            }
#endif

#if ACTK_DEBUG
            sw.Stop();
            var trace = ACTkConstants.LogPrefix + "Found assemblies in build (" + result.Count + ", " + sw.ElapsedMilliseconds + " ms):\n";

            foreach (var allowedAssembly in result)
            {
                trace += "  Name: " + allowedAssembly.name + "\n";
                trace  = allowedAssembly.hashes.Aggregate(trace, (current, hash) => current + ("    Hash: " + hash + "\n"));
            }
            Debug.Log(trace);
            sw.Start();
#endif
            return(result.ToArray());
        }
示例#8
0
        protected static HashSet <string> GetActiveScriptCompilationDefines()
        {
            if (activeScriptCompilationDefines != null)
            {
                return(activeScriptCompilationDefines);
            }

            activeScriptCompilationDefines = new HashSet <string>(UnityEditor.EditorUserBuildSettings.activeScriptCompilationDefines);
            string rspText = null;

            try
            {
                string rspFileName = null;
                for (var i = 0; i < rspFileNames.Length; ++i)
                {
                    if (System.IO.File.Exists(rspFileNames[i]))
                    {
                        rspFileName = rspFileNames[i];
                        break;
                    }
                }

                if (rspFileName != null)
                {
                    rspText = System.IO.File.ReadAllText(rspFileName);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogException(e);
            }

            if (rspText != null)
            {
                var options = rspText.Split(optionsSeparators, StringSplitOptions.RemoveEmptyEntries);
                for (var i = options.Length; i-- > 0;)
                {
                    var option = options[i];
                    if (option.StartsWith("-define:", StringComparison.OrdinalIgnoreCase) ||
                        option.StartsWith("/define:", StringComparison.OrdinalIgnoreCase))
                    {
                        option = option.Substring("-define:".Length);
                    }
                    else if (option.StartsWith("-d:", StringComparison.OrdinalIgnoreCase) ||
                             option.StartsWith("/d:", StringComparison.OrdinalIgnoreCase))
                    {
                        option = option.Substring("-d:".Length);
                    }
                    else
                    {
                        continue;
                    }

                    var defineOptions = option.Split(definesSeparators, StringSplitOptions.RemoveEmptyEntries);
                    for (var j = defineOptions.Length; j-- > 0;)
                    {
                        activeScriptCompilationDefines.Add(defineOptions[j]);
                    }
                }
            }

            return(activeScriptCompilationDefines);
        }
示例#9
0
 public static void Warn(string message)
 {
     Debug.LogWarning(message);
 }
示例#10
0
 public static void LogException(Exception e)
 {
     Debug.LogException(e);
 }
        static ConditionalCompilationUtility()
        {
            var buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
            var defines          = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';').ToList();

            if (!defines.Contains(k_EnableCCU, StringComparer.OrdinalIgnoreCase))
            {
                defines.Add(k_EnableCCU);
                PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", defines.ToArray()));

                // This will trigger another re-compile, which needs to happen, so all the custom attributes will be visible
                return;
            }

            var ccuDefines = new List <string> {
                k_EnableCCU
            };

            var conditionalAttributeType = typeof(ConditionalAttribute);

            const string kDependentClass = "dependentClass";
            const string kDefine         = "define";

            var attributeTypes = GetAssignableTypes(typeof(Attribute), type =>
            {
                var conditionals = (ConditionalAttribute[])type.GetCustomAttributes(conditionalAttributeType, true);

                foreach (var conditional in conditionals)
                {
                    if (string.Equals(conditional.ConditionString, k_EnableCCU, StringComparison.OrdinalIgnoreCase))
                    {
                        var dependentClassField = type.GetField(kDependentClass);
                        if (dependentClassField == null)
                        {
                            Debug.LogErrorFormat("[CCU] Attribute type {0} missing field: {1}", type.Name, kDependentClass);
                            return(false);
                        }

                        var defineField = type.GetField(kDefine);
                        if (defineField == null)
                        {
                            Debug.LogErrorFormat("[CCU] Attribute type {0} missing field: {1}", type.Name, kDefine);
                            return(false);
                        }
                    }
                    return(true);
                }

                return(false);
            });

            var dependencies = new Dictionary <string, string>();

            ForEachAssembly(assembly =>
            {
                var typeAttributes = assembly.GetCustomAttributes(false).Cast <Attribute>();
                foreach (var typeAttribute in typeAttributes)
                {
                    if (attributeTypes.Contains(typeAttribute.GetType()))
                    {
                        var t = typeAttribute.GetType();

                        // These fields were already validated in a previous step
                        var dependentClass = t.GetField(kDependentClass).GetValue(typeAttribute) as string;
                        var define         = t.GetField(kDefine).GetValue(typeAttribute) as string;

                        if (!string.IsNullOrEmpty(dependentClass) && !string.IsNullOrEmpty(define) && !dependencies.ContainsKey(dependentClass))
                        {
                            dependencies.Add(dependentClass, define);
                        }
                    }
                }
            });

            ForEachAssembly(assembly =>
            {
                foreach (var dependency in dependencies)
                {
                    var type = assembly.GetType(dependency.Key);
                    if (type != null)
                    {
                        var define = dependency.Value;
                        if (!defines.Contains(define, StringComparer.OrdinalIgnoreCase))
                        {
                            defines.Add(define);
                        }

                        ccuDefines.Add(define);
                    }
                }
            });

            ConditionalCompilationUtility.defines = ccuDefines.ToArray();

            PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, string.Join(";", defines.ToArray()));
        }
示例#12
0
 public static void LogError(object obj)
 {
     Debug.LogError("[UPDATER_LOG] " + obj);
 }
示例#13
0
 public static void LogWaring(object obj)
 {
     Debug.LogWarning("[UPDATER_LOG] " + obj);
 }
示例#14
0
        /// <summary>
        /// Reverts all changes that were done during or after the given tick
        /// </summary>
        public void RollbackTo(int tick, int missFrameTick, bool isNeedClear = true)
        {
            var snapshotIndices = Contexts.snapshot.GetEntities(SnapshotMatcher.Tick)
                                  .Where(entity => entity.tick.value <= tick).Select(entity => entity.tick.value).ToList();

            if (snapshotIndices.Count <= 0)
            {
                return;
            }
            snapshotIndices.Sort();
            UnityEngine.Debug.Assert(snapshotIndices.Count > 0 && snapshotIndices[0] <= tick,
                                     $"Error! no correct history frame to revert minTick{(snapshotIndices.Count > 0 ? snapshotIndices[0] : 0)} targetTick {tick}");
            int i = snapshotIndices.Count - 1;

            for (; i >= 0; i--)
            {
                if (snapshotIndices[i] <= tick)
                {
                    break;
                }
            }

            var resultTick = snapshotIndices[i];

            if (resultTick == Tick)
            {
                Logging.Debug.Log("SelfTick should not rollback");
                return;
            }
            var snaps = "";

            foreach (var idx in snapshotIndices)
            {
                snaps += idx + " ";
            }

            Debug.Log(
                $"Rolling back {Tick}->{tick} :final from {resultTick} to {Contexts.gameState.tick.value}  " +
                $"missTick:{missFrameTick} total:{Tick - resultTick} ");

            /*
             * ====================== Revert actors ======================
             * most importantly: the entity-count per actor gets reverted so the composite key (Id + ActorId) of GameEntities stays in sync
             */

            var backedUpActors =
                Contexts.actor.GetEntities(ActorMatcher.Backup).Where(e => e.backup.tick == resultTick);

            foreach (var backedUpActor in backedUpActors)
            {
                var target = Contexts.actor.GetEntityWithId(backedUpActor.backup.actorId);
                if (target == null)
                {
                    target = Contexts.actor.CreateEntity();
                    target.AddId(backedUpActor.backup.actorId);
                }

                //CopyTo does NOT remove additional existing components, so remove them first
                var additionalComponentIndices = target.GetComponentIndices().Except(
                    backedUpActor.GetComponentIndices()
                    .Except(new[] { ActorComponentsLookup.Backup })
                    .Concat(new[] { ActorComponentsLookup.Id }));

                foreach (var index in additionalComponentIndices)
                {
                    target.RemoveComponent(index);
                }

                backedUpActor.CopyTo(target, true,
                                     backedUpActor.GetComponentIndices().Except(new[] { ActorComponentsLookup.Backup }).ToArray());
            }

            /*
             * ====================== Revert game-entities ======================
             */
            var currentEntities = Contexts.game.GetEntities(GameMatcher.LocalId);
            var backupEntities  = Contexts.game.GetEntities(GameMatcher.Backup).Where(e => e.backup.tick == resultTick)
                                  .ToList();
            var backupEntityIds = backupEntities.Select(entity => entity.backup.localEntityId);

            //Entities that were created in the prediction have to be destroyed
            var invalidEntities = currentEntities.Where(entity => !backupEntityIds.Contains(entity.localId.value))
                                  .ToList();

            foreach (var invalidEntity in invalidEntities)
            {
                invalidEntity.isDestroyed = true;
            }

            //将太后 和太前的snapshot 删除掉
            if (isNeedClear)
            {
                foreach (var invalidBackupEntity in Contexts.actor.GetEntities(ActorMatcher.Backup)
                         .Where(e => e.backup.tick != resultTick))
                {
                    invalidBackupEntity.Destroy();
                }

                foreach (var invalidBackupEntity in Contexts.game.GetEntities(GameMatcher.Backup)
                         .Where(e => e.backup.tick != resultTick))
                {
                    invalidBackupEntity.Destroy();
                }

                foreach (var snapshotEntity in Contexts.snapshot.GetEntities(SnapshotMatcher.Tick)
                         .Where(e => e.tick.value != resultTick))
                {
                    snapshotEntity.Destroy();
                }
            }


            //Copy old state to the entity
            foreach (var backupEntity in backupEntities)
            {
                var target = Contexts.game.GetEntityWithLocalId(backupEntity.backup.localEntityId);
                if (target == null)
                {
                    target = Contexts.game.CreateEntity();
                    target.AddLocalId(backupEntity.backup.localEntityId);
                }

                //CopyTo does NOT remove additional existing components, so remove them first
                var additionalComponentIndices = target.GetComponentIndices().Except(
                    backupEntity.GetComponentIndices()
                    .Except(new[] { GameComponentsLookup.Backup })
                    .Concat(new[] { GameComponentsLookup.LocalId }));

                foreach (var index in additionalComponentIndices)
                {
                    target.RemoveComponent(index);
                }

                backupEntity.CopyTo(target, true,
                                    backupEntity.GetComponentIndices().Except(new[] { GameComponentsLookup.Backup }).ToArray());
            }

            //TODO: restore locally destroyed entities

            //Cleanup game-entities that are marked as destroyed
            _systems.Cleanup();
            Contexts.gameState.ReplaceTick(resultTick);
            _timeMachineService.RollbackTo(resultTick);
            _timeMachineService.CurTick = resultTick;
        }
            protected override void OnUpdate()
            {
                k_ChangesMarker.Begin();

                bool changeDetected = false;

                // Detect removed SharedMeshes
                Entities
                .WithNone <RenderMesh, DeformedEntity>()
                .WithStructuralChanges()
                .ForEach((Entity e, SharedMeshData meshData) =>
                {
                    Parent.MeshHashToInstanceCount[meshData.RenderMeshHash]--;
                    var count = Parent.MeshHashToInstanceCount[meshData.RenderMeshHash];

                    // Clean-up if this was the last instance
                    if (count == 0)
                    {
                        Parent.MeshHashToInstanceCount.Remove(meshData.RenderMeshHash);
                        m_MeshHashToSharedMeshData.Remove(meshData.RenderMeshHash);
#if ENABLE_COMPUTE_DEFORMATIONS
                        Parent.m_MeshHashToRenderMesh.Remove(meshData.RenderMeshHash);

                        totalSharedVertexCount     -= meshData.VertexCount;
                        totalBlendshapeVertexCount -= meshData.HasBlendShapes ? meshData.BlendShapeVertexCount : 0;
                        totalBoneWeightCount       -= meshData.HasSkinning ? meshData.BoneInfluencesCount : 0;
#endif
                    }

#if ENABLE_COMPUTE_DEFORMATIONS
                    if (meshData.HasBlendShapes)
                    {
                        EntityManager.RemoveComponent <BlendWeightBufferIndex>(e);
                    }
#endif

                    if (meshData.HasSkinning)
                    {
                        EntityManager.RemoveComponent <SkinMatrixBufferIndex>(e);
                    }

                    EntityManager.RemoveComponent <SharedMeshData>(e);
#if ENABLE_COMPUTE_DEFORMATIONS
                    EntityManager.RemoveComponent <DeformedMeshIndex>(e);
#endif

                    changeDetected = true;
                })
                .Run();

                // Detect new SharedMeshes
                Entities
                .WithAll <DeformedEntity>()
                .WithNone <SharedMeshData>()
                .WithStructuralChanges()
                .ForEach((Entity e, RenderMesh renderMesh) =>
                {
                    if (m_MeshHashToSharedMeshData.TryGetValue(renderMesh.GetHashCode(), out var meshData))
                    {
#if ENABLE_COMPUTE_DEFORMATIONS
                        EntityManager.AddComponent <DeformedMeshIndex>(e);

                        if (meshData.HasBlendShapes)
                        {
                            EntityManager.AddComponent <BlendWeightBufferIndex>(e);
                        }
#endif

                        if (meshData.HasSkinning)
                        {
                            EntityManager.AddComponent <SkinMatrixBufferIndex>(e);
                        }

                        EntityManager.AddSharedComponentData(e, meshData);
                        Parent.MeshHashToInstanceCount[meshData.RenderMeshHash]++;
                    }
                    else
                    {
                        var mesh     = renderMesh.mesh;
                        var meshHash = renderMesh.GetHashCode();
                        meshData     = new SharedMeshData
                        {
                            VertexCount     = mesh.vertexCount,
                            BlendShapeCount = mesh.blendShapeCount,
#if ENABLE_COMPUTE_DEFORMATIONS
                            BlendShapeVertexCount = mesh.blendShapeCount > 0 ? Parent.BlendShapeBufferManager.CalculateSparseBlendShapeVertexCount(mesh) : 0,
#else
                            BlendShapeVertexCount = 0,
#endif
                            BoneCount           = mesh.bindposes.Length,
                            BoneInfluencesCount = mesh.GetAllBoneWeights().Length,
                            RenderMeshHash      = meshHash,
                        };

#if ENABLE_COMPUTE_DEFORMATIONS
                        EntityManager.AddComponent <DeformedMeshIndex>(e);

                        if (meshData.HasBlendShapes)
                        {
                            EntityManager.AddComponent <BlendWeightBufferIndex>(e);
                        }
#endif

                        if (meshData.HasSkinning)
                        {
                            EntityManager.AddComponent <SkinMatrixBufferIndex>(e);
                        }

                        EntityManager.AddSharedComponentData(e, meshData);

                        Parent.MeshHashToInstanceCount.Add(meshHash, 1);
                        m_MeshHashToSharedMeshData.Add(meshHash, meshData);
#if ENABLE_COMPUTE_DEFORMATIONS
                        Parent.m_MeshHashToRenderMesh.Add(meshHash, renderMesh);

                        totalSharedVertexCount     += meshData.VertexCount;
                        totalBlendshapeVertexCount += meshData.HasBlendShapes ? meshData.BlendShapeVertexCount : 0;
                        totalBoneWeightCount       += meshData.HasSkinning ? meshData.BoneInfluencesCount : 0;

                        // A new shared mesh was detected. Force the buffers to be uploaded.
                        Parent.m_RebuildSharedMeshBuffers = true;
#endif
                    }

                    changeDetected = true;
                }).Run();

#if ENABLE_COMPUTE_DEFORMATIONS
                // Sanity check for desired SharedMesh data sizes
                Debug.Assert(totalSharedVertexCount >= 0);
                Debug.Assert(totalBlendshapeVertexCount >= 0);
                Debug.Assert(totalBoneWeightCount >= 0);
#endif

                k_ChangesMarker.End();

                // Early exit if no changes are detected
                if (!changeDetected)
                {
                    return;
                }

                k_ResizeMarker.Begin();

#if ENABLE_COMPUTE_DEFORMATIONS
                Parent.m_RebuildSharedMeshBuffers |= Parent.MeshBufferManager.ResizeSharedMeshBuffersIfRequired(totalSharedVertexCount);
                Parent.m_RebuildSharedMeshBuffers |= Parent.SkinningBufferManager.ResizeSharedBufferIfRequired(totalBoneWeightCount, totalSharedVertexCount);
                Parent.m_RebuildSharedMeshBuffers |= Parent.BlendShapeBufferManager.ResizeSharedBufferIfRequired(totalBlendshapeVertexCount, totalSharedVertexCount);
#endif

                k_ResizeMarker.End();
                k_OutputBuffer.Begin();

                k_OutputCountBuffer.Begin();
#if ENABLE_COMPUTE_DEFORMATIONS
                int deformedMeshVertexCount = 0;
                int blendShapeWeightCount   = 0;
#endif
                int skinMatrixCount = 0;

                m_SharedMeshQuery.CompleteDependency();

                Parent.UniqueSharedMeshData.Clear();
                EntityManager.GetAllUniqueSharedComponentData(Parent.UniqueSharedMeshData);
                foreach (var meshData in Parent.UniqueSharedMeshData)
                {
                    if (meshData.RenderMeshHash == 0)
                    {
                        continue;
                    }

                    int instanceCount = Parent.MeshHashToInstanceCount[meshData.RenderMeshHash];
#if ENABLE_COMPUTE_DEFORMATIONS
                    deformedMeshVertexCount += instanceCount * meshData.VertexCount;

                    if (meshData.HasBlendShapes)
                    {
                        blendShapeWeightCount += instanceCount * meshData.BlendShapeCount;
                    }
#endif

                    if (meshData.HasSkinning)
                    {
                        skinMatrixCount += instanceCount * meshData.BoneCount;
                    }
                }

#if ENABLE_COMPUTE_DEFORMATIONS
                totalDeformedVertexCount   = deformedMeshVertexCount;
                totalBlendShapeWeightCount = blendShapeWeightCount;
#endif
                totalSkinMatrixCount = skinMatrixCount;

                k_OutputCountBuffer.End();

                k_OutputResizeBuffer.Begin();

                Parent.SkinningBufferManager.ResizePassBufferIfRequired(totalSkinMatrixCount);
#if ENABLE_COMPUTE_DEFORMATIONS
                Parent.BlendShapeBufferManager.ResizePassBufferIfRequired(totalBlendshapeVertexCount);
                Parent.MeshBufferManager.ResizeAndPushDeformMeshBuffersIfRequired(totalDeformedVertexCount);
#endif
                k_OutputResizeBuffer.End();

                // Force the DeformedMesh layout to be updated.
                // As either; an deformed mesh has been removed, or a new one has been added.
                // Both result in a shift of indices.
                Parent.m_RebuildDeformedMeshBuffers = true;

                k_OutputBuffer.End();
            }
示例#16
0
 public static void Error(string message)
 {
     Debug.LogError(message);
 }
示例#17
0
 public string GetAbsoluteFilePath(InkFile masterInkFile)
 {
     Debug.Log(masterInkFile.absoluteFolderPath);
     Debug.Log(relativeFilePath);
     return(System.IO.Path.Combine(masterInkFile.absoluteFolderPath, relativeFilePath));
 }
示例#18
0
 public static void Message(string message)
 {
     Debug.Log(message);
 }
示例#19
0
 private static void Log(object msg)
 {
     Debug.Log(msg);
 }
示例#20
0
        private static void PushSameDependABToABUnit(IAssetDataQuerier varQuerier, List <string> varRepeatAssets,
                                                     Dictionary <string, List <string> > varAssetBeDep, Dictionary <string, List <string> > varABBeDep, Dictionary <string, List <string> > varABDepABs)
        {
            var tempHashSetHelper = new HashSet <string>();

            for (int iR = 0; iR < varRepeatAssets.Count; ++iR)
            {
                var tempAssetPath = varRepeatAssets[iR];

                var tempAssetBeDeps = varAssetBeDep[tempAssetPath];
                if (tempAssetBeDeps.Count < 2)
                {
                    UDebug.LogErrorFormat("Repeat analysis error.[{0}]", tempAssetPath);
                    iR++;
                    continue;
                }

                tempHashSetHelper.Clear();
                for (int iBD = 0; iBD < tempAssetBeDeps.Count; ++iBD)
                {
                    var tempABName = tempAssetBeDeps[iBD];
                    tempHashSetHelper.UnionWith(varABDepABs[tempABName]);
                    tempHashSetHelper.Add(tempABName);
                }
                var tempAllABDeps = tempHashSetHelper.OrderBy(a => a).ToList();

                for (int iAD = tempAllABDeps.Count - 1; iAD >= 0; --iAD)
                {
                    var tempABName = tempAllABDeps[iAD];

                    if (!varABBeDep.TryGetValue(tempABName, out var tempBeDeps))
                    {
                        continue;
                    }

                    if (tempAssetBeDeps.Count != tempBeDeps.Count)
                    {
                        continue;
                    }

                    bool tempSame = true;
                    for (int iBD = 0; iBD < tempAssetBeDeps.Count; ++iBD)
                    {
                        if (tempAssetBeDeps[iBD] == tempBeDeps[iBD])
                        {
                            continue;
                        }
                        tempSame = false;
                        break;
                    }

                    if (!tempSame)
                    {
                        continue;
                    }

                    varQuerier.SetAssetBundleName(tempAssetPath, tempABName);
                    varRepeatAssets.RemoveAt(iR);
                    iR++;
                    break;
                }
            }
        }
示例#21
0
        public static CompiledTemplateData LoadRuntimeTemplates(Type type, TemplateSettings templateSettings)
        {
            CompiledTemplateData compiledTemplateData = TemplateCompiler.CompileTemplates(type, templateSettings);

            // Stopwatch stopwatch = Stopwatch.StartNew();

            Func <UIElement, TemplateScope, UIElement>[] templates = new Func <UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledTemplates.size];
            Action <UIElement, UIElement>[] bindings = new Action <UIElement, UIElement> [compiledTemplateData.compiledBindings.size];
            Func <UIElement, UIElement, TemplateScope, UIElement>[] slots = new Func <UIElement, UIElement, TemplateScope, UIElement> [compiledTemplateData.compiledSlots.size];
            TemplateMetaData[] templateMetaData = new TemplateMetaData[compiledTemplateData.compiledTemplates.size];
            OrderablePartitioner <Tuple <int, int> > partition;

            if (templateMetaData.Length < 10)
            {
                for (int i = 0; i < templateMetaData.Length; i++)
                {
                    templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile();
                }
            }
            else
            {
                partition = Partitioner.Create(0, templateMetaData.Length);

                Parallel.ForEach(partition, (range, loopState) => {
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        templates[i] = (Func <UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledTemplates[i].templateFn.Compile();
                    }
                });
            }

            if (compiledTemplateData.compiledSlots.size < 10)
            {
                for (int i = 0; i < compiledTemplateData.compiledSlots.size; i++)
                {
                    slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile();
                }
            }
            else
            {
                partition = Partitioner.Create(0, compiledTemplateData.compiledSlots.size);
                Parallel.ForEach(partition, (range, loopState) => {
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        slots[i] = (Func <UIElement, UIElement, TemplateScope, UIElement>)compiledTemplateData.compiledSlots[i].templateFn.Compile();
                    }
                });
            }

            if (bindings.Length < 10)
            {
                for (int i = 0; i < bindings.Length; i++)
                {
                    try {
                        bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile();
                    }
                    catch (Exception e) {
                        Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode());
                        Debug.Log(e);
                    }
                }
            }
            else
            {
                partition = Partitioner.Create(0, bindings.Length);
                Parallel.ForEach(partition, (range, loopState) => {
                    for (int i = range.Item1; i < range.Item2; i++)
                    {
                        try {
                            bindings[i] = (Action <UIElement, UIElement>)compiledTemplateData.compiledBindings[i].bindingFn.Compile();
                        }
                        catch (Exception e) {
                            Debug.Log("binding " + compiledTemplateData.compiledBindings[i].bindingFn.ToCSharpCode());
                            Debug.Log(e);
                        }
                    }
                });
            }

            LightList <UIStyleGroupContainer> styleList = new LightList <UIStyleGroupContainer>(128);

            StyleSheet[] sheets = compiledTemplateData.styleImporter.GetImportedStyleSheets();

            for (int i = 0; i < sheets.Length; i++)
            {
                StyleSheet sheet = sheets[i];
                styleList.EnsureAdditionalCapacity(sheet.styleGroupContainers.Length);
                for (int j = 0; j < sheet.styleGroupContainers.Length; j++)
                {
                    styleList.array[styleList.size++] = sheet.styleGroupContainers[j];
                }
            }

            for (int i = 0; i < templateMetaData.Length; i++)
            {
                templateMetaData[i]          = compiledTemplateData.compiledTemplates[i].templateMetaData;
                templateMetaData[i].styleMap = styleList.array;
                templateMetaData[i].BuildSearchMap();
            }

            Dictionary <int, Func <ConstructedElement> > constructorFnMap = new Dictionary <int, Func <ConstructedElement> >(37);

            ConstructorInfo constructedTypeCtor = typeof(ConstructedElement).GetConstructor(new Type[] { typeof(int), typeof(UIElement) });

            System.Diagnostics.Debug.Assert(constructedTypeCtor != null, nameof(constructedTypeCtor) + " != null");

            compiledTemplateData.bindings         = bindings;
            compiledTemplateData.slots            = slots;
            compiledTemplateData.templates        = templates;
            compiledTemplateData.templateMetaData = templateMetaData;
            compiledTemplateData.constructorFnMap = constructorFnMap;
            compiledTemplateData.constructElement = (typeId) => compiledTemplateData.constructorFnMap[typeId].Invoke();

            // stopwatch.Stop();
            // Debug.Log("Loaded UIForia templates in " + stopwatch.Elapsed.TotalSeconds.ToString("F2") + " seconds");

            return(compiledTemplateData);
        }
示例#22
0
        private void ApplyInterpretedValues()
        {
            this.isAuthenticationInvalid = false;
            this.isServerUnreachable     = false;
            this.isRequestUnresolvable   = false;
            this.limitedUntilTimeStamp   = -1;
            this.displayMessage          = string.Empty;

            if (this.webRequest == null)
            {
                return;
            }

            // Interpret code
            switch (this.webRequest.responseCode)
            {
            // - Generic coding errors -
            // Bad Request
            case 400:
            // Method Not Allowed
            case 405:
            // Not Acceptable
            case 406:
            // Unsupported Media Type
            case 415:
            {
                this.displayMessage = ("Error synchronizing with the mod.io servers.");

                this.isRequestUnresolvable = true;

                Debug.LogWarning("[mod.io] " + this.ToUnityDebugString());
            }
            break;

            // Bad authorization
            case 401:
            {
                this.displayMessage = ("Your mod.io authentication details have changed."
                                       + "\nLogging out and in again should correct this issue.");

                this.isAuthenticationInvalid = true;
                this.isRequestUnresolvable   = true;
            }
            break;

            // Forbidden
            case 403:
            {
                this.displayMessage = ("Your account does not have the required permissions.");

                this.isRequestUnresolvable = true;
            }
            break;

            // Not found
            case 404:
            // Gone
            case 410:
            {
                this.displayMessage = ("A mod.io networking error was encountered."
                                       + "\nPlease report this as [" + this.webRequest.responseCode.ToString()
                                       + "@" + this.webRequest.url + "] to [email protected]");

                this.isRequestUnresolvable = true;
            }
            break;

            // case 405: Handled Above
            // case 406: Handled Above

            // Timeout
            case 408:
            {
                this.displayMessage = ("The mod.io servers cannot be reached."
                                       + "\nPlease check your internet connection.");

                this.isServerUnreachable = true;
            }
            break;

            // case 410: Handled Above

            // Unprocessable Entity
            case 422:
            {
                var displayString = new System.Text.StringBuilder();
                displayString.AppendLine("The submitted data contained error(s).");

                if (this.fieldValidationMessages != null &&
                    this.fieldValidationMessages.Count > 0)
                {
                    foreach (var kvp in fieldValidationMessages)
                    {
                        displayString.AppendLine("- [" + kvp.Key + "] " + kvp.Value);
                    }
                }

                if (displayString.Length > 0 &&
                    displayString[displayString.Length - 1] == '\n')
                {
                    --displayString.Length;
                }

                this.displayMessage = displayString.ToString();

                this.isRequestUnresolvable = true;
            }
            break;

            // Too Many Requests
            case 429:
            {
                string retryAfterString;
                int    retryAfterSeconds;

                var responseHeaders = this.webRequest.GetResponseHeaders();
                if (!(responseHeaders.TryGetValue("X-Ratelimit-RetryAfter", out retryAfterString) &&
                      int.TryParse(retryAfterString, out retryAfterSeconds)))
                {
                    retryAfterSeconds = 60;

                    Debug.LogWarning("[mod.io] Too many APIRequests have been made, however"
                                     + " no valid X-Ratelimit-RetryAfter header was detected."
                                     + "\nPlease report this to [email protected] with the following information:"
                                     + "\n[" + this.webRequest.url
                                     + ":" + this.webRequest.method
                                     + "-" + this.errorMessage + "]");
                }

                this.displayMessage = ("Too many requests have been made to the mod.io servers."
                                       + "\nReconnecting in " + retryAfterSeconds.ToString() + " seconds.");

                this.limitedUntilTimeStamp = this.timeStamp + retryAfterSeconds;
            }
            break;

            // Internal server error
            case 500:
            {
                this.displayMessage = ("There was an error with the mod.io servers. Staff have been"
                                       + " notified, and will attempt to fix the issue as soon as possible.");

                this.isRequestUnresolvable = true;
            }
            break;

            // Service Unavailable
            case 503:
            {
                this.displayMessage = "The mod.io servers are currently offline.";

                this.isServerUnreachable = true;
            }
            break;

            default:
            {
                // Cannot connect resolve destination host, used by Unity
                if (this.webRequest.responseCode <= 0)
                {
                    this.displayMessage = ("The mod.io servers cannot be reached."
                                           + "\nPlease check your internet connection.");

                    this.isServerUnreachable = true;
                }
                else
                {
                    this.displayMessage = ("Error synchronizing with the mod.io servers.");

                    this.isRequestUnresolvable = true;

                    Debug.LogWarning("[mod.io] An unhandled error was returned during a web request."
                                     + "\nPlease report this to [email protected] with the following information:\n"
                                     + this.ToUnityDebugString());
                }
            }
            break;
            }
        }
示例#23
0
 static void Log(object message)
 => Debug.Log(message);
示例#24
0
 public static void LogAsWarning(WebRequestError error)
 {
     Debug.LogWarning(error.ToUnityDebugString());
 }
示例#25
0
 public static void logError(string message, Exception ex = null)
 {
     Debug.LogException(new ReportError(message, ex));
 }
示例#26
0
 public override void Execute()
 {
     Debug.Log("启动框架");
 }
示例#27
0
 public static void InvalidFinalCategory(CategoryIndex _interiorCategory)
 {
     Debug.Assert(false, $"Invalid final category {_interiorCategory}");
 }
        public async Task <Tuple <Stack <Rotation>, int, TimeSpan> > Solve()
        {
            return(await Task.Run(() =>
            {
                Debug.Log("Start");
                _stopwatch.Start();

                var solutionPath = new Stack <Rotation>();

                //Create open and closed lists
                var open = new Queue <CubeState>();
                var closed = new Queue <CubeState>();

                //Add the initial state to the open list
                open.Enqueue(_givenState);

                //Retrieve the possible rotations
                var possibleRotations = CubeState.GetPossibleRotations();

                //Loop as long as states remain in the open list
                while (open.Any() && _exploredStates < 25000)
                {
                    //Retrieve the first state in the open list
                    var currentState = open.Dequeue();
                    _exploredStates++;

                    Debug.Log("Dequeueing " + _exploredStates + ". Depth is " + currentState.depth);

                    //Generate the children of the current state if the maximum search depth has not been reached
                    if (currentState.depth <= MAX_DEPTH)
                    {
                        foreach (var rotation in possibleRotations)
                        {
                            //Generate the child state produced by the current rotation
                            var childState = currentState.Clone();
                            childState.Rotate(rotation.FaceColor, rotation.Direction);

                            //If the generated state is the goal, return the list of rotations leading to the solution
                            if (childState.IsSolved())
                            {
                                solutionPath.Push(rotation);

                                var previousState = currentState;
                                while (previousState.rotation != null)
                                {
                                    solutionPath.Push(previousState.rotation);
                                    previousState = previousState.parentState;
                                }

                                Debug.Log("End");
                                _stopwatch.Stop();
                                return new Tuple <Stack <Rotation>, int, TimeSpan>(solutionPath, _generatedStates, _stopwatch.Elapsed);
                            }

                            //Check if the state is already on the open or closed list
                            var alreadyExists = false;
                            foreach (var existingState in open)
                            {
                                if (childState.EqualsState(existingState))
                                {
                                    alreadyExists = true;
                                    break;
                                }
                            }

                            if (!alreadyExists)
                            {
                                foreach (var existingState in closed)
                                {
                                    if (childState.EqualsState(existingState))
                                    {
                                        alreadyExists = true;
                                        break;
                                    }
                                }
                            }

                            //Add the child state to the open list if it does not already exist
                            if (!alreadyExists)
                            {
                                childState.parentState = currentState;
                                childState.rotation = rotation;
                                childState.depth = (byte)(currentState.depth + 1);
                                open.Enqueue(childState);
                                _generatedStates++;
                            }
                        }
                    }

                    //Put the current state on the closed list
                    closed.Enqueue(currentState);
                }

                //If no solution was found, return the empty list
                _stopwatch.Stop();
                return new Tuple <Stack <Rotation>, int, TimeSpan>(solutionPath, _generatedStates, _stopwatch.Elapsed);
            }));
        }