refactor(vm): use proper repr on generated enums if possible, generate stationpedia prefab enum

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers
2024-04-30 21:15:13 -07:00
parent 6bdc6f210b
commit c3182035ae
10 changed files with 314 additions and 209 deletions

View File

@@ -18,11 +18,70 @@ where
pub deprecated: bool,
}
struct ReprEnumVariant<P>
where
P: Display + FromStr,
{
pub value: P,
pub deprecated: bool,
pub props: Vec<(String, String)>
}
fn write_repr_enum<'a, T: std::io::Write, I, P>(
writer: &mut BufWriter<T>,
name: &str,
variants: I,
use_phf: bool,
) where
P: Display + FromStr + 'a,
I: IntoIterator<Item = &'a (String, ReprEnumVariant<P>)>,
{
let additional_strum = if use_phf { "#[strum(use_phf)]\n" } else { "" };
let repr = std::any::type_name::<P>();
write!(
writer,
"#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, EnumString, AsRefStr, EnumProperty, EnumIter, FromRepr, Serialize, Deserialize)]\n\
{additional_strum}\
#[repr({repr})]\n\
pub enum {name} {{\n"
)
.unwrap();
for (name, variant) in variants {
let variant_name = name.replace('.', "").to_case(Case::Pascal);
let serialize = vec![name.clone()];
let serialize_str = serialize
.into_iter()
.map(|s| format!("serialize = \"{s}\""))
.collect::<Vec<String>>()
.join(", ");
let mut props = Vec::new();
if variant.deprecated {
props.push("deprecated = \"true\"".to_owned());
}
for (prop_name, prop_val) in &variant.props {
props.push(format!("{prop_name} = \"{prop_val}\""));
}
let val = &variant.value;
props.push(format!("value = \"{val}\""));
let props_str = if !props.is_empty() {
format!(", props( {} )", props.join(", "))
} else {
"".to_owned()
};
writeln!(
writer,
" #[strum({serialize_str}{props_str})] {variant_name} = {val}{repr},"
)
.unwrap();
}
writeln!(writer, "}}").unwrap();
}
fn write_enum<'a, T: std::io::Write, I, P>(
writer: &mut BufWriter<T>,
name: &str,
variants: I,
use_phf: bool,
) where
P: Display + FromStr + 'a,
I: IntoIterator<Item = &'a (String, EnumVariant<P>)>,
@@ -72,7 +131,7 @@ fn write_logictypes() {
let output_file = File::create(dest_path).unwrap();
let mut writer = BufWriter::new(&output_file);
let mut logictypes: Vec<(String, EnumVariant<u16>)> = Vec::new();
let mut logictypes: Vec<(String, ReprEnumVariant<u16>)> = Vec::new();
let l_infile = Path::new("data/logictypes.txt");
let l_contents = fs::read_to_string(l_infile).unwrap();
@@ -80,42 +139,26 @@ fn write_logictypes() {
let mut it = line.splitn(3, ' ');
let name = it.next().unwrap();
let val_str = it.next().unwrap();
let val: Option<u16> = val_str.parse().ok();
let value: u16 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u16: {err}"));
let docs = it.next();
let deprecated = docs
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
.unwrap_or(false);
if let Some(val) = val {
if let Some((_other_name, variant)) = logictypes
.iter_mut()
.find(|(_, variant)| variant.value == Some(val))
{
variant.aliases.push(name.to_string());
variant.deprecated = deprecated;
} else {
logictypes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: Some(val),
deprecated,
},
));
}
} else {
logictypes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: val,
deprecated,
},
));
let mut props = Vec::new();
if let Some(docs) = docs {
props.push(("docs".to_owned(), docs.to_owned()));
}
logictypes.push((
name.to_string(),
ReprEnumVariant {
value,
deprecated,
props,
},
));
}
let mut slotlogictypes: Vec<(String, EnumVariant<u8>)> = Vec::new();
let mut slotlogictypes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
let sl_infile = Path::new("data/slotlogictypes.txt");
let sl_contents = fs::read_to_string(sl_infile).unwrap();
@@ -123,39 +166,23 @@ fn write_logictypes() {
let mut it = line.splitn(3, ' ');
let name = it.next().unwrap();
let val_str = it.next().unwrap();
let val: Option<u8> = val_str.parse().ok();
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
let docs = it.next();
let deprecated = docs
.map(|docs| docs.trim().to_uppercase() == "DEPRECATED")
.unwrap_or(false);
if let Some(val) = val {
if let Some((_other_name, variant)) = slotlogictypes
.iter_mut()
.find(|(_, variant)| variant.value == Some(val))
{
variant.aliases.push(name.to_string());
variant.deprecated = deprecated;
} else {
slotlogictypes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: Some(val),
deprecated,
},
));
}
} else {
slotlogictypes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: val,
deprecated,
},
));
let mut props = Vec::new();
if let Some(docs) = docs {
props.push(("docs".to_owned(), docs.to_owned()));
}
slotlogictypes.push((
name.to_string(),
ReprEnumVariant {
value,
deprecated,
props,
},
));
}
write_repr_enum(&mut writer, "LogicType", &logictypes, true);
@@ -198,7 +225,7 @@ fn write_enums() {
));
}
write_repr_enum(&mut writer, "LogicEnums", &enums_map, true);
write_enum(&mut writer, "LogicEnums", &enums_map, true);
println!("cargo:rerun-if-changed=data/enums.txt");
}
@@ -210,7 +237,7 @@ fn write_modes() {
let output_file = File::create(dest_path).unwrap();
let mut writer = BufWriter::new(&output_file);
let mut batchmodes: Vec<(String, EnumVariant<u8>)> = Vec::new();
let mut batchmodes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
let b_infile = Path::new("data/batchmodes.txt");
let b_contents = fs::read_to_string(b_infile).unwrap();
@@ -218,37 +245,19 @@ fn write_modes() {
let mut it = line.splitn(3, ' ');
let name = it.next().unwrap();
let val_str = it.next().unwrap();
let val: Option<u8> = val_str.parse().ok();
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
if let Some(val) = val {
if let Some((_other_name, variant)) = batchmodes
.iter_mut()
.find(|(_, variant)| variant.value == Some(val))
{
variant.aliases.push(name.to_string());
} else {
batchmodes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: Some(val),
deprecated: false,
},
));
}
} else {
batchmodes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: val,
deprecated: false,
},
));
}
batchmodes.push((
name.to_string(),
ReprEnumVariant {
value,
deprecated: false,
props: Vec::new(),
},
));
}
let mut reagentmodes: Vec<(String, EnumVariant<u8>)> = Vec::new();
let mut reagentmodes: Vec<(String, ReprEnumVariant<u8>)> = Vec::new();
let r_infile = Path::new("data/reagentmodes.txt");
let r_contents = fs::read_to_string(r_infile).unwrap();
@@ -256,34 +265,16 @@ fn write_modes() {
let mut it = line.splitn(3, ' ');
let name = it.next().unwrap();
let val_str = it.next().unwrap();
let val: Option<u8> = val_str.parse().ok();
let value: u8 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid u8: {err}"));
reagentmodes.push((
name.to_string(),
ReprEnumVariant {
value,
deprecated: false,
props: Vec::new(),
},
));
if let Some(val) = val {
if let Some((_other_name, variant)) = reagentmodes
.iter_mut()
.find(|(_, variant)| variant.value == Some(val))
{
variant.aliases.push(name.to_string());
} else {
reagentmodes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: Some(val),
deprecated: false,
},
));
}
} else {
reagentmodes.push((
name.to_string(),
EnumVariant {
aliases: Vec::new(),
value: val,
deprecated: false,
},
));
}
}
write_repr_enum(&mut writer, "BatchMode", &batchmodes, false);
@@ -381,12 +372,50 @@ fn write_instructions_enum() {
println!("cargo:rerun-if-changed=data/instructions.txt");
}
fn write_stationpedia() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("stationpedia_prefabs.rs");
let output_file = File::create(dest_path).unwrap();
let mut writer = BufWriter::new(&output_file);
let mut prefabs: Vec<(String, ReprEnumVariant<i32>)> = Vec::new();
let l_infile = Path::new("data/stationpedia.txt");
let l_contents = fs::read_to_string(l_infile).unwrap();
for line in l_contents.lines().filter(|l| !l.trim().is_empty()) {
let mut it = line.splitn(3, ' ');
let val_str = it.next().unwrap();
let value: i32 = val_str.parse().unwrap_or_else(|err| panic!("'{val_str}' not valid i32: {err}"));
let name = it.next().unwrap();
let title = it.next();
let mut props = Vec::new();
if let Some(title) = title {
props.push(("title".to_owned(), title.to_owned()));
}
prefabs.push((
name.to_string(),
ReprEnumVariant {
value,
deprecated: false,
props,
},
));
}
write_repr_enum(&mut writer, "StationpediaPrefab", &prefabs, true);
println!("cargo:rerun-if-changed=data/stationpdeia.txt");
}
fn main() {
// write_instructions();
write_logictypes();
write_modes();
write_constants();
write_enums();
write_instructions_enum();
write_stationpedia();
}

