Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 59 additions & 14 deletions RESTService/pyminsky.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,73 @@ namespace pyminsky

minsky::Item& findObject(const std::string& typeName)
{
using namespace minsky;
auto& canvas = minsky.canvas;
using namespace minsky;
auto& canvas = minsky.canvas;

canvas.item.reset();
canvas.item.reset(); // Reset the item to ensure no leftover references

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation has gone a bit weird

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. I must have accidentally pressed the tab key on that line. I'll check the indentation more carefully prior to a pull request next time.


if (typeName == "Group" && !canvas.model->groups.empty())
canvas.item = canvas.model->groups.front();
else
minsky.model->recursiveDo(&GroupItems::items, [&](const Items&, Items::const_iterator i)
bool found = false;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This found flag is redundant. It just shadows the validity status of canvas.item

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I was getting a segfault in the renameVariables.sh test, so I used it for added safety.


if (typeName == "Group" && !canvas.model->groups.empty())
{
canvas.item = canvas.model->groups.front();
found = true;
}
else
{
if ((*i)->classType() == typeName)
found = minsky.model->recursiveDo(&GroupItems::items, [&](const Items&, Items::const_iterator i)
{
canvas.item = *i;
return true; // Stop recursion
}
return false;
});
if ((*i)->classType() == typeName)
{
canvas.item = *i;
return true; // Stop recursion
}
return false;
});
}

// Check if an object was found
if (!found || !canvas.item)
{
// std::cerr << "findObject: Object of type '" << typeName << "' not found or invalid!" << std::endl;
throw std::runtime_error("Object not found");
}

return *canvas.item;
return *canvas.item; // Return the dereferenced item
}

// Find a variable by its name
minsky::Item& findVariable(const std::string& name)
{
using namespace minsky;
auto& canvas = minsky.canvas;

canvas.item.reset(); // Reset item to ensure clean start

bool found = minsky.model->recursiveDo(
&GroupItems::items,
[&](const Items&, Items::const_iterator i) {
if (auto v = dynamic_cast<VariableBase*>(i->get()))
{
if (v->name() == name)
{
canvas.item = *i;
return true; // Stop recursion
}
}
return false;
});

if (!found || !canvas.item)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found flag redundant here too.

{
// std::cerr << "findVariable: Variable '" << name << "' not found or invalid!" << std::endl;
throw std::runtime_error("Variable not found");
}

return *canvas.item; // Return the dereferenced item
}
CLASSDESC_ADD_FUNCTION(findObject);
CLASSDESC_ADD_FUNCTION(findVariable);
}

CLASSDESC_PYTHON_MODULE(pyminsky);
Expand Down
54 changes: 16 additions & 38 deletions test/00/deleteKey.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ trap "fail" 1 2 3 15
cat >input.py <<EOF
import sys
sys.path.insert(0, '$here')
from pyminsky import minsky
from pyminsky import minsky, findVariable

# Load the model and centre the canvas
minsky.load('$here/examples/GoodwinLinear02.mky')
Expand All @@ -41,68 +41,46 @@ numItems = minsky.model.numItems()
numWires = minsky.model.numWires()
print(f"Initial number of items: {numItems}, Initial number of wires: {numWires}")

# Function to find a variable by name
def findVariable(name):
last_error = None
for i in range(len(minsky.model.items)):
try:
if minsky.model.items[i].name() == name:
x = minsky.model.items[i].x()
y = minsky.model.items[i].y()
print(f"Found variable '{name}' at coordinates ({x}, {y})")
# Get the item at coordinates
if minsky.canvas.getItemAt(x, y):
return (x, y)
else:
print(f"Failed to focus item at ({x}, {y}). Trying manual fallback.")
return (x, y) # Return coordinates anyway for manual handling
except Exception as e:
last_error = e # Capture the error in the except block

# Handle the error if it occurred
if last_error:
print(f"Error while finding variable '{name}' at last known coordinates: {last_error}")
return None

# Function to delete an item or wire at a given position
def deleteKey(x, y):
# Check for a wire or item at the coordinates and delete it
if minsky.canvas.getWireAt(x, y):
minsky.canvas.deleteWire()
print(f"Wire deleted at ({x}, {y})")
elif minsky.canvas.getItemAt(x, y):
item = minsky.canvas.item # Try to focus on the item
item = minsky.canvas.item
if item is not None:
print(f"Deleting item at ({x}, {y}), ID: {item.id()}, Type: {item.classType()}")
minsky.canvas.deleteItem()
else:
print(f"Item found but not focused at ({x}, {y}), manually deleting.")
minsky.canvas.deleteItem() # Manually delete if focus fails
minsky.canvas.deleteItem()
else:
print(f"No item found at ({x}, {y}).")

