@@ -121,6 +121,11 @@ def input_one(self, value):
121121 self ._input_one = value
122122 self .apply_state_palette_mapping ()
123123
124+ @property
125+ def value (self ):
126+ # Output panel does not have a logic output value
127+ return False
128+
124129 def update (self ):
125130 """
126131 Run logic simulation for this entity
@@ -243,6 +248,7 @@ class Wire(Entity):
243248 TILE_INDEXES = [19 , 9 , 1 , 0 , 17 ]
244249
245250 def __init__ (self , location , workspace , state = None , add_to_workspace = True ):
251+ self ._recursion_guard = False
246252 self .type = "wire"
247253 self .size = (1 , 1 )
248254 self ._workspace = workspace
@@ -423,6 +429,12 @@ def get_value(self, ignore_input_entity):
423429
424430 @property
425431 def value (self ):
432+ if self ._recursion_guard :
433+ self ._recursion_guard = False
434+ return self .input_one or self .input_two or self .input_three or self .input_three
435+
436+ self ._recursion_guard = True
437+
426438 if "left" in self .STATES [self .state ]:
427439 if (
428440 self .input_one_entity is None
@@ -435,6 +447,7 @@ def value(self):
435447 else :
436448 self .input_one = self .input_one_entity .value
437449 if self .input_one :
450+ self ._recursion_guard = False
438451 return True
439452 if "right" in self .STATES [self .state ]:
440453 if (
@@ -449,6 +462,7 @@ def value(self):
449462 # right side only allows input from Wires
450463 self .input_two = False
451464 if self .input_two :
465+ self ._recursion_guard = False
452466 return True
453467 if "up" in self .STATES [self .state ]:
454468 if (
@@ -463,6 +477,7 @@ def value(self):
463477 # top side only accepts input from wires
464478 self .input_three = False
465479 if self .input_three :
480+ self ._recursion_guard = False
466481 return True
467482 if "down" in self .STATES [self .state ]:
468483 if (
@@ -477,7 +492,10 @@ def value(self):
477492 # bottom side only accepts input from wires?
478493 self .input_four = False
479494 if self .input_four :
495+ self ._recursion_guard = False
480496 return True
497+
498+ self ._recursion_guard = False
481499 return self .input_one or self .input_two or self .input_three or self .input_three
482500
483501 @property
@@ -512,7 +530,6 @@ def input_four_entity(self):
512530 else :
513531 return None
514532
515-
516533class TwoInputOneOutputGate (Entity ):
517534 """
518535 Super class for all Gate objects that have two inputs and one output.
@@ -535,6 +552,13 @@ class TwoInputOneOutputGate(Entity):
535552
536553 _inputs_left = True
537554 """Whether the inputs are to the left (True), or top/bottom (False)"""
555+ def __init__ (self ):
556+ self ._recursion_guard = False
557+ self .type = "gate"
558+
559+ self ._input_one = False
560+ self ._input_two = False
561+ self ._output = False
538562
539563 @property
540564 def output (self ) -> bool :
@@ -573,6 +597,11 @@ def input_two(self, value):
573597 def value (self ):
574598 """Calculate the output logic value of this gate. Will call
575599 value property on input entities."""
600+ if self ._recursion_guard :
601+ self ._recursion_guard = False
602+ return self .output
603+
604+ self ._recursion_guard = True
576605 input_one_entity = self .input_one_entity
577606 input_two_entity = self .input_two_entity
578607
@@ -594,6 +623,7 @@ def value(self):
594623 else :
595624 self .input_two = input_two_entity .value
596625
626+ self ._recursion_guard = False
597627 return self .output
598628
599629 def handle_click (self ):
@@ -664,7 +694,7 @@ class AndGate(TwoInputOneOutputGate):
664694 """AndGate - When both inputs are True the output will be True, otherwise False."""
665695
666696 def __init__ (self , location , workspace , add_to_workspace = True ):
667- self . type = "gate"
697+ super (). __init__ ()
668698
669699 self ._workspace = workspace
670700 self .location = location
@@ -673,10 +703,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
673703
674704 self .tiles = [0 , 10 , 11 , 20 ]
675705
676- self ._input_one = False
677- self ._input_two = False
678- self ._output = False
679-
680706 if add_to_workspace :
681707 self ._workspace .add_entity (self )
682708
@@ -697,7 +723,7 @@ class NandGate(TwoInputOneOutputGate):
697723 """NandGate - When at least one input is False the output will be True, otherwise False."""
698724
699725 def __init__ (self , location , workspace , add_to_workspace = True ):
700- self . type = "gate"
726+ super (). __init__ ()
701727
702728 self ._workspace = workspace
703729 self .location = location
@@ -706,10 +732,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
706732
707733 self .tiles = [0 , 14 , 15 , 20 ]
708734
709- self ._input_one = False
710- self ._input_two = False
711- self ._output = False
712-
713735 if add_to_workspace :
714736 self ._workspace .add_entity (self )
715737
@@ -730,7 +752,7 @@ class OrGate(TwoInputOneOutputGate):
730752 """OrGate - When either input is True the output will be True, otherwise False."""
731753
732754 def __init__ (self , location , workspace , add_to_workspace = True ):
733- self . type = "gate"
755+ super (). __init__ ()
734756
735757 self ._workspace = workspace
736758 self .location = location
@@ -739,10 +761,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
739761
740762 self .tiles = [0 , 12 , 13 , 20 ]
741763
742- self ._input_one = False
743- self ._input_two = False
744- self ._output = False
745-
746764 if add_to_workspace :
747765 self ._workspace .add_entity (self )
748766
@@ -763,7 +781,7 @@ class NorGate(TwoInputOneOutputGate):
763781 """NorGate - When both inputs are False the output will be True, otherwise False."""
764782
765783 def __init__ (self , location , workspace , add_to_workspace = True ):
766- self . type = "gate"
784+ super (). __init__ ()
767785
768786 self ._workspace = workspace
769787 self .location = location
@@ -772,10 +790,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
772790
773791 self .tiles = [0 , 6 , 7 , 20 ]
774792
775- self ._input_one = False
776- self ._input_two = False
777- self ._output = False
778-
779793 if add_to_workspace :
780794 self ._workspace .add_entity (self )
781795
@@ -796,7 +810,7 @@ class XorGate(TwoInputOneOutputGate):
796810 """XorGate - When one input is True and the other input is False the output will be True, otherwise False."""
797811
798812 def __init__ (self , location , workspace , add_to_workspace = True ):
799- self . type = "gate"
813+ super (). __init__ ()
800814
801815 self ._workspace = workspace
802816 self .location = location
@@ -805,10 +819,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
805819
806820 self .tiles = [0 , 4 , 5 , 20 ]
807821
808- self ._input_one = False
809- self ._input_two = False
810- self ._output = False
811-
812822 if add_to_workspace :
813823 self ._workspace .add_entity (self )
814824
@@ -837,7 +847,7 @@ class XnorGate(TwoInputOneOutputGate):
837847 """XNOR Gate - When both inputs are True, or both inputs are False the output will be True, otherwise False"""
838848
839849 def __init__ (self , location , workspace , add_to_workspace = True ):
840- self . type = "gate"
850+ super (). __init__ ()
841851
842852 self ._workspace = workspace
843853 self .location = location
@@ -846,10 +856,6 @@ def __init__(self, location, workspace, add_to_workspace=True):
846856
847857 self .tiles = [0 , 24 , 25 , 20 ]
848858
849- self ._input_one = False
850- self ._input_two = False
851- self ._output = False
852-
853859 if add_to_workspace :
854860 self ._workspace .add_entity (self )
855861
@@ -878,6 +884,8 @@ class NotGate(Entity):
878884 """NOT Gate - When the input is False the output will be True, otherwise False."""
879885
880886 def __init__ (self , location , workspace , add_to_workspace = True ):
887+ self ._recursion_guard = False
888+
881889 self .type = "gate"
882890
883891 self ._workspace = workspace
@@ -919,13 +927,19 @@ def input_one_entity(self):
919927
920928 @property
921929 def value (self ):
930+ if self ._recursion_guard :
931+ self ._recursion_guard = False
932+ return self .output
933+
934+ self ._recursion_guard = True
922935 input_one_entity = self .input_one_entity
923936
924937 if input_one_entity is not None :
925938 self .input_one = input_one_entity .value
926939 else :
927940 self .input_one = False
928941
942+ self ._recursion_guard = False
929943 return self .output
930944
931945 def _init_tile_locations (self ):
@@ -1057,6 +1071,10 @@ def palette_mapping(self):
10571071 pal [5 ] = 7 if self .input_three else 1
10581072 return pal
10591073
1074+ @property
1075+ def value (self ):
1076+ return False
1077+
10601078 def apply_state_palette_mapping (self ):
10611079 """
10621080 Apply the current palette mapping to all tiles used by this Gate.
0 commit comments