[MIRROR] More circuit components. Restructures the circuit components folder to be more organised. (#6142)

* More circuit components. Restructures the circuit components folder to be more organised.

* Mirror!

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Funce <funce.973@gmail.com>
This commit is contained in:
SkyratBot
2021-06-05 17:15:43 +12:00
committed by GitHub
co-authored by Watermelon914 Funce
parent 6e52d05e2e
commit cc5cf407b0
42 changed files with 630 additions and 106 deletions
@@ -0,0 +1,54 @@
/**
* # Clock Component
*
* Fires every tick of the circuit timer SS
*/
/obj/item/circuit_component/clock
display_name = "Clock"
/// Whether the clock is on or not
var/datum/port/input/on
/// The signal from this clock component
var/datum/port/output/signal
/obj/item/circuit_component/clock/Initialize()
. = ..()
on = add_input_port("On", PORT_TYPE_NUMBER)
signal = add_output_port("Signal", PORT_TYPE_SIGNAL)
/obj/item/circuit_component/clock/input_received(datum/port/input/port)
. = ..()
if(.)
return
if(on.input_value)
start_process()
else
stop_process()
/obj/item/circuit_component/clock/Destroy()
on = null
signal = null
stop_process()
return ..()
/obj/item/circuit_component/clock/process(delta_time)
signal.set_output(COMPONENT_SIGNAL)
/**
* Adds the component to the SSclock_component process list
*
* Starts ticking to send signals between periods of time
*/
/obj/item/circuit_component/clock/proc/start_process()
START_PROCESSING(SSclock_component, src)
/**
* Removes the component to the SSclock_component process list
*
* Signals stop getting sent.
*/
/obj/item/circuit_component/clock/proc/stop_process()
STOP_PROCESSING(SSclock_component, src)
@@ -0,0 +1,46 @@
/**
* # Combiner Component
*
* Combines multiple inputs into 1 output port.
*/
/obj/item/circuit_component/combiner
display_name = "Combiner"
/// The amount of input ports to have
var/input_port_amount = 4
var/datum/port/output/output_port
var/current_type
GLOBAL_LIST_INIT(comp_combiner_options, list(
COMP_COMBINER_ANY,
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
PORT_TYPE_SIGNAL,
))
/obj/item/circuit_component/combiner/Initialize()
options = GLOB.comp_combiner_options
. = ..()
current_type = current_option
for(var/port_id in 1 to input_port_amount)
var/letter = ascii2text(text2ascii("A") + (port_id-1))
add_input_port(letter, current_type)
output_port = add_output_port("Output", current_type)
/obj/item/circuit_component/combiner/input_received(datum/port/input/port)
. = ..()
if(current_type != current_option && (current_option != COMP_COMBINER_ANY || current_type != PORT_TYPE_ANY))
current_type = current_option
if(current_type == COMP_COMBINER_ANY)
current_type = PORT_TYPE_ANY
for(var/datum/port/input/input_port as anything in input_ports)
input_port.set_datatype(current_type)
output_port.set_datatype(current_type)
output_port.set_output(port?.input_value)
if(. || !port)
return TRUE
@@ -0,0 +1,43 @@
/**
* # Delay Component
*
* Delays a signal by a specified duration.
*/
/obj/item/circuit_component/delay
display_name = "Delay"
/// Amount to delay by
var/datum/port/input/delay_amount
/// Input signal to fire the delay
var/datum/port/input/trigger
/// The output of the signal
var/datum/port/output/output
/obj/item/circuit_component/delay/Initialize()
. = ..()
delay_amount = add_input_port("Delay", PORT_TYPE_NUMBER, FALSE)
trigger = add_input_port("Trigger", PORT_TYPE_SIGNAL)
output = add_output_port("Result", PORT_TYPE_SIGNAL)
/obj/item/circuit_component/delay/Destroy()
output = null
trigger = null
delay_amount = null
return ..()
/obj/item/circuit_component/delay/input_received(datum/port/input/port)
. = ..()
if(.)
return
if(!COMPONENT_TRIGGERED_BY(trigger, port))
return
var/delay = delay_amount.input_value
if(delay > COMP_DELAY_MIN_VALUE)
// Convert delay into deciseconds
addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.input_value), delay*10, timer_subsystem =SScircuit_component)
else
output.set_output(trigger.input_value)
@@ -0,0 +1,51 @@
/**
* # RAM Component
*
* Stores the current input when triggered.
* Players will need to think logically when using the RAM component
* as there can be race conditions due to the delays of transferring signals
*/
/obj/item/circuit_component/ram
display_name = "RAM"
/// The input to store
var/datum/port/input/input_port
/// The trigger to store the current value of the input
var/datum/port/input/trigger
/// Clears the current input
var/datum/port/input/clear
/// The current set value
var/datum/port/output/output
/obj/item/circuit_component/ram/Initialize()
. = ..()
input_port = add_input_port("Input", PORT_TYPE_ANY)
trigger = add_input_port("Store", PORT_TYPE_SIGNAL)
clear = add_input_port("Clear", PORT_TYPE_SIGNAL)
output = add_output_port("Stored Value", PORT_TYPE_ANY)
/obj/item/circuit_component/ram/Destroy()
input_port = null
trigger = null
clear = null
output = null
return ..()
/obj/item/circuit_component/ram/input_received(datum/port/input/port)
. = ..()
match_port_datatype(input_port, output)
if(.)
return
if(COMPONENT_TRIGGERED_BY(clear, port))
output.set_output(null)
return
if(!COMPONENT_TRIGGERED_BY(trigger, port))
return
var/input_val = input_port.input_value
output.set_output(input_val)
@@ -0,0 +1,45 @@
/**
* # Typecheck Component
*
* Checks the type of a value
*/
/obj/item/circuit_component/compare/typecheck
display_name = "Typecheck"
input_port_amount = 1
GLOBAL_LIST_INIT(comp_typecheck_options, list(
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
COMP_TYPECHECK_MOB,
COMP_TYPECHECK_HUMAN,
))
/obj/item/circuit_component/compare/typecheck/Initialize()
options = GLOB.comp_typecheck_options
return ..()
/obj/item/circuit_component/compare/typecheck/do_comparisons(list/ports)
if(!length(ports))
return
. = FALSE
// We're only comparing the first port/value. There shouldn't be any more.
var/datum/port/input/input_port = ports[1]
var/input_val = input_port.input_value
switch(current_option)
if(PORT_TYPE_STRING)
return istext(input_val)
if(PORT_TYPE_NUMBER)
return isnum(input_val)
if(PORT_TYPE_LIST)
return islist(input_val)
if(PORT_TYPE_ATOM)
return isatom(input_val)
if(COMP_TYPECHECK_MOB)
return ismob(input_val)
if(COMP_TYPECHECK_HUMAN)
return ishuman(input_val)