View File

@@ -81,6 +81,7 @@ LogicType.AlignmentError 243
LogicType.Apex 238
LogicType.AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing.
LogicType.AutoShutOff 218 Turns off all devices in the rocket upon reaching destination
LogicType.BestContactFilter 267
LogicType.Bpm 103 Bpm
LogicType.BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage.
LogicType.CelestialHash 242
@@ -346,6 +347,11 @@ PowerMode.Charging 3
PowerMode.Discharged 1
PowerMode.Discharging 2
PowerMode.Idle 0
ReEntryProfile.High 3
ReEntryProfile.Max 4
ReEntryProfile.Medium 2
ReEntryProfile.None 0
ReEntryProfile.Optimal 1
RobotMode.Follow 1
RobotMode.MoveToTarget 2
RobotMode.None 0
@@ -353,6 +359,12 @@ RobotMode.PathToTarget 5
RobotMode.Roam 3
RobotMode.StorageFull 6
RobotMode.Unload 4
RocketMode.Chart 5
RocketMode.Discover 4
RocketMode.Invalid 0
RocketMode.Mine 2
RocketMode.None 1
RocketMode.Survey 3
SlotClass.AccessCard 22
SlotClass.Appliance 18
SlotClass.Back 3
@@ -388,10 +400,18 @@ SlotClass.ScanningHead 36
SlotClass.SensorProcessingUnit 30
SlotClass.SoundCartridge 34
SlotClass.Suit 2
SlotClass.SuitMod 39
SlotClass.Tool 17
SlotClass.Torpedo 20
SlotClass.Uniform 12
SlotClass.Wreckage 33
SorterInstruction.FilterPrefabHashEquals 1
SorterInstruction.FilterPrefabHashNotEquals 2
SorterInstruction.FilterQuantityCompare 5
SorterInstruction.FilterSlotTypeCompare 4
SorterInstruction.FilterSortingClassCompare 3
SorterInstruction.LimitNextExecutionByCount 6
SorterInstruction.None 0
SortingClass.Appliances 6
SortingClass.Atmospherics 7
SortingClass.Clothing 5

