public DynamicScheduler(ReadOnlySpan <TItem> scheduleItems) { m_executeItemAction = ExecuteScheduledItem; var items = new ItemInfo[scheduleItems.Length]; for (int i = 0; i < items.Length; i++) { items[i] = new ItemInfo() { Item = scheduleItems[i] } } ; // sort dynamically var ok = DynamicOrdering.Perform <ItemInfo>(items, out _); if (!ok) { CoreException.Throw("Failed to sort dynamically"); } m_concurrencyPreventionMatrix = new SymmetricMatrixBool(scheduleItems.Length); m_running = new FastList <ItemInfo>(16); // set up items (determine nods, concurrency etc) var nods = new FastList <int>(32); for (int aIdx = 0; aIdx < items.Length; aIdx++) { var a = items[aIdx]; a.Index = aIdx; // set up index ref var aInfo = ref items[aIdx]; aInfo.EmitNodsIndex = nods.Count; for (int bIdx = 0; bIdx < items.Length; bIdx++) { if (aIdx == bIdx) { continue; } // determine is aIdx nods to bIdx var b = items[bIdx]; var aOrder = a.Item.ScheduleAgainst(b.Item); var bOrder = b.Item.ScheduleAgainst(a.Item); aOrder = ScheduleOrderUtil.ResolveOrder(aOrder, bOrder, out var conflict); if (aOrder == ScheduleOrder.RunBefore) { ref var bInfo = ref items[bIdx]; bInfo.NodsRequired++; nods.Add(bIdx); } if (aOrder != ScheduleOrder.AnyOrderConcurrent) { m_concurrencyPreventionMatrix[aIdx, bIdx] = true; } } aInfo.EmitNodsCount = nods.Count - aInfo.EmitNodsIndex; }