Multiplexer gains extra outputs and wraps out-of-range indices. (#60462)

* Multiplexer also selects output port, indices wrap

* Remove broken multiplexer type changer

* Scratch that. Wasn't broken.

* Document WRAPACCESS

* Rename Multiplexer to Router

* Address review.

* typo

* Address review.

* fix partial rename

* Address review

* double desc
This commit is contained in:
Gurkenglas
2021-08-03 12:23:09 +02:00
committed by GitHub
parent 03fed1a68c
commit d6dd864c23
5 changed files with 87 additions and 58 deletions
@@ -1,56 +0,0 @@
/**
* # Combiner Component
*
* Combines multiple inputs into 1 output port.
*/
/obj/item/circuit_component/multiplexer
display_name = "Multiplexer"
desc = "A component that allows you to selectively choose which input port provides an output. The first port is the selector and takes a number between 1 and the maximum port amount."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The port to select from, goes from 1 to input_port_amount
var/datum/port/input/input_port
/// The amount of input ports to have
var/input_port_amount = 4
var/datum/port/output/output_port
/// Current type of the ports
var/current_type
/// The multiplexer inputs. These are what get selected for the output by the input_port.
var/list/datum/port/input/multiplexer_inputs
/obj/item/circuit_component/multiplexer/populate_options()
var/static/component_options = list(
PORT_TYPE_ANY,
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
)
options = component_options
/obj/item/circuit_component/multiplexer/Initialize()
. = ..()
current_type = current_option
input_port = add_input_port("Selector", PORT_TYPE_NUMBER, default = 1)
multiplexer_inputs = list()
for(var/port_id in 1 to input_port_amount)
multiplexer_inputs += add_input_port("Port [port_id]", current_type)
output_port = add_output_port("Output", current_type)
/obj/item/circuit_component/multiplexer/input_received(datum/port/input/port)
. = ..()
if(current_type != current_option)
current_type = current_option
for(var/datum/port/input/input_port as anything in multiplexer_inputs)
input_port.set_datatype(current_type)
output_port.set_datatype(current_type)
input_port.set_input(clamp(input_port.input_value || 1, 1, input_port_amount), FALSE)
if(.)
return
output_port.set_output(multiplexer_inputs[input_port.input_value].input_value)
@@ -0,0 +1,79 @@
/**
* # Router Component
*
* Writes one of multiple inputs to one of multiple outputs.
*/
/obj/item/circuit_component/router
display_name = "Router"
desc = "Copies the input chosen by \"Input Selector\" to the output chosen by \"Output Selector\"."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// Which ports to connect.
var/datum/port/input/input_selector
var/datum/port/input/output_selector
/// How many ports to have.
var/input_port_amount = 4
var/output_port_amount = 4
/// Current type of the ports
var/current_type
/// The ports to route.
var/list/datum/port/input/ins
var/list/datum/port/output/outs
/obj/item/circuit_component/router/populate_options()
var/static/component_options = list(
PORT_TYPE_ANY,
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
)
options = component_options
/obj/item/circuit_component/router/Initialize()
. = ..()
current_type = current_option
if(input_port_amount > 1)
input_selector = add_input_port("Input Selector", PORT_TYPE_NUMBER, default = 1)
if(output_port_amount > 1)
output_selector = add_input_port("Output Selector", PORT_TYPE_NUMBER, default = 1)
ins = list()
for(var/port_id in 1 to input_port_amount)
ins += add_input_port(input_port_amount > 1 ? "Input [port_id]" : "Input", current_type)
outs = list()
for(var/port_id in 1 to output_port_amount)
outs += add_output_port(output_port_amount > 1 ? "Output [port_id]" : "Output", current_type)
/obj/item/circuit_component/router/Destroy()
input_selector = null
output_selector = null
ins.Cut()
ins = null
outs.Cut()
outs = null
return ..()
// If I is in range, L[I]. If I is out of range, wrap around.
#define WRAPACCESS(L, I) L[(((I||1)-1)%length(L)+length(L))%length(L)+1]
/obj/item/circuit_component/router/input_received(datum/port/input/port)
. = ..()
if(current_type != current_option)
current_type = current_option
for(var/datum/port/input/input as anything in ins)
input.set_datatype(current_type)
for(var/datum/port/output/output as anything in outs)
output.set_datatype(current_type)
if(.)
return
var/datum/port/input/input = WRAPACCESS(ins, input_selector ? input_selector.input_value : 1)
var/datum/port/output/output = WRAPACCESS(outs, output_selector ? output_selector.input_value : 1)
output.set_output(input.input_value)
/obj/item/circuit_component/router/multiplexer
display_name = "Multiplexer"
desc = "Copies the input chosen by \"Input Selector\" to the output."
output_port_amount = 1