diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index 7e40b8e9f2b..a3b4a9a8866 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -276,6 +276,17 @@ id = "comp_list_remove" build_path = /obj/item/circuit_component/variable/list/listremove +/datum/design/component/assoc_list_set + name = "Associative List Set" + id = "comp_assoc_list_set" + build_path = /obj/item/circuit_component/variable/assoc_list/list_set + +/datum/design/component/assoc_list_remove + name = "Associative List Remove" + id = "comp_assoc_list_remove" + build_path = /obj/item/circuit_component/variable/assoc_list/list_remove + + /datum/design/component/list_clear name = "List Clear" id = "comp_list_clear" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 1bf64185152..75d1367618e 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -308,6 +308,8 @@ "comp_access_checker", "comp_arithmetic", "comp_assoc_list_pick", + "comp_assoc_list_remove", + "comp_assoc_list_set", "comp_binary_convert", "comp_clock", "comp_comparison", diff --git a/code/modules/wiremod/components/abstract/assoc_list_variable.dm b/code/modules/wiremod/components/abstract/assoc_list_variable.dm new file mode 100644 index 00000000000..9ad489a6ee5 --- /dev/null +++ b/code/modules/wiremod/components/abstract/assoc_list_variable.dm @@ -0,0 +1,5 @@ +/obj/item/circuit_component/variable/assoc_list + circuit_size = 1 + +/obj/item/circuit_component/variable/assoc_list/get_variable_list(obj/item/integrated_circuit/integrated_circuit) + return integrated_circuit.assoc_list_variables diff --git a/code/modules/wiremod/components/list/assoc_list_remove.dm b/code/modules/wiremod/components/list/assoc_list_remove.dm new file mode 100644 index 00000000000..04b3b489d68 --- /dev/null +++ b/code/modules/wiremod/components/list/assoc_list_remove.dm @@ -0,0 +1,25 @@ +/** + * # Associative List Remove Component + * + * Removes an element from an assoc list. + */ +/obj/item/circuit_component/variable/assoc_list/list_remove + display_name = "Associative List Remove" + desc = "Removes a key from an associative list variable." + category = "List" + + /// Key to remove to the list + var/datum/port/input/to_remove + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/variable/assoc_list/list_remove/populate_ports() + to_remove = add_input_port("To Remove", PORT_TYPE_STRING) + +/obj/item/circuit_component/variable/assoc_list/list_remove/input_received(datum/port/input/port, list/return_values) + if(!current_variable) + return + var/list/info = current_variable.value + var/value_to_remove = to_remove.value + + info -= value_to_remove diff --git a/code/modules/wiremod/components/list/assoc_list_set.dm b/code/modules/wiremod/components/list/assoc_list_set.dm new file mode 100644 index 00000000000..098212df8e1 --- /dev/null +++ b/code/modules/wiremod/components/list/assoc_list_set.dm @@ -0,0 +1,54 @@ +/** + * # Assoc List Set Component + * + * Sets a string value on an assoc list. + */ +/obj/item/circuit_component/variable/assoc_list/list_set + display_name = "Associative List Set" + desc = "Sets a string key on an associative list to a specific value." + category = "List" + + /// Key to set + var/datum/port/input/key + /// Value to set the key to. + var/datum/port/input/value + /// For when the list is too long, a signal is sent here. + var/datum/port/output/failed + + var/max_list_size = 500 + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL + +/obj/item/circuit_component/variable/assoc_list/list_set/get_ui_notices() + . = ..() + . += create_ui_notice("Max List Size: [max_list_size]", "orange", "sitemap") + +/obj/item/circuit_component/variable/assoc_list/list_set/populate_ports() + key = add_input_port("Key", PORT_TYPE_STRING) + value = add_input_port("Value", PORT_TYPE_ANY) + failed = add_output_port("Failed", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/variable/assoc_list/list_set/pre_input_received(datum/port/input/port) + . = ..() + if(current_variable) + value.set_datatype(current_variable.datatype_handler.get_datatype(2)) + +/obj/item/circuit_component/variable/assoc_list/list_set/input_received(datum/port/input/port, list/return_values) + if(!current_variable) + return + var/list/info = current_variable.value + var/key_to_set = key.value + var/value_to_set = value.value + + if(!key_to_set) + failed.set_output(COMPONENT_SIGNAL) + return + + if(length(info) >= max_list_size) + failed.set_output(COMPONENT_SIGNAL) + return + + if(isdatum(value_to_set)) + value_to_set = WEAKREF(value_to_set) + + info[key_to_set] = value_to_set diff --git a/code/modules/wiremod/components/list/list_in.dm b/code/modules/wiremod/components/list/list_find.dm similarity index 76% rename from code/modules/wiremod/components/list/list_in.dm rename to code/modules/wiremod/components/list/list_find.dm index 1c95979354b..995b6c5247a 100644 --- a/code/modules/wiremod/components/list/list_in.dm +++ b/code/modules/wiremod/components/list/list_find.dm @@ -1,11 +1,11 @@ /** - * # List Add Component + * # List Find Component * - * Adds an element to a list. + * Finds an element in a list and returns the index. */ /obj/item/circuit_component/listin display_name = "Element Find" - desc = "Checks if an element is in a list." + desc = "Checks if an element is in a list and returns the index it is as if it is. Index is set to 0 on failure." category = "List" /// The list type we're checking @@ -22,6 +22,8 @@ var/datum/port/output/not_found /// Result of the search var/datum/port/output/result + /// Index of the element if found. + var/datum/port/output/index circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL @@ -35,6 +37,7 @@ found = add_output_port("Succeeded", PORT_TYPE_SIGNAL) not_found = add_output_port("Failed", PORT_TYPE_SIGNAL) result = add_output_port("Result", PORT_TYPE_NUMBER) + index = add_output_port("Index", PORT_TYPE_NUMBER) /obj/item/circuit_component/listin/pre_input_received(datum/port/input/port) . = ..() @@ -50,9 +53,11 @@ if(isdatum(data_to_check)) data_to_check = WEAKREF(data_to_check) - var/actual_result = (data_to_check in info) - if(actual_result) + var/actual_result = info.Find(data_to_check) + index.set_output(actual_result) + if(actual_result != 0) + result.set_output(TRUE) found.set_output(COMPONENT_SIGNAL) else + result.set_output(FALSE) not_found.set_output(COMPONENT_SIGNAL) - result.set_output(actual_result) diff --git a/code/modules/wiremod/components/list/get_column.dm b/code/modules/wiremod/components/table/get_column.dm similarity index 100% rename from code/modules/wiremod/components/list/get_column.dm rename to code/modules/wiremod/components/table/get_column.dm diff --git a/code/modules/wiremod/components/list/index_table.dm b/code/modules/wiremod/components/table/index_table.dm similarity index 100% rename from code/modules/wiremod/components/list/index_table.dm rename to code/modules/wiremod/components/table/index_table.dm diff --git a/code/modules/wiremod/components/list/select.dm b/code/modules/wiremod/components/table/select.dm similarity index 100% rename from code/modules/wiremod/components/list/select.dm rename to code/modules/wiremod/components/table/select.dm diff --git a/code/modules/wiremod/core/duplicator.dm b/code/modules/wiremod/core/duplicator.dm index a784f4030bc..7b373db6e35 100644 --- a/code/modules/wiremod/core/duplicator.dm +++ b/code/modules/wiremod/core/duplicator.dm @@ -21,7 +21,10 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( var/variable_name = variable["name"] var/datum/circuit_variable/variable_datum = new /datum/circuit_variable(variable_name, variable["datatype"]) circuit_variables[variable_name] = variable_datum - if(variable["is_list"]) + if(variable["is_assoc_list"]) + assoc_list_variables[variable_name] = variable_datum + variable_datum.set_value(list()) + else if(variable["is_list"]) list_variables[variable_name] = variable_datum variable_datum.set_value(list()) else @@ -191,10 +194,10 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( var/datum/circuit_variable/variable = circuit_variables[variable_identifier] new_data["name"] = variable.name new_data["datatype"] = variable.datatype - if(variable_identifier in list_variables) + if(variable_identifier in assoc_list_variables) + new_data["is_assoc_list"] = TRUE + else if(variable_identifier in list_variables) new_data["is_list"] = TRUE - else - new_data["is_list"] = FALSE variables += list(new_data) general_data["variables"] = variables diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm index 6b153e637d4..4a04da3480e 100644 --- a/code/modules/wiremod/core/integrated_circuit.dm +++ b/code/modules/wiremod/core/integrated_circuit.dm @@ -59,6 +59,9 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) /// List variables stored on this integrated circuit, with a `variable_name = value` structure var/list/datum/circuit_variable/list_variables = list() + /// Assoc list variables stored on this integrated circuit, with a `variable_name = value` structure + var/list/datum/circuit_variable/assoc_list_variables = list() + /// The maximum amount of setters and getters a circuit can have var/max_setters_and_getters = 30 @@ -598,8 +601,13 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) return if(params["is_list"]) variable_datatype = PORT_TYPE_LIST(variable_datatype) + else if(params["is_assoc_list"]) + variable_datatype = PORT_TYPE_ASSOC_LIST(PORT_TYPE_STRING, variable_datatype) var/datum/circuit_variable/variable = new /datum/circuit_variable(variable_identifier, variable_datatype) - if(params["is_list"]) + if(params["is_assoc_list"]) + variable.set_value(list()) + assoc_list_variables[variable_identifier] = variable + else if(params["is_list"]) variable.set_value(list()) list_variables[variable_identifier] = variable else diff --git a/code/modules/wiremod/datatypes/composite/assoc_list.dm b/code/modules/wiremod/datatypes/composite/assoc_list.dm index 1a603a5ff9c..760658aa7d2 100644 --- a/code/modules/wiremod/datatypes/composite/assoc_list.dm +++ b/code/modules/wiremod/datatypes/composite/assoc_list.dm @@ -4,7 +4,10 @@ expected_types = 2 /datum/circuit_composite_template/assoc_list/generate_name(list/composite_datatypes) - return "[composite_datatypes[1]], [composite_datatypes[2]] assoc. list" + if(composite_datatypes[1] == PORT_TYPE_STRING) + return "[composite_datatypes[2]] associative list" + else + return "[composite_datatypes[1]], [composite_datatypes[2]] assoc. list" /datum/circuit_datatype/composite_instance/assoc_list color = "white" diff --git a/tgstation.dme b/tgstation.dme index c7e0de583ef..76a71a16a86 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5520,6 +5520,7 @@ #include "code\modules\vending\wardrobes.dm" #include "code\modules\vending\youtool.dm" #include "code\modules\visuals\render_steps.dm" +#include "code\modules\wiremod\components\abstract\assoc_list_variable.dm" #include "code\modules\wiremod\components\abstract\compare.dm" #include "code\modules\wiremod\components\abstract\equpiment_action.dm" #include "code\modules\wiremod\components\abstract\list_variable.dm" @@ -5567,21 +5568,20 @@ #include "code\modules\wiremod\components\id\getter.dm" #include "code\modules\wiremod\components\id\info_reader.dm" #include "code\modules\wiremod\components\list\assoc_list_pick.dm" +#include "code\modules\wiremod\components\list\assoc_list_remove.dm" +#include "code\modules\wiremod\components\list\assoc_list_set.dm" #include "code\modules\wiremod\components\list\assoc_literal.dm" #include "code\modules\wiremod\components\list\concat.dm" #include "code\modules\wiremod\components\list\filter.dm" #include "code\modules\wiremod\components\list\foreach.dm" #include "code\modules\wiremod\components\list\format.dm" -#include "code\modules\wiremod\components\list\get_column.dm" #include "code\modules\wiremod\components\list\index.dm" -#include "code\modules\wiremod\components\list\index_table.dm" #include "code\modules\wiremod\components\list\list_add.dm" #include "code\modules\wiremod\components\list\list_clear.dm" -#include "code\modules\wiremod\components\list\list_in.dm" +#include "code\modules\wiremod\components\list\list_find.dm" #include "code\modules\wiremod\components\list\list_literal.dm" #include "code\modules\wiremod\components\list\list_pick.dm" #include "code\modules\wiremod\components\list\list_remove.dm" -#include "code\modules\wiremod\components\list\select.dm" #include "code\modules\wiremod\components\list\split.dm" #include "code\modules\wiremod\components\math\arithmetic.dm" #include "code\modules\wiremod\components\math\binary_conversion.dm" @@ -5602,6 +5602,9 @@ #include "code\modules\wiremod\components\string\textcase.dm" #include "code\modules\wiremod\components\string\tonumber.dm" #include "code\modules\wiremod\components\string\tostring.dm" +#include "code\modules\wiremod\components\table\get_column.dm" +#include "code\modules\wiremod\components\table\index_table.dm" +#include "code\modules\wiremod\components\table\select.dm" #include "code\modules\wiremod\components\utility\clock.dm" #include "code\modules\wiremod\components\utility\delay.dm" #include "code\modules\wiremod\components\utility\router.dm" diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.js b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.js index 39726e9ab5d..5a75ebe4630 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.js +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.js @@ -1,6 +1,7 @@ import { Box, Stack, Section, Button, Input, Dropdown, Icon } from '../../components'; import { Component } from 'inferno'; import { shallowDiffers } from 'common/react'; +import { VARIABLE_ASSOC_LIST, VARIABLE_LIST, VARIABLE_NOT_A_LIST } from './constants'; export class VariableMenu extends Component { constructor() { @@ -69,7 +70,7 @@ export class VariableMenu extends Component { {val.name} - + @@ -125,43 +126,69 @@ export class VariableMenu extends Component { } /> + + + this.setState({ + variable_type: selectedVal, + }) + } + /> + - - this.setState({ - variable_type: selectedVal, - }) - } - /> - - - + + + + diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/constants.js b/tgui/packages/tgui/interfaces/IntegratedCircuit/constants.js index 5d410f1984f..2c91442de31 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/constants.js +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/constants.js @@ -7,3 +7,7 @@ export const OPTION_DROPDOWN_LARGE_CHAR_AMOUNT = 12; export const TIME_UNTIL_PORT_RELEASE_WORKS = 100; export const DEFAULT_COMPONENT_MENU_LIMIT = 6; export const noop = () => {}; + +export const VARIABLE_NOT_A_LIST = 1; +export const VARIABLE_LIST = 2; +export const VARIABLE_ASSOC_LIST = 3; diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/index.js b/tgui/packages/tgui/interfaces/IntegratedCircuit/index.js index 3e7e7afac9e..81d7b1dd5d0 100644 --- a/tgui/packages/tgui/interfaces/IntegratedCircuit/index.js +++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/index.js @@ -4,7 +4,7 @@ import { Component } from 'inferno'; import { Window } from '../../layouts'; import { resolveAsset } from '../../assets'; import { CircuitInfo } from './CircuitInfo'; -import { ABSOLUTE_Y_OFFSET, MOUSE_BUTTON_LEFT, TIME_UNTIL_PORT_RELEASE_WORKS } from './constants'; +import { ABSOLUTE_Y_OFFSET, MOUSE_BUTTON_LEFT, TIME_UNTIL_PORT_RELEASE_WORKS, VARIABLE_ASSOC_LIST, VARIABLE_LIST } from './constants'; import { Connections } from '../common/Connections'; import { ObjectComponent } from './ObjectComponent'; import { DisplayComponent } from './DisplayComponent'; @@ -574,11 +574,12 @@ export class IntegratedCircuit extends Component { variables={variables} types={global_basic_types} onClose={(event) => this.setState({ variableMenuOpen: false })} - onAddVariable={(name, type, asList, event) => + onAddVariable={(name, type, listType, event) => act('add_variable', { variable_name: name, variable_datatype: type, - is_list: asList, + is_list: listType === VARIABLE_LIST, + is_assoc_list: listType === VARIABLE_ASSOC_LIST, }) } onRemoveVariable={(name, event) =>