ShapeMachine
- class ShapeMachine(communication_layer: CommunicationLayer, initial_design: Shape | None = None)
ShapeMachine
is the core engine of Shape Machine that enables querying and updating of shapes byRule
objects.The engine requires a
CommunicationLayer
to allow for communication between the engine and another program. By default, communication layers initialize their own instance of the engine. This means you don’t have to initialize the engine directly, you should instead initialize aCommunicationLayer
and use itsengine
attribute when you need to work with an instance ofShapeMachine
.Internally, the
initial_design
is used to shift the entire design (and modified designs) towards the origin. This reduces floating-point error in query computations. This shift is not reflected in the output of engine functions (i.e.: all outputs are shifted back to where the initial design was).Attributes
The initial design tracked by the engine.
The current design tracked by the engine.
Optional callable that gets called right before the execution of a new rule during
apply_rule_sequence()
.Optional callable that gets called right before the execution of a new rule during
apply_program()
.Methods
Apply a
Program
to thecurrent_design
by the following process:Apply a
Rule
to thecurrent_design
by the following process:Apply a
RuleSequence
to thecurrent_design
by the following process:- apply_program(program: Program) List[Tuple[Rule, List[Tuple[Shape, Shape]], Shape, Shape, Shape, Shape]]
Apply a
Program
to thecurrent_design
by the following process:If
initial_design
isNone
, set the initial shape from the engine’sCommunicationLayer
withimport_shape()
. This then becomes thecurrent_design
and is internally shifted to the origin.Add the rules within the entry-point
RuleSequence
to the rule queue.The entry-point sequence is indicated by the program’s
entry_point
. If this key cannot be found in the program, the engine will request the user to input the entry-point from the set of sequence keys in the program.
While the rule queue is not empty:
Grab the next
Rule
in the queue.If this rule is a
JumpRule
:Query the current design with the rule (see
JumpRule
for more information).If the query is successful, “jump” to the sequence indicated by the rule’s
jump_target
. This involves inserting all of the rules in the sequence designated by the jump target to the beginning of the rule queue.
Otherwise:
Apply it with
apply_rule()
within_script=True
.Add a
(rule_applied, updated_design)
tuple to the design history.
Return the design history.
This process keeps track of a design history that contains tuples of rules applied and the updated design created after the application of the applied rule. The first entry in the history is
(None, initial_design)
.- Parameters:
program – The program to apply to the
current_design
.- Returns:
The design history (see above).
- apply_rule(rule: Rule, in_script: bool = False) Tuple[Rule, List[Tuple[Shape, Shape]], Shape, Shape, Shape, Shape]
Apply a
Rule
to thecurrent_design
by the following process:If
initial_design
isNone
, set the initial shape from the engine’sCommunicationLayer
withimport_shape()
. This then becomes thecurrent_design
and is internally shifted to the origin.Apply the rule to the
current_design
.Replace the current design with the updated design (shifted back to the initial position) using the communication layer’s
replace_current_design()
.Return the shifted-back updated design.
- Parameters:
rule – The rule to apply to the
current_design
.in_script – Passed to the rule’s
apply_to()
method. See its documentation for more details.
- Returns:
The updated design.
- apply_rule_sequence(sequence: RuleSequence) List[Tuple[Rule, List[Tuple[Shape, Shape]], Shape, Shape, Shape, Shape]]
Apply a
RuleSequence
to thecurrent_design
by the following process:If
initial_design
isNone
, set the initial shape from the engine’sCommunicationLayer
withimport_shape()
. This then becomes thecurrent_design
and is internally shifted to the origin.For each
Rule
in the sequence:Apply it with
apply_rule()
within_script=True
.Add a
(rule_applied, updated_design)
tuple to the design history.
Return the design history.
This process keeps track of a design history that contains tuples of rules applied and the updated design created after the application of the applied rule. The first entry in the history is
(None, initial_design)
.- Parameters:
sequence – The rule sequence to apply to the
current_design
.- Returns:
The design history (see above).
- current_design
The current design tracked by the engine. This is modified by engine functions.
- initial_design
The initial design tracked by the engine. Internally, both this and
current_design
are shifted to the origin to reduce floating-point error in queries. This shift is not reflected in the output of engine functions (i.e.: all outputs are shifted back to where the initial design was).
- on_next_rule_in_program: Callable[[str, int], None] | None
Optional callable that gets called right before the execution of a new rule during
apply_program()
. The parameters passed in are the label of theRuleSequence
the rule is in and the line number of the rule in the sequence (starting at 1), respectively. The callable gets called each rule loop.
- on_next_rule_in_sequence: Callable[[int], None] | None
Optional callable that gets called right before the execution of a new rule during
apply_rule_sequence()
. The parameter passed in is the line number of the rule in the sequence (starting at 1). The callable does not get called each rule loop, just when changing rules.