tgui backend

This commit is contained in:
LetterN
2021-10-28 12:51:31 +08:00
parent 853ff1d8ad
commit 49940c373e
110 changed files with 7353 additions and 259 deletions
@@ -0,0 +1,57 @@
/**
* # Clock Component
*
* Fires every tick of the circuit timer SS
*/
/obj/item/circuit_component/clock
display_name = "Clock"
desc = "A component that repeatedly fires."
/// 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/get_ui_notices()
. = ..()
. += create_ui_notice("Clock Interval: [DisplayTimeText(COMP_CLOCK_DELAY)]", "orange", "clock")
/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.value)
start_process()
else
stop_process()
/obj/item/circuit_component/clock/Destroy()
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,43 @@
/// The minimum delay value that the delay component can have.
#define COMP_DELAY_MIN_VALUE 0.1
/**
* # Delay Component
*
* Delays a signal by a specified duration.
*/
/obj/item/circuit_component/delay
display_name = "Delay"
desc = "A component that delays a signal by a specified duration."
/// 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/input_received(datum/port/input/port)
. = ..()
if(.)
return
if(!COMPONENT_TRIGGERED_BY(trigger, port))
return
var/delay = delay_amount.value
if(delay > COMP_DELAY_MIN_VALUE)
// Convert delay into deciseconds
addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.value), delay*10)
else
output.set_output(trigger.value)
#undef COMP_DELAY_MIN_VALUE
@@ -0,0 +1,70 @@
/**
* # Getter Component
*
* Gets the current value from a variable.
*/
/obj/item/circuit_component/getter
display_name = "Variable Getter"
desc = "A component that gets a variable globally on the circuit."
/// Variable name
var/datum/port/input/option/variable_name
/// The value of the variable
var/datum/port/output/value
var/datum/circuit_variable/current_variable
/obj/item/circuit_component/getter/populate_options()
variable_name = add_option_port("Variable", null)
/obj/item/circuit_component/getter/add_to(obj/item/integrated_circuit/added_to)
. = ..()
variable_name.possible_options = added_to.circuit_variables
/obj/item/circuit_component/getter/removed_from(obj/item/integrated_circuit/removed_from)
variable_name.possible_options = null
return ..()
/obj/item/circuit_component/getter/Initialize()
. = ..()
value = add_output_port("Value", PORT_TYPE_ANY)
/obj/item/circuit_component/getter/input_received(datum/port/input/port)
. = ..()
// We don't care much about the parent's return value. We only care if the parent exists
// since this should never really fail.
if(!parent)
return
var/variable_string = variable_name.value
if(!variable_string)
remove_current_variable()
value.set_output(null)
return
var/datum/circuit_variable/variable = parent.circuit_variables[variable_string]
if(!variable)
remove_current_variable()
value.set_output(null)
return
set_current_variable(variable)
value.set_output(variable.value)
/obj/item/circuit_component/getter/proc/remove_current_variable()
SIGNAL_HANDLER
if(current_variable)
current_variable.remove_listener(src)
UnregisterSignal(current_variable, COMSIG_PARENT_QDELETING)
current_variable = null
/obj/item/circuit_component/getter/proc/set_current_variable(datum/circuit_variable/variable)
if(variable == current_variable)
return
remove_current_variable()
current_variable = variable
current_variable.add_listener(src)
RegisterSignal(current_variable, COMSIG_PARENT_QDELETING, .proc/remove_current_variable)
value.set_datatype(variable.datatype)
@@ -0,0 +1,82 @@
/**
* # 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
var/datum/port/input/option/router_options
/// 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,
)
router_options = add_option_port("Router Options", component_options)
/obj/item/circuit_component/router/Initialize()
. = ..()
current_type = router_options.value
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)
. = ..()
var/current_option = router_options.value
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.value : 1)
var/datum/port/output/output = WRAPACCESS(outs, output_selector ? output_selector.value : 1)
output.set_output(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
@@ -0,0 +1,58 @@
/**
* # Setter Component
*
* Stores the current input when triggered into a variable.
*/
/obj/item/circuit_component/setter
display_name = "Variable Setter"
desc = "A component that sets a variable globally on the circuit."
circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL
/// Variable name
var/datum/port/input/option/variable_name
/// 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
var/current_type
/obj/item/circuit_component/setter/populate_options()
variable_name = add_option_port("Variable", null)
/obj/item/circuit_component/setter/add_to(obj/item/integrated_circuit/added_to)
. = ..()
variable_name.possible_options = added_to.circuit_variables
/obj/item/circuit_component/setter/removed_from(obj/item/integrated_circuit/removed_from)
variable_name.possible_options = null
return ..()
/obj/item/circuit_component/setter/Initialize()
. = ..()
input_port = add_input_port("Input", PORT_TYPE_ANY)
trigger = add_input_port("Store", PORT_TYPE_SIGNAL)
/obj/item/circuit_component/setter/input_received(datum/port/input/port)
. = ..()
var/variable_string = variable_name.value
if(!variable_string)
return
var/datum/circuit_variable/variable = parent.circuit_variables[variable_string]
if(!variable)
return
if(variable.datatype != current_type)
current_type = variable.datatype
input_port.set_datatype(current_type)
if(.)
return
if(!COMPONENT_TRIGGERED_BY(trigger, port))
return TRUE
variable.set_value(input_port.value)
@@ -0,0 +1,60 @@
/**
* # Typecast Component
*
* A component that casts a value to a type if it matches or outputs null.
*/
/obj/item/circuit_component/typecast
display_name = "Typecast"
desc = "A component that casts a value to a type if it matches or outputs null."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
var/datum/port/input/option/typecast_options
var/datum/port/input/input_value
var/datum/port/output/output_value
var/current_type
/obj/item/circuit_component/typecast/Initialize()
. = ..()
current_type = typecast_options.value
input_value = add_input_port("Input", PORT_TYPE_ANY)
output_value = add_output_port("Output", current_type)
/obj/item/circuit_component/typecast/populate_options()
var/static/list/component_options = list(
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
)
typecast_options = add_option_port("Typecast Options", component_options)
/obj/item/circuit_component/typecast/input_received(datum/port/input/port)
. = ..()
var/current_option = typecast_options.value
if(current_type != current_option)
current_type = current_option
output_value.set_datatype(current_type)
if(.)
return
var/value = input_value.value
var/value_to_set = null
switch(current_option)
if(PORT_TYPE_STRING)
if(istext(value))
value_to_set = value
if(PORT_TYPE_NUMBER)
if(isnum(value))
value_to_set = value
if(PORT_TYPE_LIST)
if(islist(value))
value_to_set = value
if(PORT_TYPE_ATOM)
if(isatom(value))
value_to_set = value
output_value.set_output(value_to_set)
@@ -0,0 +1,51 @@
#define COMP_TYPECHECK_MOB "organism"
#define COMP_TYPECHECK_HUMAN "humanoid"
/**
* # Typecheck Component
*
* Checks the type of a value
*/
/obj/item/circuit_component/compare/typecheck
display_name = "Typecheck"
desc = "A component that checks the type of its input."
input_port_amount = 1
var/datum/port/input/option/typecheck_options
/obj/item/circuit_component/compare/typecheck/populate_options()
var/static/component_options = list(
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
COMP_TYPECHECK_MOB,
COMP_TYPECHECK_HUMAN,
)
typecheck_options = add_option_port("Typecheck Options", component_options)
/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.value
switch(typecheck_options.value)
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)
#undef COMP_TYPECHECK_MOB
#undef COMP_TYPECHECK_HUMAN