View File

@@ -1,14 +1,15 @@
Acceleration 216 Change in velocity. Rockets that are deccelerating when landing will show this as negative value.
Activate 9 1 if device is activated (usually means running), otherwise 0
AirRelease 75 The current state of the air release system, for example AirRelease = 1 for a Hardsuit sets Air Release to On
AlignmentError 243
Apex 238
AlignmentError 243
Apex 238
AutoLand 226 Engages the automatic landing algorithm. The rocket will automatically throttle and turn on and off its engines to achieve a smooth landing.
AutoShutOff 218 Turns off all devices in the rocket upon reaching destination
BestContactFilter 267
Bpm 103 Bpm
BurnTimeRemaining 225 Estimated time in seconds until fuel is depleted. Calculated based on current fuel usage.
CelestialHash 242
CelestialParentHash 250
CelestialHash 242
CelestialParentHash 250
Channel0 165 Channel 0 on a cable network which should be considered volatile
Channel1 166 Channel 1 on a cable network which should be considered volatile
Channel2 167 Channel 2 on a cable network which should be considered volatile
@@ -18,10 +19,10 @@ Channel5 170 Channel 5 on a cable network which should be considered volatile
Channel6 171 Channel 6 on a cable network which should be considered volatile
Channel7 172 Channel 7 on a cable network which should be considered volatile
Charge 11 The current charge the device has
Chart 256
ChartedNavPoints 259
Chart 256
ChartedNavPoints 259
ClearMemory 62 When set to 1, clears the counter memory (e.g. ExportCount). Will set itself back to 0 when actioned
CollectableGoods 101
CollectableGoods 101
Color 38 \n Whether driven by concerns for clarity, safety or simple aesthetics, {LINK:Stationeers;Stationeers} have access to a small rainbow of colors for their constructions. These are the color setting for devices, represented as an integer.\n\n0: Blue\n1: Grey\n2: Green\n3: Orange\n4: Red\n5: Yellow\n6: White\n7: Black\n8: Brown\n9: Khaki\n10: Pink\n11: Purple\n\n It is an unwavering universal law that anything higher than 11 will be purple. The {LINK:ODA;ODA} is powerless to change this. Similarly, anything lower than 0 will be Blue.\n
Combustion 98 The assess atmosphere is on fire. Returns 1 if atmosphere is on fire, 0 if not.
CombustionInput 146 The assess atmosphere is on fire. Returns 1 if device's input network is on fire, 0 if not.
@@ -31,34 +32,34 @@ CombustionOutput 148 The assess atmosphere is on fire. Returns 1 if device's Out
CombustionOutput2 149 The assess atmosphere is on fire. Returns 1 if device's Output2 network is on fire, 0 if not.
CompletionRatio 61 How complete the current production is for this device, between 0 and 1
ContactTypeId 198 The type id of the contact.
CurrentCode 261
CurrentResearchPodType 93
Density 262
CurrentCode 261
CurrentResearchPodType 93
Density 262
DestinationCode 215 Unique identifier code for a destination on the space map.
Discover 255
DistanceAu 244
DistanceKm 249
DrillCondition 240
Discover 255
DistanceAu 244
DistanceKm 249
DrillCondition 240
DryMass 220 The Mass in kilograms of the rocket excluding fuel. The more massive the rocket the more fuel will be required to move to a new location in space.
Eccentricity 247
Eccentricity 247
ElevatorLevel 40 Level the elevator is currently at
ElevatorSpeed 39 Current speed of the elevator
EntityState 239
EntityState 239
EnvironmentEfficiency 104 The Environment Efficiency reported by the machine, as a float between 0 and 1
Error 4 1 if device is in error state, otherwise 0
ExhaustVelocity 235
ExhaustVelocity 235
ExportCount 63 How many items exported since last ClearMemory
ExportQuantity 31 Total quantity of items exported by the device
ExportSlotHash 42 DEPRECATED
ExportSlotOccupant 32 DEPRECATED
Filtration 74 The current state of the filtration system, for example Filtration = 1 for a Hardsuit sets filtration to On
FlightControlRule 236
FlightControlRule 236
Flush 174 Set to 1 to activate the flush function on the device
ForceWrite 85 Forces Logic Writer devices to rewrite value
ForwardX 227
ForwardY 228
ForwardZ 229
Fuel 99
ForwardX 227
ForwardY 228
ForwardZ 229
Fuel 99
Harvest 69 Performs the harvesting action for any plant based machinery
Horizontal 20 Horizontal setting of the device
HorizontalRatio 34 Radio of horizontal setting for device
@@ -67,30 +68,29 @@ ImportCount 64 How many items imported since last ClearMemory
ImportQuantity 29 Total quantity of items imported by the device
ImportSlotHash 43 DEPRECATED
ImportSlotOccupant 30 DEPRECATED
Inclination 246
Index 241
Inclination 246
Index 241
InterrogationProgress 157 Progress of this sattellite dish's interrogation of its current target, as a ratio from 0-1
LineNumber 173 The line number of current execution for an integrated circuit running on this device. While this number can be written, use with caution
Lock 10 1 if device is locked, otherwise 0, can be set in most devices and prevents the user from access the values
ManualResearchRequiredPod 94
ManualResearchRequiredPod 94
Mass 219 The total Mass of the rocket in kilograms including fuel and cargo. The more massive the rocket the more fuel will be required to move to a new location in space.
Maximum 23 Maximum setting of the device
MinWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact
MineablesInQueue 96
MineablesInVicinity 95
MinedQuantity 266
MineablesInQueue 96
MineablesInVicinity 95
MinedQuantity 266
MinimumWattsToContact 163 Minimum required amount of watts from the dish hitting the target trader contact to start interrogating the contact
Mode 3 Integer for mode state, different devices will have different mode states available to them
NavPoints 258
NextWeatherEventTime 97
NavPoints 258
NextWeatherEventTime 97
None 0 No description
On 28 The current state of the device, 0 for off, 1 for on
Open 2 1 if device is open, otherwise 0
OperationalTemperatureEfficiency 150 How the input pipe's temperature effects the machines efficiency
OrbitPeriod 245
Orientation 230
OrbitPeriod 245
Orientation 230
Output 70 The output operation for a sort handling device, such as a stacker or sorter, when in logic mode the device will only action one repetition when set zero or above and then back to -1 and await further instructions
PassedMoles 234
PassedMoles 234
Plant 68 Performs the planting action for any plant based machinery
PlantEfficiency1 52 DEPRECATED
PlantEfficiency2 53 DEPRECATED
@@ -202,33 +202,31 @@ RatioWaterInput 113 The ratio of water in device's input network
RatioWaterInput2 123 The ratio of water in device's Input2 network
RatioWaterOutput 133 The ratio of water in device's Output network
RatioWaterOutput2 143 The ratio of water in device's Output2 network
ReEntryAltitude 237
ReEntryAltitude 237
Reagents 13 Total number of reagents recorded by the device
RecipeHash 41 Current hash of the recipe the device is set to produce
ReferenceId 217
ReferenceId 217
RequestHash 60 When set to the unique identifier, requests an item of the provided type from the device
RequiredPower 33 Idle operating power quantity, does not necessarily include extra demand power
ReturnFuelCost 100
Richness 263
ReturnFuelCost 100
Richness 263
Rpm 155 The number of revolutions per minute that the device's spinning mechanism is doing
SemiMajorAxis 248
SemiMajorAxis 248
Setting 12 A variable setting that can be read or written, depending on the device
SettingInput 91
SettingInputHash 91 The input setting for the device
SettingOutput 92
SettingOutputHash 91 The output setting for the device
SettingInput 91 The input setting for the device
SettingOutput 92 The output setting for the device
SignalID 87 Returns the contact ID of the strongest signal from this Satellite
SignalStrength 86 Returns the degree offset of the strongest contact
Sites 260
Size 264
Sites 260
Size 264
SizeX 160 Size on the X (right) axis of the object in largeGrids (a largeGrid is 2meters)
SizeY 161 Size on the Y(Up) axis of the object in largeGrids (a largeGrid is 2meters)
SizeZ 162 Size on the Z(Forward) axis of the object in largeGrids (a largeGrid is 2meters)
SolarAngle 22 Solar angle of the device
SolarIrradiance 176
SolarIrradiance 176
SoundAlert 175 Plays a sound alert on the devices speaker
Stress 156 Machines get stressed when working hard. When Stress reaches 100 the machine will automatically shut down
Survey 257
Survey 257
TargetPadIndex 158 The index of the trader landing pad on this devices data network that it will try to call a trader in to land
TargetX 88 The target position in X dimension in world coordinates
TargetY 89 The target position in Y dimension in world coordinates
@@ -251,15 +249,15 @@ TotalMolesInput 115 Returns the total moles of the device's Input Network
TotalMolesInput2 125 Returns the total moles of the device's Input2 Network
TotalMolesOutput 135 Returns the total moles of the device's Output Network
TotalMolesOutput2 145 Returns the total moles of the device's Output2 Network
TotalQuantity 265
TrueAnomaly 251
TotalQuantity 265
TrueAnomaly 251
VelocityMagnitude 79 The current magnitude of the velocity vector
VelocityRelativeX 80 The current velocity X relative to the forward vector of this
VelocityRelativeY 81 The current velocity Y relative to the forward vector of this
VelocityRelativeZ 82 The current velocity Z relative to the forward vector of this
VelocityX 231
VelocityY 232
VelocityZ 233
VelocityX 231
VelocityY 232
VelocityZ 233
Vertical 21 Vertical setting of the device
VerticalRatio 35 Radio of vertical setting for device
Volume 67 Returns the device atmosphere volume

