The point here is to achieve adjustable throughput for each output, also priority.
Simple round-robin way probably would not work with adjustable throughputs.
This is kinda different suggestion than "add priority splitter" and "add adjustable rate splitter" because we need this two at the same time in one piece and also because i suggest an algorithm to make it work in order to make it easier to implement the suggestion. (We all know, guys at Coffee Stain have a lot of work right now)
A splitter, looks similar to regular splitters. Has 1 input, 3 outputs.
There is a GUI interface for the splitter, in which you can adjust the following for each output:
1. Priority, which can be "Low", "Medium" or "High". Same priorities can be adjusted for more than one output.
2. Output rate, which is an integer number of how many items per minute is given out by given output. Can be blank, which means no limit on throughput.
3. Initial state of the built splitter is "Medium priority" and blank throughput for each output.
There is an internal buffer (think of it as an internal inventory) of items. Size of buffer can be 1 to 3 items. Size depends on adjustments made in GUI interface.
After a splitter is built or changes been applied using GUI interface, calculations are made:
1. buffer size equals to how many different priorities are present in current configuration
2. queues of item consumers are created for each priority (of which at least one output assigned). Count of items in buffer is assigned to each queue, from which queue is allowed to take items from buffer. 1 is assigned to highest priority of all present, 2 to the next, 3 to least priority. Let it be called queue_permission
While an item comes from input conveyor belt, following happens:
1. if the buffer is full, item is not accepted and input conveyor stops. Nothing more happens.
2.1. if the buffer has room, item is accepted and put into least free slot.
2.2. queue, which has queue_permission equal to slot just been filled is checked. If then slot is not empty, next queue (with higher queue_permission) is checked, and so on, until either item is consumed or all priorities confirmed not demanding item from this slot.
While queue is checked, following happens:
1. corresponding slot (slot number equals queue_permission) is checked for item presence. If it is empty, nothing more happens.
2. if slot is filled with an item, all consumers in queue are checked in order (order comes from definition of a queue, not of a stack), until found a consumer with not-blocked conveyor output. When such found:
2.1. item is consumed to the corresponding output.
2.2. if no limit on throughput for this consumer's output is set, consumer is immediately added to the queue, otherwise a timer is set, which is meant to add the consumer to the queue and trigger another queue check when it(timer) fires. Timer time equals interval required to maintain adjusted throughput.
While blocked output ceases to be blocked and room appears there to output to, it's priority's queue is checked. (not sure how it works, but something like that works for regular machinery's outputs)
After an item is consumed from a buffer slot, an item from another slot with bigger number is taken to fill the gap, if there is a non-empty slot with bigger number. Rule of queue also applied here. Last in, last out.
An item is always taken from slot 1, regardless of queue_permission value is assigned to queue, which takes the item. It may be required to 3 slots be filled with items, but if an item is taken, it is taken from slot 1.
Also, exactly 1 item occupies exactly 1 slot. Nothing stacks.