[MIRROR] Refactors port types completely and adds the option type. Refactors options to use this new type (#7386)

* Refactors port types completely and adds the option type. Refactors options to use this new type (#60571)

Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com>

* Refactors port types completely and adds the option type. Refactors options to use this new type

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Watermelon914 <3052169-Watermelon914@ users.noreply.gitlab.com>
This commit is contained in:
SkyratBot
2021-08-04 18:30:56 +01:00
committed by GitHub
co-authored by Watermelon914 Watermelon914
parent 742f11f0d8
commit 3ab1e7ebe2
39 changed files with 487 additions and 271 deletions
+12
View File
@@ -26,6 +26,8 @@
#define PORT_TYPE_LIST "list"
/// Table datatype. Derivative of list, contains other lists with matching columns.
#define PORT_TYPE_TABLE "table"
/// Options datatype. Derivative of string.
#define PORT_TYPE_OPTION "option"
// Other datatypes
/// Atom datatype
@@ -114,6 +116,10 @@
#define COMP_PROC_GLOBAL "Global"
#define COMP_PROC_OBJECT "Object"
// Bar overlay component
#define COMP_BAR_OVERLAY_VERTICAL "Vertical"
#define COMP_BAR_OVERLAY_HORIZONTAL "Horizontal"
// Shells
/// Whether a circuit is stuck on a shell and cannot be removed (by a user)
@@ -148,3 +154,9 @@
#define CIRCUIT_FLAG_ADMIN (1<<3)
/// This circuit component does not show in the menu.
#define CIRCUIT_FLAG_HIDDEN (1<<4)
// Datatype flags
/// The datatype supports manual inputs
#define DATATYPE_FLAG_ALLOW_MANUAL_INPUT (1<<0)
/// The datatype won't update the value when it is connected to the port
#define DATATYPE_FLAG_AVOID_VALUE_UPDATE (1<<1)
+3 -6
View File
@@ -107,8 +107,8 @@
/// The targets to set the status of.
var/datum/port/input/targets
/// Sets the new status of the targets. If set to null, the status is taken from the options.
var/datum/port/input/new_status
/// Sets the new status of the targets.
var/datum/port/input/option/new_status
/// Returns the new status set once the setting is complete. Good for locating errors.
var/datum/port/output/new_status_set
@@ -135,12 +135,11 @@
COMP_STATE_DISCHARGED,
COMP_STATE_NONE,
)
options = component_options
new_status = add_option_port("Arrest Options", component_options)
/obj/item/circuit_component/arrest_console_arrest/Initialize()
. = ..()
targets = add_input_port("Targets", PORT_TYPE_TABLE)
new_status = add_input_port("New Status", PORT_TYPE_STRING)
new_status_set = add_output_port("Set Status", PORT_TYPE_STRING)
on_fail = add_output_port("Failed", PORT_TYPE_SIGNAL)
@@ -154,8 +153,6 @@
return
var/status_to_set = new_status.input_value
if(!status_to_set || !(status_to_set in options))
status_to_set = current_option
new_status_set.set_output(status_to_set)
var/list/target_table = targets.input_value
@@ -891,6 +891,8 @@
display_name = "Air Alarm"
desc = "Controls levels of gases and their temperature as well as all vents and scrubbers in the room."
var/datum/port/input/option/air_alarm_options
var/datum/port/input/min_2
var/datum/port/input/min_1
var/datum/port/input/max_1
@@ -919,24 +921,18 @@
/obj/item/circuit_component/air_alarm/populate_options()
var/static/list/component_options
var/static/list/options_to_key
if(!component_options)
component_options = list(
"Pressure",
"Temperature"
)
options_to_key = list(
"Pressure" = "pressure",
"Temperature" = "temperature"
)
for(var/gas_id in GLOB.meta_gas_info)
component_options.Add(GLOB.meta_gas_info[gas_id][META_GAS_NAME])
options_to_key[GLOB.meta_gas_info[gas_id][META_GAS_NAME]] = gas_id2path(gas_id)
component_options[GLOB.meta_gas_info[gas_id][META_GAS_NAME]] = gas_id2path(gas_id)
options = component_options
options_map = options_to_key
air_alarm_options = add_option_port("Air Alarm Options", component_options)
options_map = component_options
/obj/item/circuit_component/air_alarm/register_usb_parent(atom/movable/parent)
. = ..()
@@ -953,6 +949,8 @@
if(. || !connected_alarm || connected_alarm.locked)
return
var/current_option = air_alarm_options.input_value
if(COMPONENT_TRIGGERED_BY(request_data, port))
var/turf/alarm_turf = get_turf(connected_alarm)
var/datum/gas_mixture/environment = alarm_turf.return_air()
+17 -25
View File
@@ -42,31 +42,28 @@
/// The power usage whenever this component receives an input
var/power_usage_per_input = 1
/// The current selected option
var/current_option
/// The options that this component can take on. Limited to strings
var/list/options
// Whether the component is removable or not. Only affects user UI
var/removable = TRUE
// Defines which shells support this component. Only used as an informational guide, does not restrict placing these components in circuits.
var/required_shells = null
/// Called when the option ports should be set up
/obj/item/circuit_component/proc/populate_options()
return
/// Extension of add_input_port. Simplifies the code to make an option port to reduce boilerplate
/obj/item/circuit_component/proc/add_option_port(name, list/list_to_use)
return add_input_port(name, PORT_TYPE_OPTION, port_type = /datum/port/input/option, extra_args = list("possible_options" = list_to_use))
/obj/item/circuit_component/Initialize()
. = ..()
if(name == COMPONENT_DEFAULT_NAME)
name = "[lowertext(display_name)] [COMPONENT_DEFAULT_NAME]"
populate_options()
if(length(options))
current_option = options[1]
return INITIALIZE_HINT_LATELOAD
/// Called when the options variable should be set.
/obj/item/circuit_component/proc/populate_options()
return
/obj/item/circuit_component/LateInitialize()
. = ..()
if(circuit_flags & CIRCUIT_FLAG_INPUT_SIGNAL)
@@ -120,17 +117,6 @@
for(var/datum/port/input/port_to_disconnect as anything in input_ports)
port_to_disconnect.disconnect()
/**
* Sets the option on this component
*
* Can only be a value from the options variable
* Arguments:
* * option - The option that has been switched to.
*/
/obj/item/circuit_component/proc/set_option(option)
current_option = option
TRIGGER_CIRCUIT_COMPONENT(src, null)
/**
* Adds an input port and returns it
*
@@ -139,8 +125,12 @@
* * type - The datatype it handles
* * trigger - Whether this input port triggers an update on the component when updated.
*/
/obj/item/circuit_component/proc/add_input_port(name, type, trigger = TRUE, default = null, index = null)
var/datum/port/input/input_port = new(src, name, type, trigger, default)
/obj/item/circuit_component/proc/add_input_port(name, type, trigger = TRUE, default = null, index = null, port_type = /datum/port/input, extra_args = null)
var/list/arguments = list(src)
arguments += args
if(extra_args)
arguments += extra_args
var/datum/port/input/input_port = new port_type(arglist(arguments))
if(index)
input_ports.Insert(index, input_port)
else
@@ -169,7 +159,9 @@
* * type - The datatype it handles.
*/
/obj/item/circuit_component/proc/add_output_port(name, type)
var/datum/port/output/output_port = new(src, name, type)
var/list/arguments = list(src)
arguments += args
var/datum/port/output/output_port = new(arglist(arguments))
output_ports += output_port
return output_port
@@ -19,11 +19,13 @@
/// The result from the output
var/datum/port/output/result
var/list/datum/port/input/compare_ports = list()
/obj/item/circuit_component/compare/Initialize()
. = ..()
for(var/port_id in 1 to input_port_amount)
var/letter = ascii2text(text2ascii("A") + (port_id-1))
add_input_port(letter, PORT_TYPE_ANY)
compare_ports += add_input_port(letter, PORT_TYPE_ANY)
load_custom_ports()
compare = add_input_port("Compare", PORT_TYPE_SIGNAL)
@@ -43,11 +45,7 @@
if(.)
return
var/list/ports = input_ports.Copy()
if(input_port_amount)
ports.Cut(input_port_amount+1)
var/logic_result = do_comparisons(ports)
var/logic_result = do_comparisons(compare_ports)
if(COMPONENT_TRIGGERED_BY(compare, port))
if(logic_result)
true.set_output(COMPONENT_SIGNAL)
@@ -7,6 +7,9 @@
display_name = "Radio"
desc = "A component that can listen and send frequencies. If set to private, the component will only receive signals from other components attached to circuitboards with the same owner id."
/// The publicity options. Controls whether it's public or private.
var/datum/port/input/option/public_options
/// Frequency input
var/datum/port/input/freq
/// Signal input
@@ -22,7 +25,7 @@
COMP_RADIO_PUBLIC,
COMP_RADIO_PRIVATE,
)
options = component_options
public_options = add_option_port("Encryption Options", component_options)
/obj/item/circuit_component/radio/Initialize()
. = ..()
@@ -59,7 +62,7 @@
if(signal.data["code"] != round(code.input_value || 0))
return
if(current_option == COMP_RADIO_PRIVATE && parent?.owner_id != signal.data["key"])
if(public_options.input_value == COMP_RADIO_PRIVATE && parent?.owner_id != signal.data["key"])
return
trigger_output.set_output(COMPONENT_SIGNAL)
@@ -8,6 +8,9 @@
desc = "A component that emits a sound when it receives an input. The frequency is a multiplier which determines the speed at which the sound is played"
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// Sound to play
var/datum/port/input/option/sound_file
/// Volume of the sound when played
var/datum/port/input/volume
@@ -40,7 +43,7 @@
COMP_SOUND_WARN,
COMP_SOUND_SLOWCLAP,
)
options = component_options
sound_file = add_option_port("Sound Option", component_options)
var/static/options_to_sound = list(
COMP_SOUND_BUZZ = 'sound/machines/buzz-sigh.ogg',
@@ -65,7 +68,7 @@
if(TIMER_COOLDOWN_CHECK(parent, COOLDOWN_CIRCUIT_SOUNDEMITTER))
return
var/sound_to_play = options_map[current_option]
var/sound_to_play = options_map[sound_file.input_value]
if(!sound_to_play)
return
@@ -5,9 +5,11 @@
*/
/obj/item/circuit_component/proccall
display_name = "Proc Call"
desc = "A component that gets a variable on an object."
desc = "A component that calls a proc on an object."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
var/datum/port/input/option/proccall_options
/// Entity to proccall on
var/datum/port/input/entity
@@ -26,7 +28,7 @@
COMP_PROC_GLOBAL,
)
options = component_options
proccall_options = add_option_port("Proccall Options", component_options)
/obj/item/circuit_component/proccall/Initialize()
. = ..()
@@ -42,7 +44,7 @@
return
var/called_on
if(current_option == COMP_PROC_OBJECT)
if(proccall_options.input_value == COMP_PROC_OBJECT)
called_on = entity.input_value
else
called_on = GLOBAL_PROC
@@ -5,7 +5,7 @@
*/
/obj/item/circuit_component/spawn_atom
display_name = "Spawn Atom"
desc = "A component that returns the value of a list at a given index."
desc = "Spawns an atom at a desired location"
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
/// The input path to convert into a typepath
@@ -5,7 +5,7 @@
*/
/obj/item/circuit_component/to_type
display_name = "String To Type"
desc = "A component that returns the value of a list at a given index."
desc = "Converts a string into a typepath. Useful for adding components."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL|CIRCUIT_FLAG_ADMIN
/// The input path to convert into a typepath
@@ -5,42 +5,40 @@
* Requires a BCI shell.
*/
#define BAR_OVERLAY_LIMIT 10
/obj/item/circuit_component/object_overlay/bar
display_name = "Bar Overlay"
desc = "Requires a BCI shell. A component that shows a bar overlay ontop of an object from a range of 0 to 100."
var/datum/port/input/option/bar_overlay_options
var/datum/port/input/bar_number
var/overlay_limit = 10
/obj/item/circuit_component/object_overlay/bar/Initialize()
. = ..()
bar_number = add_input_port("Number", PORT_TYPE_NUMBER)
/obj/item/circuit_component/object_overlay/bar/populate_options()
var/static/component_options_bar = list(
"Vertical",
"Horizontal"
COMP_BAR_OVERLAY_VERTICAL = "barvert",
COMP_BAR_OVERLAY_HORIZONTAL = "barhoriz"
)
options = component_options_bar
var/static/options_to_icons_bar = list(
"Vertical" = "barvert",
"Horizontal" = "barhoriz"
)
options_map = options_to_icons_bar
bar_overlay_options = add_option_port("Bar Overlay Options", component_options_bar)
options_map = component_options_bar
/obj/item/circuit_component/object_overlay/bar/show_to_owner(atom/target_atom, mob/living/owner)
if(LAZYLEN(active_overlays) >= BAR_OVERLAY_LIMIT)
if(LAZYLEN(active_overlays) >= overlay_limit)
return
var/current_option = bar_overlay_options.input_value
if(active_overlays[target_atom])
QDEL_NULL(active_overlays[target_atom])
var/number_clear = clamp(bar_number.input_value, 0, 100)
if(current_option == "Horizontal")
if(current_option == COMP_BAR_OVERLAY_HORIZONTAL)
number_clear = round(number_clear / 6.25) * 6.25
else if(current_option == "Vertical")
else if(current_option == COMP_BAR_OVERLAY_VERTICAL)
number_clear = round(number_clear / 10) * 10
var/image/cool_overlay = image(icon = 'icons/hud/screen_bci.dmi', loc = target_atom, icon_state = "[options_map[current_option]][number_clear]", layer = RIPPLE_LAYER)
@@ -56,5 +54,3 @@
cool_overlay,
owner,
))
#undef BAR_OVERLAY_LIMIT
@@ -13,6 +13,8 @@
required_shells = list(/obj/item/organ/cyberimp/bci)
var/datum/port/input/option/object_overlay_options
/// Target atom
var/datum/port/input/target
@@ -44,20 +46,6 @@
/obj/item/circuit_component/object_overlay/populate_options()
var/static/component_options = list(
"Corners (Blue)",
"Corners (Red)",
"Circle (Blue)",
"Circle (Red)",
"Small Corners (Blue)",
"Small Corners (Red)",
"Triangle (Blue)",
"Triangle (Red)",
"HUD mark (Blue)",
"HUD mark (Red)"
)
options = component_options
var/static/options_to_icons = list(
"Corners (Blue)" = "hud_corners",
"Corners (Red)" = "hud_corners_red",
"Circle (Blue)" = "hud_circle",
@@ -69,7 +57,8 @@
"HUD mark (Blue)" = "hud_mark",
"HUD mark (Red)" = "hud_mark_red"
)
options_map = options_to_icons
object_overlay_options = add_option_port("Object", component_options)
options_map = component_options
/obj/item/circuit_component/object_overlay/register_shell(atom/movable/shell)
if(istype(shell, /obj/item/organ/cyberimp/bci))
@@ -106,7 +95,7 @@
if(active_overlays[target_atom])
QDEL_NULL(active_overlays[target_atom])
var/image/cool_overlay = image(icon = 'icons/hud/screen_bci.dmi', loc = target_atom, icon_state = options_map[current_option], layer = RIPPLE_LAYER)
var/image/cool_overlay = image(icon = 'icons/hud/screen_bci.dmi', loc = target_atom, icon_state = options_map[object_overlay_options.input_value], layer = RIPPLE_LAYER)
if(image_pixel_x.input_value)
cool_overlay.pixel_x = image_pixel_x.input_value
@@ -8,6 +8,8 @@
desc = "A component used with USB cables that can perform select queries on a list based on the column name selected. The values are then compared with the comparison input."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
var/datum/port/input/option/comparison_options
/// The list to perform the filter on
var/datum/port/input/received_table
@@ -31,7 +33,7 @@
COMP_COMPARISON_GREATER_THAN_OR_EQUAL,
COMP_COMPARISON_LESS_THAN_OR_EQUAL,
)
options = component_options
comparison_options = add_option_port("Comparison Options", component_options)
/obj/item/circuit_component/select/Initialize()
. = ..()
@@ -43,6 +45,8 @@
/obj/item/circuit_component/select/input_received(datum/port/input/port)
. = ..()
var/current_option = comparison_options.input_value
switch(current_option)
if(COMP_COMPARISON_EQUAL, COMP_COMPARISON_NOT_EQUAL)
if(current_type != PORT_TYPE_ANY)
@@ -11,9 +11,12 @@
/// The amount of input ports to have
var/input_port_amount = 4
var/datum/port/input/option/arithmetic_option
/// The result from the output
var/datum/port/output/output
var/list/arithmetic_ports
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/obj/item/circuit_component/arithmetic/populate_options()
@@ -25,13 +28,14 @@
COMP_ARITHMETIC_MIN,
COMP_ARITHMETIC_MAX,
)
options = component_options
arithmetic_option = add_option_port("Arithmetic Option", component_options)
/obj/item/circuit_component/arithmetic/Initialize()
. = ..()
arithmetic_ports = list()
for(var/port_id in 1 to input_port_amount)
var/letter = ascii2text(text2ascii("A") + (port_id-1))
add_input_port(letter, PORT_TYPE_NUMBER)
arithmetic_ports += add_input_port(letter, PORT_TYPE_NUMBER)
output = add_output_port("Output", PORT_TYPE_NUMBER)
@@ -40,10 +44,8 @@
if(.)
return
var/list/ports = input_ports.Copy()
var/datum/port/input/first_port = ports[1]
ports -= first_port
ports -= trigger_input
var/list/ports = arithmetic_ports.Copy()
var/datum/port/input/first_port = popleft(ports)
var/result = first_port.input_value
for(var/datum/port/input/input_port as anything in ports)
@@ -51,7 +53,7 @@
if(isnull(value))
continue
switch(current_option)
switch(arithmetic_option.input_value)
if(COMP_ARITHMETIC_ADD)
result += value
if(COMP_ARITHMETIC_SUBTRACT)
@@ -7,6 +7,8 @@
display_name = "Comparison"
desc = "A component that compares two objects."
var/datum/port/input/option/comparison_option
input_port_amount = 2
var/current_type = PORT_TYPE_ANY
@@ -19,20 +21,20 @@
COMP_COMPARISON_GREATER_THAN_OR_EQUAL,
COMP_COMPARISON_LESS_THAN_OR_EQUAL,
)
options = component_options
comparison_option = add_option_port("Comparison Option", component_options)
/obj/item/circuit_component/compare/comparison/input_received(datum/port/input/port)
switch(current_option)
switch(comparison_option.input_value)
if(COMP_COMPARISON_EQUAL, COMP_COMPARISON_NOT_EQUAL)
if(current_type != PORT_TYPE_ANY)
current_type = PORT_TYPE_ANY
input_ports[1].set_datatype(PORT_TYPE_ANY)
input_ports[2].set_datatype(PORT_TYPE_ANY)
compare_ports[1].set_datatype(PORT_TYPE_ANY)
compare_ports[2].set_datatype(PORT_TYPE_ANY)
else
if(current_type != PORT_TYPE_NUMBER)
current_type = PORT_TYPE_NUMBER
input_ports[1].set_datatype(PORT_TYPE_NUMBER)
input_ports[2].set_datatype(PORT_TYPE_NUMBER)
compare_ports[1].set_datatype(PORT_TYPE_NUMBER)
compare_ports[2].set_datatype(PORT_TYPE_NUMBER)
return ..()
@@ -41,8 +43,9 @@
return FALSE
// Comparison component only compares the first two ports
var/input1 = input_ports[1].input_value
var/input2 = input_ports[2].input_value
var/input1 = compare_ports[1].input_value
var/input2 = compare_ports[2].input_value
var/current_option = comparison_option.input_value
switch(current_option)
if(COMP_COMPARISON_EQUAL)
@@ -7,16 +7,20 @@
display_name = "Logic"
desc = "A component with 'and' and 'or' capabilities."
var/datum/port/input/option/logic_options
/obj/item/circuit_component/compare/logic/populate_options()
var/static/component_options = list(
COMP_LOGIC_AND,
COMP_LOGIC_OR,
COMP_LOGIC_XOR,
)
options = component_options
logic_options = add_option_port("Logic Options", component_options)
/obj/item/circuit_component/compare/logic/do_comparisons(list/ports)
. = FALSE
var/current_option = logic_options.input_value
// Used by XOR
var/total_ports = 0
var/total_true_ports = 0
@@ -7,6 +7,8 @@
display_name = "Text Case"
desc = "A component that makes its input uppercase or lowercase."
var/datum/port/input/option/textcase_options
/// The input port
var/datum/port/input/input_port
@@ -20,7 +22,7 @@
COMP_TEXT_LOWER,
COMP_TEXT_UPPER,
)
options = component_options
textcase_options = add_option_port("Textcase Options", component_options)
/obj/item/circuit_component/textcase/Initialize()
. = ..()
@@ -37,7 +39,7 @@
return
var/result
switch(current_option)
switch(textcase_options.input_value)
if(COMP_TEXT_LOWER)
result = lowertext(value)
if(COMP_TEXT_UPPER)
@@ -9,9 +9,11 @@
/// The amount of input ports to have
var/input_port_amount = 4
var/datum/port/input/option/combiner_options
var/datum/port/output/output_port
var/list/combiner_ports = list()
var/current_type
/obj/item/circuit_component/combiner/populate_options()
@@ -23,21 +25,21 @@
PORT_TYPE_ATOM,
PORT_TYPE_SIGNAL,
)
options = component_options
combiner_options = add_option_port("Combiner Options", component_options)
/obj/item/circuit_component/combiner/Initialize()
. = ..()
current_type = current_option
current_type = combiner_options.input_value
for(var/port_id in 1 to input_port_amount)
var/letter = ascii2text(text2ascii("A") + (port_id-1))
add_input_port(letter, current_option)
output_port = add_output_port("Output", current_option)
combiner_ports += 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_type = current_option
for(var/datum/port/input/input_port as anything in input_ports)
if(current_type != combiner_options.input_value)
current_type = combiner_options.input_value
for(var/datum/port/input/input_port as anything in combiner_ports)
input_port.set_datatype(current_type)
output_port.set_datatype(current_type)
@@ -10,6 +10,8 @@
desc = "A component that retains a variable."
circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL
var/datum/port/input/option/ram_options
/// The input to store
var/datum/port/input/input_port
/// The trigger to store the current value of the input
@@ -31,16 +33,15 @@
PORT_TYPE_ATOM,
PORT_TYPE_SIGNAL,
)
options = component_options
ram_options = add_option_port("RAM Options", component_options)
/obj/item/circuit_component/ram/Initialize()
. = ..()
current_type = current_option
input_port = add_input_port("Input", current_type)
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", current_type)
output = add_output_port("Stored Value", PORT_TYPE_ANY)
/obj/item/circuit_component/ram/Destroy()
input_port = null
@@ -51,8 +52,8 @@
/obj/item/circuit_component/ram/input_received(datum/port/input/port)
. = ..()
if(current_type != current_option)
current_type = current_option
if(current_type != ram_options.input_value)
current_type = ram_options.input_value
input_port.set_datatype(current_type)
output.set_datatype(current_type)
@@ -8,6 +8,8 @@
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
@@ -31,11 +33,11 @@
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
)
options = component_options
router_options = add_option_port("Router Options", component_options)
/obj/item/circuit_component/router/Initialize()
. = ..()
current_type = current_option
current_type = router_options.input_value
if(input_port_amount > 1)
input_selector = add_input_port("Input Selector", PORT_TYPE_NUMBER, default = 1)
if(output_port_amount > 1)
@@ -61,6 +63,7 @@
#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.input_value
if(current_type != current_option)
current_type = current_option
for(var/datum/port/input/input as anything in ins)
@@ -8,6 +8,8 @@
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
@@ -16,21 +18,22 @@
/obj/item/circuit_component/typecast/Initialize()
. = ..()
current_type = current_option
current_type = typecast_options.input_value
input_value = add_input_port("Input", PORT_TYPE_ANY)
output_value = add_output_port("Output", current_option)
output_value = add_output_port("Output", current_type)
/obj/item/circuit_component/typecast/populate_options()
var/static/component_options = list(
var/static/list/component_options = list(
PORT_TYPE_STRING,
PORT_TYPE_NUMBER,
PORT_TYPE_LIST,
PORT_TYPE_ATOM,
)
options = component_options
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.input_value
if(current_type != current_option)
current_type = current_option
output_value.set_datatype(current_type)
@@ -8,6 +8,7 @@
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(
@@ -18,7 +19,7 @@
COMP_TYPECHECK_MOB,
COMP_TYPECHECK_HUMAN,
)
options = component_options
typecheck_options = add_option_port("Typecheck Options", component_options)
/obj/item/circuit_component/compare/typecheck/do_comparisons(list/ports)
if(!length(ports))
@@ -28,7 +29,7 @@
// 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)
switch(typecheck_options.input_value)
if(PORT_TYPE_STRING)
return istext(input_val)
if(PORT_TYPE_NUMBER)
+91
View File
@@ -0,0 +1,91 @@
// An assoc list of all the possible datatypes.
GLOBAL_LIST_INIT(circuit_datatypes, generate_circuit_datatypes())
/proc/generate_circuit_datatypes()
var/list/datatypes_by_key = list()
for(var/datum/circuit_datatype/type as anything in subtypesof(/datum/circuit_datatype))
if(!initial(type.datatype))
continue
datatypes_by_key[initial(type.datatype)] = new type()
return datatypes_by_key
/**
* A circuit datatype. Used to determine the datatype of a port and also handle any additional behaviour.
*/
/datum/circuit_datatype
/// The key. Used to identify the datatype. Should be a define.
var/datatype
/// The color of the port in the UI. Doesn't work with hex colours.
var/color = "blue"
/// The flags of the circuit datatype
var/datatype_flags = 0
/**
* Returns the value to be set for the port
*
* Used for implicit conversions between outputs and inputs (e.g. number -> string)
* and applying/removing signals on inputs
*/
/datum/circuit_datatype/proc/convert_value(datum/port/port, value_to_convert)
return value_to_convert
/**
* Determines if a datatype is compatible with another port of a different type.
* Note: This is ALWAYS called on the input port, never on the output port.
* Inputs need to care about what types they're receiving, output ports don't have to care.
*
* Arguments:
* * datatype_to_check - The datatype to check
*/
/datum/circuit_datatype/proc/can_receive_from_datatype(datatype_to_check)
return datatype == datatype_to_check // This is already done by default on the input port.
/**
* Called when the datatype is given to a port.
*
* Arguments:
* * gained_port - The gained port.
*/
/datum/circuit_datatype/proc/on_gain(datum/port/gained_port)
gained_port.disconnect()
/**
* Called when the datatype is removed from a port.
*
* Arguments:
* * lost_port - The removed port.
*/
/datum/circuit_datatype/proc/on_loss(datum/port/lost_port)
return
/**
* Determines if a port is compatible with this datatype.
* This WILL throw a runtime if it returns false. This is for sanity checking and it should not return false
* unless under extraordinary circumstances or people fail to write proper code.
*
* Arguments:
* * port - The port to check if it is compatible.
*/
/datum/circuit_datatype/proc/is_compatible(datum/port/port)
return TRUE
/**
* The data to send to the UI attached to the port. Received by the type in FUNDAMENTAL_PORT_TYPES
*
* Arguments:
* * port - The port sending the data.
*/
/datum/circuit_datatype/proc/datatype_ui_data(datum/port/port)
return
/**
* When an input is manually set by a player. This is where extra sanitizing can happen. Will still call convert_value()
*
* Arguments:
* * port - The port sending the data.
* *
*/
/datum/circuit_datatype/proc/handle_manual_input(datum/port/input/port, mob/user, user_input)
return user_input
+10
View File
@@ -0,0 +1,10 @@
/datum/circuit_datatype/any
datatype = PORT_TYPE_ANY
color = "blue"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT
/datum/circuit_datatype/any/can_receive_from_datatype(datatype_to_check)
return TRUE
/datum/circuit_datatype/any/handle_manual_input(datum/port/input/port, mob/user, user_input)
return text2num(user_input) || user_input
+9
View File
@@ -0,0 +1,9 @@
// This file is for types that do not have any special conversion behaviour
/datum/circuit_datatype/list_type
datatype = PORT_TYPE_LIST
color = "white"
/datum/circuit_datatype/table
datatype = PORT_TYPE_TABLE
color = "grey"
+10
View File
@@ -0,0 +1,10 @@
/datum/circuit_datatype/entity
datatype = PORT_TYPE_ATOM
color = "purple"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT
/datum/circuit_datatype/entity/convert_value(datum/port/port, value_to_convert)
var/atom/object = value_to_convert
if(QDELETED(object))
return null
return object
+14
View File
@@ -0,0 +1,14 @@
/datum/circuit_datatype/number
datatype = PORT_TYPE_NUMBER
color = "green"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT
/datum/circuit_datatype/number/can_receive_from_datatype(datatype_to_check)
. = ..()
if(.)
return
return datatype_to_check == PORT_TYPE_NUMBER
/datum/circuit_datatype/number/handle_manual_input(datum/port/input/port, mob/user, user_input)
return text2num(user_input)
+33
View File
@@ -0,0 +1,33 @@
/datum/port/input/option
var/list/possible_options
/datum/port/input/option/New(obj/item/circuit_component/to_connect, name, datatype, trigger, default, possible_options)
. = ..()
src.possible_options = possible_options
set_input(default, FALSE)
/datum/circuit_datatype/option
datatype = PORT_TYPE_OPTION
color = "violet"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT
/datum/circuit_datatype/option/is_compatible(datum/port/gained_port)
return istype(gained_port, /datum/port/input/option)
/datum/circuit_datatype/option/can_receive_from_datatype(datatype_to_check)
. = ..()
if(.)
return
return datatype_to_check == PORT_TYPE_STRING
/datum/circuit_datatype/option/convert_value(datum/port/input/option/port, value_to_convert)
if(!port.possible_options)
return null
if(value_to_convert in port.possible_options)
return value_to_convert
return port.possible_options[1]
/datum/circuit_datatype/option/datatype_ui_data(datum/port/input/option/port)
return port.possible_options
+17
View File
@@ -0,0 +1,17 @@
/datum/circuit_datatype/signal
datatype = PORT_TYPE_SIGNAL
color = "teal"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT|DATATYPE_FLAG_AVOID_VALUE_UPDATE
/datum/circuit_datatype/signal/can_receive_from_datatype(datatype_to_check)
. = ..()
if(.)
return
return datatype_to_check == PORT_TYPE_NUMBER
/datum/circuit_datatype/signal/handle_manual_input(datum/port/input/port, mob/user, user_input)
var/atom/parent = port.connected_component
if(parent)
parent.balloon_alert(user, "triggered [port.name]")
return COMPONENT_SIGNAL
+17
View File
@@ -0,0 +1,17 @@
/datum/circuit_datatype/string
datatype = PORT_TYPE_STRING
color = "orange"
datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT
/datum/circuit_datatype/string/can_receive_from_datatype(datatype_to_check)
return TRUE
/datum/circuit_datatype/string/convert_value(datum/port/port, value_to_convert)
if(isnull(value_to_convert))
return
// So that they can't easily get the name like this.
if(isatom(value_to_convert))
return PORT_TYPE_ATOM
else
return copytext("[value_to_convert]", 1, PORT_MAX_STRING_LENGTH)
+15 -5
View File
@@ -6,6 +6,7 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list(
PORT_TYPE_STRING,
PORT_TYPE_LIST,
PORT_TYPE_ANY,
PORT_TYPE_OPTION,
))
/// Loads a circuit based on json data at a location. Can also load usb connections, such as arrest consoles.
@@ -33,6 +34,17 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list(
identifiers_to_circuit[identifier] = component
component.load_data_from_list(component_data)
var/list/input_ports_data = component_data["input_ports_stored_data"]
for(var/port_name in input_ports_data)
var/datum/port/input/port
var/list/port_data = input_ports_data[port_name]
for(var/datum/port/input/port_to_check as anything in component.input_ports)
if(port_to_check.name == port_name)
port = port_to_check
break
port.set_input(port_data["stored_data"])
var/list/external_objects = general_data["external_objects"]
for(var/identifier in external_objects)
var/list/object_data = external_objects[identifier]
@@ -118,6 +130,7 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list(
component_data["type"] = component.type
var/list/connections = list()
var/list/input_ports_stored_data = list()
for(var/datum/port/input/port as anything in component.input_ports)
var/list/connection_data = list()
var/datum/port/output/output_port = port.connected_port
@@ -125,12 +138,13 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list(
if(isnull(port.input_value) || !(port.datatype in GLOB.circuit_dupe_whitelisted_types))
continue
connection_data["stored_data"] = port.input_value
connections[port.name] = connection_data
input_ports_stored_data[port.name] = connection_data
continue
connection_data["component_id"] = circuit_to_identifiers[output_port.connected_component]
connection_data["port_name"] = output_port.name
connections[port.name] = connection_data
component_data["connections"] = connections
component_data["input_ports_stored_data"] = input_ports_stored_data
component.save_data_to_list(component_data)
circuit_data[identifier] = component_data
@@ -160,15 +174,11 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list(
component_data["rel_x"] = rel_x
component_data["rel_y"] = rel_y
component_data["option"] = current_option
/// Loads data from a list
/obj/item/circuit_component/proc/load_data_from_list(list/component_data)
rel_x = component_data["rel_x"]
rel_y = component_data["rel_y"]
set_option(component_data["option"])
/client/proc/load_circuit()
set name = "Load Circuit"
set category = "Admin.Fun"
+7 -25
View File
@@ -245,6 +245,7 @@
"connected_to" = REF(port.connected_port),
"color" = port.color,
"current_data" = current_data,
"datatype_data" = port.datatype_ui_data(user),
))
component_data["output_ports"] = list()
for(var/datum/port/output/port as anything in component.output_ports)
@@ -252,14 +253,12 @@
"name" = port.name,
"type" = port.datatype,
"ref" = REF(port),
"color" = port.color
"color" = port.color,
))
component_data["name"] = component.display_name
component_data["x"] = component.rel_x
component_data["y"] = component.rel_y
component_data["option"] = component.current_option
component_data["options"] = component.options
component_data["removable"] = component.removable
.["components"] += list(component_data)
@@ -332,7 +331,7 @@
var/datum/port/input/input_port = input_component.input_ports[input_port_id]
var/datum/port/output/output_port = output_component.output_ports[output_port_id]
if(input_port.datatype != PORT_TYPE_ANY && !output_port.compatible_datatype(input_port.datatype))
if(!input_port.can_receive_from_datatype(output_port.datatype))
return
input_port.register_output_port(output_port)
@@ -378,16 +377,6 @@
component.rel_x = min(max(-COMPONENT_MAX_POS, text2num(params["rel_x"])), COMPONENT_MAX_POS)
component.rel_y = min(max(-COMPONENT_MAX_POS, text2num(params["rel_y"])), COMPONENT_MAX_POS)
. = TRUE
if("set_component_option")
var/component_id = text2num(params["component_id"])
if(!WITHIN_RANGE(component_id, attached_components))
return
var/obj/item/circuit_component/component = attached_components[component_id]
var/option = params["option"]
if(!(option in component.options))
return
component.set_option(option)
. = TRUE
if("set_component_input")
var/component_id = text2num(params["component_id"])
var/port_id = text2num(params["port_id"])
@@ -427,17 +416,10 @@
port.set_input(marker.marked_atom)
return TRUE
var/user_input = params["input"]
switch(port.datatype)
if(PORT_TYPE_NUMBER)
port.set_input(text2num(user_input))
if(PORT_TYPE_ANY)
port.set_input(text2num(user_input) || user_input)
if(PORT_TYPE_STRING)
port.set_input(user_input)
if(PORT_TYPE_SIGNAL)
balloon_alert(usr, "triggered [port.name]")
port.set_input(COMPONENT_SIGNAL)
var/user_input = port.handle_manual_input(usr, params["input"])
if(isnull(user_input))
return TRUE
port.set_input(user_input)
. = TRUE
if("get_component_value")
var/component_id = text2num(params["component_id"])
+50 -70
View File
@@ -16,7 +16,7 @@
var/datatype
/// The default port type. Stores the original datatype of the port set on Initialize.
var/default_datatype
var/datum/circuit_datatype/datatype_handler
/// The port color. If unset, appears as blue.
var/color
@@ -30,29 +30,11 @@
// with the other variable declarations
src.connected_component = to_connect
src.name = name
src.datatype = datatype
src.default_datatype = datatype
src.color = datatype_to_color()
///Converts the datatype into an appropriate colour
/datum/port/proc/datatype_to_color()
switch(datatype)
if(PORT_TYPE_ATOM)
return "purple"
if(PORT_TYPE_NUMBER)
return "green"
if(PORT_TYPE_STRING)
return "orange"
if(PORT_TYPE_LIST)
return "white"
if(PORT_TYPE_SIGNAL)
return "teal"
if(PORT_TYPE_TABLE)
return "grey"
set_datatype(datatype)
/datum/port/Destroy(force)
connected_component = null
datatype_handler = null
return ..()
/**
@@ -61,30 +43,8 @@
* Used for implicit conversions between outputs and inputs (e.g. number -> string)
* and applying/removing signals on inputs
*/
/datum/port/proc/convert_value(prev_value, value_to_convert)
if(prev_value == value_to_convert)
return prev_value
. = value_to_convert
if(isnull(value_to_convert))
return null
switch(datatype)
if(PORT_TYPE_STRING)
// So that they can't easily get the name like this.
if(isatom(value_to_convert))
return PORT_TYPE_ATOM
else
return copytext("[value_to_convert]", 1, PORT_MAX_STRING_LENGTH)
if(PORT_TYPE_NUMBER)
if(!istext(value_to_convert) && !isnum(value_to_convert))
return null
return text2num(value_to_convert)
if(isatom(value_to_convert))
var/atom/atom_to_check = value_to_convert
if(QDELETED(atom_to_check))
return null
/datum/port/proc/convert_value(value_to_convert)
return datatype_handler.convert_value(src, value_to_convert)
/**
* Sets the datatype of the port.
@@ -93,12 +53,33 @@
* * type_to_set - The type this port is set to.
*/
/datum/port/proc/set_datatype(type_to_set)
if(type_to_set == datatype)
return
if(datatype_handler)
datatype_handler.on_loss(src)
datatype_handler = null
var/datum/circuit_datatype/handler = GLOB.circuit_datatypes[type_to_set]
if(!handler || !handler.is_compatible(src))
type_to_set = PORT_TYPE_ANY
handler = GLOB.circuit_datatypes[type_to_set]
// We can't leave this port without a type or else it'll just keep spewing out unnecessary and unneeded runtimes as well as leaving the circuit in a broken state.
stack_trace("[src] port attempted to be set to an incompatible datatype! (target datatype to set: [type_to_set])")
datatype = type_to_set
color = datatype_to_color()
disconnect()
datatype_handler = handler
color = datatype_handler.color
datatype_handler.on_gain(src)
if(connected_component?.parent)
SStgui.update_uis(connected_component.parent)
/**
* Returns the data from the datatype
*/
/datum/port/proc/datatype_ui_data()
return datatype_handler.datatype_ui_data(src)
/**
* Disconnects a port from all other ports
*
@@ -138,7 +119,7 @@
/datum/port/output/proc/set_output(value)
if(isatom(output_value))
UnregisterSignal(output_value, COMSIG_PARENT_QDELETING)
output_value = convert_value(output_value, value)
output_value = convert_value(value)
if(isatom(output_value))
RegisterSignal(output_value, COMSIG_PARENT_QDELETING, .proc/null_output)
@@ -154,26 +135,6 @@
. = ..()
set_output(null)
/**
* Determines if a datatype is compatible with another port of a different type.
*
* Arguments:
* * other_datatype - The datatype to check
*/
/datum/port/output/proc/compatible_datatype(datatype_to_check)
if(datatype_to_check == datatype)
return TRUE
switch(datatype)
if(PORT_TYPE_NUMBER)
// Can easily convert a number to string. Everything else has to use a tostring component
return datatype_to_check == PORT_TYPE_STRING || datatype_to_check == PORT_TYPE_SIGNAL
if(PORT_TYPE_SIGNAL)
// A signal port is just a number port but distinguishable
return datatype_to_check == PORT_TYPE_NUMBER
return FALSE
/**
* # Input Port
*
@@ -220,9 +181,28 @@
connected_port = port_to_register
SEND_SIGNAL(connected_port, COMSIG_PORT_OUTPUT_CONNECT, src)
// For signals, we don't update the input to prevent sending a signal when connecting ports.
if(datatype != PORT_TYPE_SIGNAL)
if(!(datatype_handler.datatype_flags & DATATYPE_FLAG_AVOID_VALUE_UPDATE))
set_input(connected_port.output_value)
/**
* Determines if a datatype is compatible with another port of a different type.
*
* Arguments:
* * other_datatype - The datatype to check
*/
/datum/port/input/proc/can_receive_from_datatype(datatype_to_check)
return datatype_handler.can_receive_from_datatype(datatype_to_check)
/**
* Determines if a datatype is compatible with another port of a different type.
*
* Arguments:
* * other_datatype - The datatype to check
*/
/datum/port/input/proc/handle_manual_input(mob/user, manual_input)
if(datatype_handler.datatype_flags & DATATYPE_FLAG_ALLOW_MANUAL_INPUT)
return datatype_handler.handle_manual_input(src, user, manual_input)
return null
/**
* Sets a timer depending on the value of the input_receive_delay
@@ -246,7 +226,7 @@
/datum/port/input/proc/set_input(new_value, send_update = TRUE)
if(isatom(input_value))
UnregisterSignal(input_value, COMSIG_PARENT_QDELETING)
input_value = convert_value(input_value, new_value)
input_value = convert_value(new_value)
if(isatom(input_value))
RegisterSignal(input_value, COMSIG_PARENT_QDELETING, .proc/null_output)
@@ -38,6 +38,9 @@
desc = "Represents an action the user can take when implanted with the brain-computer interface."
required_shells = list(/obj/item/organ/cyberimp/bci)
/// The icon of the button
var/datum/port/input/option/icon_options
/// The name to use for the button
var/datum/port/input/button_name
@@ -51,7 +54,7 @@
. = ..()
if (!isnull(default_icon))
set_option(default_icon)
icon_options.set_input(default_icon)
button_name = add_input_port("Name", PORT_TYPE_STRING)
@@ -99,7 +102,7 @@
"Wireless",
)
options = action_options
icon_options = add_option_port("Icon", action_options)
/obj/item/circuit_component/bci_action/register_shell(atom/movable/shell)
var/obj/item/organ/cyberimp/bci/bci = shell
@@ -126,7 +129,7 @@
/obj/item/circuit_component/bci_action/proc/update_action()
bci_action.name = button_name.input_value
bci_action.button_icon_state = "bci_[replacetextEx(lowertext(current_option), " ", "_")]"
bci_action.button_icon_state = "bci_[replacetextEx(lowertext(icon_options.input_value), " ", "_")]"
/datum/action/innate/bci_action
name = "Action"
+8
View File
@@ -3671,6 +3671,7 @@
#include "code\modules\vending\youtool.dm"
#include "code\modules\wiremod\component.dm"
#include "code\modules\wiremod\component_printer.dm"
#include "code\modules\wiremod\datatypes.dm"
#include "code\modules\wiremod\duplicator.dm"
#include "code\modules\wiremod\integrated_circuit.dm"
#include "code\modules\wiremod\marker.dm"
@@ -3728,6 +3729,13 @@
#include "code\modules\wiremod\components\utility\router.dm"
#include "code\modules\wiremod\components\utility\typecast.dm"
#include "code\modules\wiremod\components\utility\typecheck.dm"
#include "code\modules\wiremod\datatypes\any.dm"
#include "code\modules\wiremod\datatypes\basic.dm"
#include "code\modules\wiremod\datatypes\entity.dm"
#include "code\modules\wiremod\datatypes\number.dm"
#include "code\modules\wiremod\datatypes\option.dm"
#include "code\modules\wiremod\datatypes\signal.dm"
#include "code\modules\wiremod\datatypes\string.dm"
#include "code\modules\wiremod\preset\hello_world.dm"
#include "code\modules\wiremod\preset\speech_relay.dm"
#include "code\modules\wiremod\shell\airlock.dm"
@@ -1,21 +1,19 @@
import { useBackend } from '../../backend';
import {
Box,
Button, Flex,
} from '../../components';
import { FUNDAMENTAL_DATA_TYPES } from './FundamentalTypes';
import { Box, Button, Flex } from '../../components';
import { FUNDAMENTAL_DATA_TYPES, DATATYPE_DISPLAY_HANDLERS } from './FundamentalTypes';
import { NULL_REF } from './constants';
export const DisplayName = (props, context) => {
const { act } = useBackend(context);
const { port, isOutput, componentId, portIndex, ...rest } = props;
const InputComponent = FUNDAMENTAL_DATA_TYPES[port.type || 'any'];
const InputComponent = FUNDAMENTAL_DATA_TYPES[port.type || 'unknown'];
const TypeDisplayHandler = DATATYPE_DISPLAY_HANDLERS[port.type || 'unknown'];
const hasInput = !isOutput
&& port.connected_to === NULL_REF
&& InputComponent;
const hasInput
= !isOutput && port.connected_to === NULL_REF && InputComponent;
const displayType = TypeDisplayHandler? TypeDisplayHandler(port) : port.type;
return (
<Box {...rest}>
@@ -23,24 +21,28 @@ export const DisplayName = (props, context) => {
<Flex.Item>
{(hasInput && (
<InputComponent
setValue={(val, extraParams) => act('set_component_input', {
component_id: componentId,
port_id: portIndex,
input: val,
...extraParams,
})}
setValue={(val, extraParams) =>
act('set_component_input', {
component_id: componentId,
port_id: portIndex,
input: val,
...extraParams,
})}
color={port.color}
name={port.name}
value={port.current_data} />
value={port.current_data}
extraData={port.datatype_data}
/>
))
|| (isOutput && (
<Button
compact
color="transparent"
onClick={() => act('get_component_value', {
component_id: componentId,
port_id: portIndex,
})}>
onClick={() =>
act('get_component_value', {
component_id: componentId,
port_id: portIndex,
})}>
<Box color="white">{port.name}</Box>
</Button>
))
@@ -51,7 +53,7 @@ export const DisplayName = (props, context) => {
fontSize={0.75}
opacity={0.25}
textAlign={isOutput ? 'right' : 'left'}>
{port.type || 'any'}
{displayType || 'unknown'}
</Box>
</Flex.Item>
</Flex>
@@ -1,5 +1,5 @@
import { BasicInput } from './BasicInput';
import { NumberInput, Button, Stack, Input } from '../../components';
import { NumberInput, Button, Stack, Input, Dropdown, Box } from '../../components';
export const FUNDAMENTAL_DATA_TYPES = {
'string': (props, context) => {
@@ -10,6 +10,7 @@ export const FUNDAMENTAL_DATA_TYPES = {
placeholder={name}
value={value}
onChange={(e, val) => setValue(val)}
width="96px"
/>
</BasicInput>
);
@@ -32,7 +33,7 @@ export const FUNDAMENTAL_DATA_TYPES = {
);
},
'entity': (props, context) => {
const { name, setValue, color } = props;
const { name, setValue } = props;
return (
<Button
content={name}
@@ -54,6 +55,21 @@ export const FUNDAMENTAL_DATA_TYPES = {
/>
);
},
'option': (props, context) => {
const { value, setValue, extraData } = props;
return (
<Dropdown
className="Datatype__Option"
color={"transparent"}
options={typeof extraData === 'object'
? Object.keys(extraData)
: extraData}
onSelected={setValue}
displayText={value}
noscroll
/>
);
},
'any': (props, context) => {
const { name, value, setValue, color } = props;
return (
@@ -75,6 +91,7 @@ export const FUNDAMENTAL_DATA_TYPES = {
placeholder={name}
value={value}
onChange={(e, val) => setValue(val)}
width="64px"
/>
</Stack.Item>
</Stack>
@@ -82,3 +99,9 @@ export const FUNDAMENTAL_DATA_TYPES = {
);
},
};
export const DATATYPE_DISPLAY_HANDLERS = {
'option': (port) => {
return port.name.toLowerCase();
},
};
@@ -95,8 +95,6 @@ export class ObjectComponent extends Component {
y,
index,
color = 'blue',
options,
option,
removable,
locations,
onPortUpdated,
@@ -142,21 +140,6 @@ export class ObjectComponent extends Component {
<Stack.Item grow={1} unselectable="on">
{name}
</Stack.Item>
{!!options && (
<Stack.Item>
<Dropdown
color={color}
nochevron
over
options={options}
displayText={option}
noscroll
onSelected={(selected) => act('set_component_option', {
component_id: index,
option: selected,
})} />
</Stack.Item>
)}
<Stack.Item>
<Button
color="transparent"
@@ -43,3 +43,12 @@ $bg-map: colors.$bg-map !default;
stroke: $color-value !important;
}
}
$border-color: #88bfff !default;
$border-radius: base.$border-radius !default;
.Datatype__Option {
border: base.em(1px) solid $border-color;
border: base.em(1px) solid rgba($border-color, 0.75);
border-radius: $border-radius;
}