View File

@@ -157,7 +157,7 @@
-746362430 DynamicCrateCableSupplies Crate (Cabling Supplies)
166707648 DynamicCrateConveyorSupplies Crate (Conveyor Supplies)
-282237045 DynamicCratePipeSupplies Crate (Pipe Supplies)
-2085885850 DynamicGPR Ground Penetrating Radar (GPR)
-2085885850 DynamicGPR <N:EN:DynamicGPR>
-1713611165 DynamicGasCanisterAir Portable Gas Tank (Air)
-322413931 DynamicGasCanisterCarbonDioxide Portable Gas Tank (CO2)
-1741267161 DynamicGasCanisterEmpty Portable Gas Tank
@@ -225,6 +225,7 @@
-626453759 Invar Invar
-666742878 Iron Iron
-842048328 ItemActiveVent Kit (Active Vent)
1871048978 ItemAdhesiveInsulation Adhesive Insulation
1722785341 ItemAdvancedTablet Advanced Tablet
176446172 ItemAlienMushroom Alien Mushroom
-9559091 ItemAmmoBox Ammo Box
@@ -500,6 +501,8 @@
288111533 ItemKitIceCrusher Kit (Ice Crusher)
2067655311 ItemKitInsulatedLiquidPipe Kit (Insulated Liquid Pipe)
452636699 ItemKitInsulatedPipe Kit (Insulated Pipe)
-27284803 ItemKitInsulatedPipeUtility Kit (Insulated Pipe Utility Gas)
-1831558953 ItemKitInsulatedPipeUtilityLiquid Kit (Insulated Pipe Utility Liquid)
-1708400347 ItemKitInsulatedWaterPipe Insulated Water Pipe Kit
1935945891 ItemKitInteriorDoors Kit (Interior Doors)
489494578 ItemKitLadder Kit (Ladder)
@@ -793,6 +796,13 @@
-2038663432 ItemStelliteGlassSheets Stellite Glass Sheets
-1897868623 ItemStelliteIngot Ingot (Stellite)
-1335056202 ItemSugarCane Sugar Cane
1447327071 ItemSuitAdvancedAC Advanced AC Suit
711019524 ItemSuitEmergency Emergency Suit
70631292 ItemSuitHard Hard Suit
-2020709888 ItemSuitInsulated Insulated Suit
-1274308304 ItemSuitModCryogenicUpgrade Cryogenic Suit Upgrade
-942170293 ItemSuitNormal Normal Suit
416903029 ItemSuitSpace Space Suit
318109626 ItemSuitStorage Kit (Suit Storage)
-229808600 ItemTablet Handheld Tablet
-1782380726 ItemTankConnector Kit (Tank Connector)
@@ -1342,6 +1352,10 @@
35149429 StructureInLineTankGas1x2 In-Line Tank Gas
543645499 StructureInLineTankLiquid1x1 In-Line Tank Small Liquid
-1183969663 StructureInLineTankLiquid1x2 In-Line Tank Liquid
1818267386 StructureInsulatedInLineTankGas1x1 Insulated In-Line Tank Small Gas
-177610944 StructureInsulatedInLineTankGas1x2 Insulated In-Line Tank Gas
-813426145 StructureInsulatedInLineTankLiquid1x1 Insulated In-Line Tank Small Liquid
1452100517 StructureInsulatedInLineTankLiquid1x2 Insulated In-Line Tank Liquid
-1967711059 StructureInsulatedPipeCorner Insulated Pipe (Corner)
-92778058 StructureInsulatedPipeCrossJunction Insulated Pipe (Cross Junction)
1328210035 StructureInsulatedPipeCrossJunction3 Insulated Pipe (3-Way Junction)
@@ -1422,6 +1436,7 @@
546002924 StructureLogicRocketUplink Logic Uplink
1822736084 StructureLogicSelect Logic Select
-767867194 StructureLogicSlotReader Slot Reader
873418029 StructureLogicSorter Logic Sorter
1220484876 StructureLogicSwitch Lever
321604921 StructureLogicSwitch2 Switch
-693235651 StructureLogicTransmitter Logic Transmitter
@@ -1638,7 +1653,6 @@
1570931620 StructureTraderWaypoint Trader Waypoint
-1423212473 StructureTransformer Transformer (Large)
-1065725831 StructureTransformerMedium Transformer (Medium)
-771036757 StructureTransformerMedium(Reversed) Transformer Reversed (Medium)
833912764 StructureTransformerMediumReversed Transformer Reversed (Medium)
-890946730 StructureTransformerSmall Transformer (Small)
1054059374 StructureTransformerSmallReversed Transformer Reversed (Small)

