/// <summary> /// Private implementation method that performs a merge of multiple, ordered sequences using /// a precedence function which encodes order-sensitive comparison logic based on the caller's arguments. /// </summary> /// <remarks> /// The algorithm employed in this implementation is not necessarily the most optimal way to merge /// two sequences. A swap-compare version would probably be somewhat more efficient - but at the /// expense of considerably more complexity. One possible optimization would be to detect that only /// a single sequence remains (all other being consumed) and break out of the main while-loop and /// simply yield the items that are part of the final sequence. /// The algorithm used here will perform N*(K1+K2+...Kn-1) comparisons, where <c>N => otherSequences.Count()+1.</c> /// </remarks> private static IEnumerable <T> SortedMergeImpl <T>(Func <T, T, bool> precedenceFunc, IEnumerable <IEnumerable <T> > otherSequences) { using (var disposables = new DisposableGroup <T>(otherSequences.Select(e => e.GetEnumerator()).Acquire())) { var iterators = disposables.Iterators; // prime all of the iterators by advancing them to their first element (if any) // NOTE: We start with the last index to simplify the removal of an iterator if // it happens to be terminal (no items) before we start merging for (var i = iterators.Count - 1; i >= 0; i--) { if (!iterators[i].MoveNext()) { disposables.Exclude(i); } } // while all iterators have not yet been consumed... while (iterators.Count > 0) { var nextIndex = 0; var nextValue = disposables[0].Current; // find the next least element to return for (var i = 1; i < iterators.Count; i++) { var anotherElement = disposables[i].Current; // determine which element follows based on ordering function if (precedenceFunc(nextValue, anotherElement)) { nextIndex = i; nextValue = anotherElement; } } yield return(nextValue); // next value in precedence order // advance iterator that yielded element, excluding it when consumed if (!iterators[nextIndex].MoveNext()) { disposables.Exclude(nextIndex); } } } }
public static DisposableGroup RegisterFixedUpdate(this DisposableGroup dg, Action fixedupdateAction, int order = 0) => dg.Register( TimeMachine.RegisterFixedUpdate(fixedupdateAction, order));
public static DisposableGroup RegisterLateUpdate(this DisposableGroup dg, Action lateupdateAction, int order = 0) => dg.Register( TimeMachine.RegisterLateUpdate(lateupdateAction, order));
/// <summary> /// Merges two or more sequences that are in a common order (either ascending or descending) into /// a single sequence that preserves that order. /// </summary> /// <typeparam name="TSource">The type of the elements in the sequence</typeparam> /// <param name="source">The primary sequence with which to merge</param> /// <param name="direction">The ordering that all sequences must already exhibit</param> /// <param name="comparer">The comparer used to evaluate the relative order between elements</param> /// <param name="otherSequences">A variable argument array of zero or more other sequences to merge with</param> /// <returns>A merged, order-preserving sequence containing al of the elements of the original sequences</returns> public static IEnumerable <TSource> SortedMerge <TSource>(this IEnumerable <TSource> source, OrderByDirection direction, IComparer <TSource> comparer, params IEnumerable <TSource>[] otherSequences) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (otherSequences == null) { throw new ArgumentNullException(nameof(otherSequences)); } if (otherSequences.Length == 0) { return(source); // optimization for when otherSequences is empty } comparer = comparer ?? Comparer <TSource> .Default; // define an precedence function based on the comparer and direction // this is a function that will return True if (b) should precede (a) var precedenceFunc = direction == OrderByDirection.Ascending ? (Func <TSource, TSource, bool>)((a, b) => comparer.Compare(b, a) < 0) : (a, b) => comparer.Compare(b, a) > 0; // return the sorted merge result return(Impl(new[] { source }.Concat(otherSequences))); // Private implementation method that performs a merge of multiple, ordered sequences using // a precedence function which encodes order-sensitive comparison logic based on the caller's arguments. // // The algorithm employed in this implementation is not necessarily the most optimal way to merge // two sequences. A swap-compare version would probably be somewhat more efficient - but at the // expense of considerably more complexity. One possible optimization would be to detect that only // a single sequence remains (all other being consumed) and break out of the main while-loop and // simply yield the items that are part of the final sequence. // // The algorithm used here will perform N*(K1+K2+...Kn-1) comparisons, where <c>N => otherSequences.Count()+1.</c> IEnumerable <TSource> Impl(IEnumerable <IEnumerable <TSource> > sequences) { using (var disposables = new DisposableGroup <TSource>(sequences.Select(e => e.GetEnumerator()).Acquire())) { var iterators = disposables.Iterators; // prime all of the iterators by advancing them to their first element (if any) // NOTE: We start with the last index to simplify the removal of an iterator if // it happens to be terminal (no items) before we start merging for (var i = iterators.Count - 1; i >= 0; i--) { if (!iterators[i].MoveNext()) { disposables.Exclude(i); } } // while all iterators have not yet been consumed... while (iterators.Count > 0) { var nextIndex = 0; var nextValue = disposables[0].Current; // find the next least element to return for (var i = 1; i < iterators.Count; i++) { var anotherElement = disposables[i].Current; // determine which element follows based on ordering function if (precedenceFunc(nextValue, anotherElement)) { nextIndex = i; nextValue = anotherElement; } } yield return(nextValue); // next value in precedence order // advance iterator that yielded element, excluding it when consumed if (!iterators[nextIndex].MoveNext()) { disposables.Exclude(nextIndex); } } } } }
public static void GenCodeByAssemblies() { var config = XConfig.GetConfig <TinaX.XILRuntime.Internal.XILRTConfig>(XILConst.ConfigPath_Resources); if (config == null) { Debug.LogError($"[{XILConst.ServiceName}] Generate CLRBinding code failed: config file not found."); return; } string output_path = config.EditorCLRBindingCodeOutputPath; if (!output_path.StartsWith("Assets/")) { Debug.LogError($"[{XILConst.ServiceName}]Generate failed: Output folder path is invalid :" + output_path); return; } ILAppDomain domain = new ILAppDomain(); DisposableGroup disGroup = new DisposableGroup(); foreach (var path in config.EditorLoadAssemblyPaths) { if (!path.AssemblyPath.IsNullOrEmpty()) { var fs = new FileStream(path.AssemblyPath, FileMode.Open, FileAccess.Read); disGroup.Register(fs); domain.LoadAssembly(fs); } } List <Type> gen_valueTypes = new List <Type>(s_InternalValueTypes); List <Type> gen_delegates = new List <Type>(s_InternalDelegateTypes); Type t_define = typeof(ICLRGenerateDefine); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(t_define))) .ToArray(); if (types.Length > 0) { foreach (var type in types) { ICLRGenerateDefine define_obj = (ICLRGenerateDefine)Activator.CreateInstance(type); define_obj.GenerateByAssemblies_InitILRuntime(domain); var _valueTypes = define_obj.GetValueTypeBinders(); if (_valueTypes != null && _valueTypes.Count > 0) { foreach (var __valueType in _valueTypes) { if (!gen_valueTypes.Contains(__valueType)) { gen_valueTypes.Add(__valueType); } } } var _delegates = define_obj.GetDelegateTypes(); if (_delegates != null && _delegates.Count > 0) { foreach (var __delegate in _delegates) { if (!gen_delegates.Contains(__delegate)) { gen_delegates.Add(__delegate); } } } } } Internal_HandleBeforeGenCodeByAssemblies(domain); BindingCodeGenerator.GenerateBindingCode(domain, output_path, gen_valueTypes, gen_delegates); disGroup.Dispose(); Debug.Log($"<color=#{TinaX.Internal.XEditorColorDefine.Color_Safe_16}>Generate code finish.</color>"); AssetDatabase.Refresh(); }
public static DisposableGroup RegisterEvent(this DisposableGroup dg, string EventName, Action <object> Handler, string EventGroup = XEvent.DefaultGroup) => dg.Register(XEvent.Register(EventName, Handler, EventGroup));