# Step 1: Delete the wire at coordinates (415, 290)
# Step 1: Delete the wire at coordinates (450, 50)
deleteKey(450, 50)
assert minsky.model.numWires() == (numWires - 1), "Test wire deletion failed."

# Step 2: Delete the variable 'emprate'
emprate_coords = findVariable("emprate")
if emprate_coords:
deleteKey(emprate_coords[0], emprate_coords[1]) # Delete the variable directly using coordinates
try:
variable_emprate = findVariable("emprate")
assert variable_emprate is not None, "Variable 'emprate' not found in the model."
deleteKey(variable_emprate.x(), variable_emprate.y())
assert minsky.model.numItems() == (numItems - 1), "Test 'emprate' variable deletion failed."
# Two wires should also be deleted after deleting the variable
assert minsky.model.numWires() == (numWires - 3), "Test attached wires deletion failed."
else:
raise ValueError("Variable 'emprate' not found in the model.")
except Exception as e:
raise AssertionError(f"Error deleting variable 'emprate': {e}")

# Step 3: Delete the variable 'Investment'
investment_coords = findVariable("Investment")
if investment_coords:
try:
variable_investment = findVariable("Investment")
assert variable_investment is not None, "Variable 'Investment' not found in the model."
minsky.canvas.selectAllVariables()
deleteKey(investment_coords[0], investment_coords[1]) # Delete the variable using coordinates
deleteKey(variable_investment.x(), variable_investment.y())
assert minsky.model.numItems() == (numItems - 2), "Test selection deletion failed."
else:
raise ValueError("Variable 'Investment' not found in the model.")
except Exception as e:
raise ValueError(f"Error deleting variable 'Investment': {e}")
EOF

python3 input.py
Expand Down
59 changes: 35 additions & 24 deletions test/00/renameVariables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,43 @@ pass()
trap "fail" 1 2 3 15
cat >input.py <<EOF
import sys
sys.path.insert(0,'$here')
from pyminsky import minsky
sys.path.insert(0, '$here')
from pyminsky import minsky, findVariable

# Load the model
minsky.load('$here/examples/GoodwinLinear02.mky')

def findVariable(name):
for i in range(len(minsky.model.items)):
try:
if minsky.model.items[i].name()==name:
minsky.canvas.getItemAt(minsky.model.items[i].x(),minsky.model.items[i].y())
return True
except:
pass

assert findVariable('L')
minsky.canvas.renameAllInstances('R')
assert not findVariable('L')
assert findVariable('R')
minsky.canvas.selectAllVariables()
assert len(minsky.canvas.selection.items)==2

# check findDefinition
assert findVariable('R')
minsky.canvas.findVariableDefinition()
assert minsky.canvas.itemIndicator.name()=="R"
# check that the selected variable has its input wired
assert minsky.canvas.itemIndicator.inputWired()
try:
# Ensure the variable 'L' exists and get a reference to it
variable_L = findVariable("L")
assert variable_L is not None, "Variable 'L' not found in the model."
print(f"Found variable 'L': {variable_L.name()} at ({variable_L.x()}, {variable_L.y()})")

# Rename all instances of 'L' to 'R'
minsky.canvas.renameAllInstances('R')

# Ensure 'L' no longer exists
variable_L = findVariable("L")
assert variable_L is None, "Variable 'L' still exists after renaming."

# Ensure 'R' now exists
variable_R = findVariable("R")
assert variable_R is not None, "Variable 'R' not found after renaming."
print(f"Renamed variable: {variable_R.name()} at ({variable_R.x()}, {variable_R.y()})")

# Select all variables and verify selection
minsky.canvas.selectAllVariables()
assert len(minsky.canvas.selection.items) == 2, "Selection count does not match."

# Check findDefinition and wiring
variable_R = findVariable("R")
assert variable_R is not None, "Variable 'R' not found for findDefinition."
minsky.canvas.findVariableDefinition()
assert minsky.canvas.itemIndicator.name() == "R", "Selected variable for findDefinition is incorrect."
assert minsky.canvas.itemIndicator.inputWired(), "Selected variable input is not wired."

except Exception as e:
print(f"Test failed with exception: {e}")
EOF

python3 input.py
Expand Down
Loading