Skip to content

Commit e575e8f

Browse files
authored
Merge pull request #3142 from RetiredWizard/fruitlogic
Logic_Gates: Fix recursion and NotImplementedErrors
2 parents e2fd3c2 + c9376d0 commit e575e8f

File tree

2 files changed

+59
-33
lines changed

2 files changed

+59
-33
lines changed

Fruit_Jam/Fruit_Jam_Logic_Gates/code.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
old_button_values = [True, True, True]
6666
button_values_changed = False
6767

68+
waiting_for_release = False
69+
6870
while True:
6971
# update mouse, and get any mouse buttons that are pressed
7072
pressed_btns = mouse.update()
@@ -73,10 +75,16 @@
7375
now = time.monotonic()
7476
if last_click_time is None or now > last_click_time + CLICK_COOLDOWN:
7577
# if any buttons are pressed
76-
if pressed_btns is not None and len(pressed_btns) > 0:
78+
if not waiting_for_release and pressed_btns is not None and len(pressed_btns) > 0:
79+
waiting_for_release = True
80+
click_x = mouse.x
81+
click_y = mouse.y
82+
click_btns = pressed_btns
83+
elif waiting_for_release and not mouse.pressed_btns:
84+
waiting_for_release = False
7785
last_click_time = now
7886
# let workspace handle the click event
79-
workspace.handle_mouse_click(mouse.x, mouse.y, pressed_btns)
87+
workspace.handle_mouse_click(click_x, click_y, click_btns)
8088

8189
# if there is an entity on the mouse being moved
8290
if not workspace.mouse_moving_tg.hidden:

Fruit_Jam/Fruit_Jam_Logic_Gates/entity.py

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
516533
class 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

Comments
 (0)