View File

@@ -210,7 +210,7 @@ def extract_data(install_path: Path, data_path: Path, language: str):
continue
key = key.text
value = value.text
if key is None:
if key is None or any(bad in key for bad in "(){}|[]") :
continue
crc_u = binascii.crc32(key.encode('utf-8'))
crc_i: int = struct.unpack("i", struct.pack("I", crc_u))[0]

View File

@@ -11,12 +11,9 @@ pub mod generated {
use crate::interpreter::ICError;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use strum::AsRefStr;
use strum::Display;
use strum::EnumIter;
use strum::EnumProperty;
use strum::EnumString;
use strum::IntoEnumIterator;
use strum::{
AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr, IntoEnumIterator,
};
include!(concat!(env!("OUT_DIR"), "/instructions.rs"));
include!(concat!(env!("OUT_DIR"), "/logictypes.rs"));
@@ -1081,7 +1078,9 @@ impl Number {
}
pub fn value_i64(&self, signed: bool) -> i64 {
match self {
Number::Enum(val) | Number::Float(val) | Number::Constant(val) => interpreter::f64_to_i64(*val, signed),
Number::Enum(val) | Number::Float(val) | Number::Constant(val) => {
interpreter::f64_to_i64(*val, signed)
}
Number::Binary(val) | Number::Hexadecimal(val) => *val,
Number::String(s) => const_crc32::crc32(s.as_bytes()) as i32 as i64,
}

View File

@@ -1,5 +1,5 @@
macro_rules! object_trait {
(intf {$trait_name:ident $trt:path}) => {
(@intf {$trait_name:ident $trt:path}) => {
paste::paste! {
#[allow(missing_docs)]
pub type [<$trt Ref>]<'a, T> = &'a dyn $trt<ID = <T as $trait_name>::ID>;
@@ -7,30 +7,37 @@ macro_rules! object_trait {
pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt<ID = <T as $trait_name>::ID>;
}
};
( $trait_name:ident {$($trt:path),*}) => {
(@body $trait_name:ident $($trt:path),*) => {
type ID;
fn id(&self) -> &Self::ID;
fn type_name(&self) -> &str;
fn as_object(&self) -> &dyn $trait_name<ID = Self::ID>;
fn as_object_mut(&mut self) -> &mut dyn $trait_name<ID = Self::ID>;
paste::paste!{$(
#[inline(always)]
fn [<as_ $trt:snake>](&self) -> Option<[<$trt Ref>]<Self>> {
None
}
#[inline(always)]
fn [<as_ $trt:snake _mut>](&mut self) -> Option<[<$trt RefMut>]<Self>> {
None
}
)*}
};
( $trait_name:ident $(: $($bound:tt)* )? {$($trt:path),*}) => {
$(
$crate::vm::object::macros::object_trait!{intf {$trait_name $trt}}
$crate::vm::object::macros::object_trait!{@intf {$trait_name $trt}}
)*
pub trait $trait_name {
type ID;
fn id(&self) -> &Self::ID;
pub trait $trait_name $(: $($bound)* )? {
fn as_object(&self) -> &dyn $trait_name<ID = Self::ID>;
fn as_object_mut(&mut self) -> &mut dyn $trait_name<ID = Self::ID>;
paste::paste!{$(
#[inline(always)]
fn [<as_ $trt:snake>](&self) -> Option<[<$trt Ref>]<Self>> {
None
}
#[inline(always)]
fn [<as_ $trt:snake _mut>](&mut self) -> Option<[<$trt RefMut>]<Self>> {
None
}
)*}
$crate::vm::object::macros::object_trait!{@body $trait_name $($trt),*}
}
};
}
@@ -64,6 +71,10 @@ macro_rules! ObjectInterface {
&self.$field_id
}
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
#[inline(always)]
fn as_object(&self) -> &dyn $trait_name<ID = Self::ID> {
self
@@ -114,25 +125,25 @@ pub(crate) use ObjectTrait;
macro_rules! tag_object_traits {
{
@tag
tag=$trt_name:ident;
tag=$trt_name:ident $(: $($obj_bound:tt)* )?;
acc={ $($tagged_trt:ident,)* }
$(#[$attr:meta])*
$viz:vis trait $trt:ident $(: $($bound:path)* )? {
$viz:vis trait $trt:ident $(: $($trt_bound:path)* )? {
$($tbody:tt)*
}
$($used:tt)*
} => {
#[doc = concat!("Autotagged with ", stringify!($trt_name))]
$(#[$attr])*
$viz trait $trt : $($($bound)* +)? $trt_name {
$viz trait $trt : $($($trt_bound)* +)? $trt_name {
$($tbody)*
}
$crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $trt, $($tagged_trt,)* } $($used)* }
$crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name $(: $($obj_bound)* )?; acc={ $trt, $($tagged_trt,)* } $($used)* }
};
{
@tag
tag=$trt_name:ident;
tag=$trt_name:ident $(: $($obj_bound:tt)* )?;
acc={ $($tagged_trt:ident,)* }
impl $name:ident for $trt:path {
$($body:tt)*
@@ -143,19 +154,19 @@ macro_rules! tag_object_traits {
impl $name for $trt {
$($body)*
}
$crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $($tagged_trt,)* } $($used)* }
$crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name $(: $($obj_bound)* )?; acc={ $($tagged_trt,)* } $($used)* }
};
{
@tag
tag=$trt_name:ident;
tag=$trt_name:ident $(: $($obj_bound:tt)* )?;
acc={ $($tagged_trt:ident,)* }
} => {
// end tagged traits {$trt_name}
$crate::vm::object::macros::object_trait!($trt_name { $($tagged_trt),* });
$crate::vm::object::macros::object_trait!($trt_name $(: $($obj_bound)* )? { $($tagged_trt),* });
};
{ #![object_trait($trt_name:ident)] $($tree:tt)* } => {
{ #![object_trait($trt_name:ident $(: $($bound:tt)* )? )] $($tree:tt)* } => {
$crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={} $($tree)* }
};
}

View File

@@ -2,6 +2,7 @@ use macro_rules_attribute::derive;
mod macros;
mod traits;
mod stationpedia;
use macros::ObjectInterface;
use traits::*;

View File

@@ -0,0 +1,26 @@
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
use crate::vm::object::BoxedObject;
include!(concat!(env!("OUT_DIR"), "/stationpedia_prefabs.rs"));
pub enum PrefabTemplate {
Hash(i32),
Name(String),
}
pub fn object_from_prefab_template(template: &PrefabTemplate) -> Option<BoxedObject> {
let prefab = match template {
PrefabTemplate::Hash(hash) => StationpediaPrefab::from_repr(*hash),
PrefabTemplate::Name(name) => StationpediaPrefab::from_str(name).ok(),
};
match prefab {
// Some(StationpediaPrefab::ItemIntegratedCircuit10) => Some()
// Some(StationpediaPrefab::StructureCircuitHousing) => Some()
// Some(StationpediaPrefab::StructureRocketCircuitHousing) => Some()
_ => None,
}
}

View File

@@ -1,7 +1,9 @@
use std::fmt::Debug;
use crate::{grammar, vm::{object::{macros::tag_object_traits, ObjectID}, VM}};
tag_object_traits! {
#![object_trait(Object)]
#![object_trait(Object: Debug)]
pub trait Memory {
fn size(&self) -> usize;
@@ -53,3 +55,8 @@ tag_object_traits! {
}
impl<T: Debug> Debug for dyn Object<ID = T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Object: (ID = {:?}, Type = {})", self.id(), self.type_name())
}
}