From d6dd864c23cccb489a1a3ba61b0df6f7cc4e9434 Mon Sep 17 00:00:00 2001 From: Gurkenglas Date: Tue, 3 Aug 2021 12:23:09 +0200 Subject: [PATCH] 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 --- .../research/designs/wiremod_designs.dm | 7 +- code/modules/research/techweb/all_nodes.dm | 1 + .../wiremod/components/utility/multiplexer.dm | 56 ------------- .../wiremod/components/utility/router.dm | 79 +++++++++++++++++++ tgstation.dme | 2 +- 5 files changed, 87 insertions(+), 58 deletions(-) delete mode 100644 code/modules/wiremod/components/utility/multiplexer.dm create mode 100644 code/modules/wiremod/components/utility/router.dm diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index 4d2b9915ddf..cd44e891f7e 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -193,10 +193,15 @@ id = "comp_mmi" build_path = /obj/item/circuit_component/mmi +/datum/design/component/router + name = "Router Component" + id = "comp_router" + build_path = /obj/item/circuit_component/router + /datum/design/component/multiplexer name = "Multiplexer Component" id = "comp_multiplexer" - build_path = /obj/item/circuit_component/multiplexer + build_path = /obj/item/circuit_component/router/multiplexer /datum/design/component/get_column name = "Get Column Component" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 473881ccef0..bc78d52e744 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -223,6 +223,7 @@ "comp_radio", "comp_ram", "comp_random", + "comp_router", "comp_select_query", "comp_self", "comp_soundemitter", diff --git a/code/modules/wiremod/components/utility/multiplexer.dm b/code/modules/wiremod/components/utility/multiplexer.dm deleted file mode 100644 index 155a8a9bd49..00000000000 --- a/code/modules/wiremod/components/utility/multiplexer.dm +++ /dev/null @@ -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) - diff --git a/code/modules/wiremod/components/utility/router.dm b/code/modules/wiremod/components/utility/router.dm new file mode 100644 index 00000000000..06cc9a5dc23 --- /dev/null +++ b/code/modules/wiremod/components/utility/router.dm @@ -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 diff --git a/tgstation.dme b/tgstation.dme index 75c122e30b7..71ec6811ffb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3737,7 +3737,7 @@ #include "code\modules\wiremod\components\utility\clock.dm" #include "code\modules\wiremod\components\utility\combiner.dm" #include "code\modules\wiremod\components\utility\delay.dm" -#include "code\modules\wiremod\components\utility\multiplexer.dm" +#include "code\modules\wiremod\components\utility\router.dm" #include "code\modules\wiremod\components\utility\ram.dm" #include "code\modules\wiremod\components\utility\typecast.dm" #include "code\modules\wiremod\components\utility\typecheck.dm"