Added simulation files.

This commit is contained in:
cheezedoodle2
2023-04-03 23:19:16 -07:00
parent b7d548800e
commit 0f10f22345
5 changed files with 109 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
{
"configurations": [
{
"name": "Python: HotdogSimulation",
"type": "python",
"request": "launch",
"program": "simulation/SimulationRunner.py",
"justMyCode": true,
"args": "./HotdogSimulation.py"
}
]
}
+18
View File
@@ -0,0 +1,18 @@
from Simulation import Simulation
class HotdogSimulation(Simulation):
def __init__(self) -> None:
self.ticks_left = 5
def start(self):
print(f"DEBUG: simulation started.")
def use(self):
print(f"DEBUG: someone ate the hot dog! 🌭")
def tick(self):
self.ticks_left -= 1
if self.ticks_left == 0:
print(f"DEBUG: simulation out of ticks, expiring.")
return False
return True
def stop(self):
print(f"DEBUG: simulation stopped.")
pass
+8
View File
@@ -0,0 +1,8 @@
This is a simple example of a pluggable object simulator. If you run the
SimulatorRunner file, it'll throw up a GUI file picker if a simulation class
isn't specified on the command line. It will then:
* Run the simulation class's `start()` method,
* Call its `tick()` method,
* Call its `use()` method,
* then call its `stop()` method once `tick()` returns false.
+31
View File
@@ -0,0 +1,31 @@
from abc import ABC, abstractmethod
class Simulation(ABC):
@abstractmethod
def start(self):
"Start the simulated object."
pass
@abstractmethod
def tick(self) -> bool:
"""
Simulate one clock tick.
Returns:
bool: True if the simulation could advance one clock tick, or False if the object is expired.
"""
pass
@abstractmethod
def use(self, *args, **kwargs):
"""
Use the simulated object.
Args:
args (tuple): A tuple of arguments.
kwargs (dict): A dictionary of key-value pairs of arguments.
"""
pass
@abstractmethod
def stop(self):
"Stop the simulated object."
pass
+40
View File
@@ -0,0 +1,40 @@
from importlib import import_module
import tkinter as tk
import os
import sys
from time import sleep
from tkinter import filedialog
from abc import ABC, abstractmethod
class SimulationRunner:
def __init__(self, simulation) -> None:
self.simulation = simulation()
self.simulation.start()
while self.simulation.tick():
self.simulation.use()
self.simulation.stop()
if __name__ == '__main__':
if len(sys.argv) == 1:
# Create a hidden root window
root = tk.Tk()
root.withdraw()
# Open the file chooser dialog
file_path = filedialog.askopenfilename()
print(f"Selected file: {file_path}")
else:
file_path = sys.argv[1]
# Get the python file's directory and filename
module_dir, module_file = os.path.split(file_path)
# Get the python file's name without any extension
module_name, _ = os.path.splitext(module_file)
# Add the module directory to sys.path so we can import it unqualified
sys.path.append(module_dir)
simulation = import_module(module_name)
# Load the simulation module's simulation class, which should be the same
# name as the module name.
simulationrunner = SimulationRunner(getattr(simulation, module_name))