コード例 #1
0
        /// <summary>
        /// The heart of the program
        /// Returns the best available slot based on the input requirements
        /// </summary>
        /// <param name="activity">The slot type</param>
        /// <param name="status">Used to push aside low priority tables if needed</param>
        /// <returns>The best suited slot based on the requirements</returns>
        private Slot GetAvailableSlot(Slot.ActivityUses slotType, Table table)
        {
            Slot resultSlot = null;

            // Find all possible slots & order them
            var possibleSlots = Config.Active.ActiveProfile.Slots
                                .Where(s => s.ActivityUse == slotType) // Match the slot type (active/inactive)
                                .OrderBy(s => s.OccupiedBy.Count)      // Pick the best slot
                                .ThenBy(s => s.Priority)               // Pick user preferred slot
                                .ThenBy(s => s.X)                      // Pick left-to-right instead
                                .ThenBy(s => s.Y);

            // Handle situations where no slot for this use is found
            if (possibleSlots.Count() == 0)
            {
                if (slotType == Slot.ActivityUses.Aside)
                {
                    Logger.Log("WindowManager: Attempting to move table aside but there is no aside slot. Add one in config.",
                               Logger.Status.Warning, showMessageBox: true);
                }
                else
                {
                    Logger.Log($"WindowManager: An active or inactive slot was missing. Corrupt config?", Logger.Status.Fatal);
                }

                return(resultSlot);
            }

            // Try to find an empty or the current slot or stackable slot - filter by preferred slot
            resultSlot = possibleSlots
                         .Where(s => s.OccupiedBy.Count == 0 || s.OccupiedBy.Contains(table) || s.CanStack)
                         .OrderBy(s => s.OccupiedBy.Count)                                               // Prefer empty slots regardless of preferred
                         .ThenByDescending(s => table.PreferredSlot != null && s == table.PreferredSlot) // pick the table's preferred slot
                         .ThenBy(s => s.OccupiedBy.Where(t => t.PreferredSlot == null).Count())          // Find a slot with a table without a preferred slot
                         .FirstOrDefault();
            if (resultSlot != null)
            {
                return(resultSlot);
            }

            // At this point only handle active tables
            if (slotType == Slot.ActivityUses.Aside)
            {
                Logger.Log($"WindowManager: Tried to find Aside slot but none were available.");
                return(resultSlot); // No available aside slots, do nothing.
            }
            else if (slotType == Slot.ActivityUses.Inactive)
            {
                Logger.Log($"WindowManager: No inactive slot available. " +
                           "This should be impossible since Inactive slots must be stackable. Corrupt config?",
                           Logger.Status.Fatal);
                return(resultSlot);
            }

            // Try to find an active slot with a low priority table and push it to Inactive.
            resultSlot = possibleSlots
                         // Only tables with priority that's allowed to be pushed aside
                         .Where(s => s.OccupiedBy.First().Priority <= Table.Status.NoActionRequired)
                         // Find lowest priority table to push aside
                         .OrderByDescending(s => s.OccupiedBy
                                            .OrderBy(x => x.Priority)
                                            .ThenByDescending(x => x.PriorityChangedTime)
                                            .First().PriorityChangedTime
                                            )
                         .FirstOrDefault();

            // Give up if there's no table to push or
            // Push the table we found to inactive & return the free slot
            if (resultSlot != null)
            {
                Table tableToMove    = resultSlot.OccupiedBy.First();
                Slot  anInactiveSlot = GetAvailableSlot(Slot.ActivityUses.Inactive, table);
                Slot  previousSlot   = Config.Active.ActiveProfile.Slots
                                       .Where(s => s.OccupiedBy.Contains(tableToMove))
                                       .FirstOrDefault();

                // Move table in queue
                MoveTable(tableToMove, anInactiveSlot, previousSlot);

                // Also move any double stacked tables when an inactive slot is available
                if (Config.Active.PreferSpreadOverStack)
                {
                    // if there's a free inactive slot
                    var freeInactiveSlots = Config.Active.ActiveProfile.Slots.Where(s => s.ActivityUse == Slot.ActivityUses.Inactive && s.OccupiedBy.Count == 0);
                    if (freeInactiveSlots.Count() > 0)
                    {
                        // Find a slot with a table that should be moved, if any
                        Slot slotWithUnnessecarilyStackedTable = Config.Active.ActiveProfile.Slots
                                                                 .Where(s => s.ActivityUse == Slot.ActivityUses.Inactive)
                                                                 .Where(s => s.OccupiedBy.Count > 1)
                                                                 .FirstOrDefault();

                        // if we found a slot, move the most approperiate table
                        if (slotWithUnnessecarilyStackedTable != null)
                        {
                            Table bestTableToMove = slotWithUnnessecarilyStackedTable.OccupiedBy.
                                                    OrderByDescending(t => t.PriorityChangedTime)
                                                    .FirstOrDefault();
                            MoveTable(
                                bestTableToMove,
                                freeInactiveSlots.First(),
                                slotWithUnnessecarilyStackedTable);
                        }
                    }
                }
            }

            return(resultSlot);
        }
コード例 #2
0
ファイル: Slot.cs プロジェクト: NotCoffee418/MultiTablePro
 public ActivityUseChangedEventArgs(Slot.ActivityUses oldActivityUse, Slot.ActivityUses newActivityUse)
 {
     OldActivityUse = oldActivityUse;
     NewActivityUse = newActivityUse;
 }