PolygonMorph variableSubclass: #LogicGate instanceVariableNames: 'state inputsCollection outputsCollection inputsReporting verts' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !LogicGate commentStamp: '' prior: 0! Super class (Abstract) for all logic gates. Contains input and output management code and stubs for getState! !LogicGate methodsFor: 'accessing'! addInput: input "Add an input , then add ourselves as an output to the input object" inputsCollection add: input. input addOutput: self! ]style[(10 5 3 68 2 16 6 5 3 5 12 4)f2b,f2cblue;b,f2,f2c146044000,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;! ! !LogicGate methodsFor: 'accessing'! addOutput: output "Add an output" outputsCollection add:output.! ]style[(11 6 3 15 31)f2b,f2cblue;b,f2,f2c146044000,f2! ! !LogicGate methodsFor: 'accessing'! clock: whichInput "Our inputs call our clock to strobe when their output values are set, we don't strobe our outputs until all inputs report and our state is correct" (inputsCollection includes: whichInput) ifTrue: [inputsReporting := inputsReporting + 1. inputsReporting >= inputsCollection size ifTrue: ["All inputs have reported, send the clock tick to our outputs" outputsCollection do: [:output | output clock: self]. "Reset our inputs reporting for the next clock" inputsReporting := 0]]. self getState! ]style[(7 10 3 154 3 16 11 10 13 15 4 15 3 1 5 15 4 16 19 69 6 17 12 8 2 6 8 4 8 47 6 15 4 1 5 4 9)f2b,f2cblue;b,f2,f2c149047000,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2c199199123,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2c149047000,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c149047000,f2,f2cmagenta;,f2,f2c199199123,f2,f2cmagenta;,f2! ! !LogicGate methodsFor: 'accessing'! getState "Return the current state of this gate" self subclassResponsibility! ]style[(8 2 39 2 4 23)f2b,f2,f2c146044000,f2,f2cmagenta;,f2! ! !LogicGate methodsFor: 'accessing'! inputAt: anIndex "Return the input at the specified index, or error if none" ^ inputsCollection at: anIndex. ! ]style[(16 3 59 4 16 5 7 3)f2b,f2,f2c146044000,f2,f2cmagenta;,f2,f2cblue;i,f2! ! !LogicGate methodsFor: 'accessing'! outputAt: anIndex "Return the output at the specified index, or error if none" ^ outputsCollection at: anIndex! ]style[(10 7 3 60 4 17 5 7)f2b,f2cblue;b,f2,f2c146044000,f2,f2cmagenta;,f2,f2cblue;i! ! !LogicGate methodsFor: 'accessing'! removeAllConnections "Remove all connections (inputs and outputs)" outputsCollection do: [:output | output removeInput: self]. inputsCollection do: [:input | input removeOutput: self]. outputsCollection := OrderedCollection new. inputsCollection := OrderedCollection new! ]style[(20 2 45 2 17 8 8 2 6 14 4 4 16 8 7 2 5 15 4 4 17 4 17 7 16 4 17 4)f2b,f2,f2c149047000,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! !LogicGate methodsFor: 'accessing'! removeInput: input "Remove an input from our inputs collection" inputsCollection remove: input ifAbsent: []! ]style[(13 5 3 44 2 16 11 5 15)f2b,f2cblue;b,f2,f2c146044000,f2,f2cmagenta;,f2,f2cblue;i,f2! ! !LogicGate methodsFor: 'accessing'! removeOutput: output "Remove an output from our outputs collection" outputsCollection remove: output ifAbsent: []! ]style[(14 6 3 46 2 17 11 6 15)f2b,f2cblue;b,f2,f2c146044000,f2,f2cmagenta;,f2,f2cblue;i,f2! ! !LogicGate methodsFor: 'initialize'! initialize super initialize. inputsCollection := OrderedCollection new. outputsCollection := OrderedCollection new. state := false. inputsReporting := 0! ]style[(29 2 16 4 17 7 17 4 17 7 5 4 5 3 15 4 1)f2b,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2c200200124! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! LogicGate class instanceVariableNames: ''! !LogicGate class methodsFor: 'instance creation'! newGate "Create a new gate with inputs set at false (no objects or other gates yet attached" | newGate | newGate := self new initialize. ^ newGate! ]style[(7 2 87 3 8 4 7 4 4 20 7)f2b,f2,f2c145043000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i! ! LogicGate variableSubclass: #AndGate instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !AndGate commentStamp: '' prior: 0! And Logic gate. If all inputs are true, output is true. If any inputs are not true, output is false! !AndGate methodsFor: 'accessing'! getState "Return true if all inputs are true, return false if any input is false" |returnState| returnState := true. color := Color green. inputsCollection do: [:input | input getState ifFalse: [color := Color white. returnState := false. ]]. "If any input is not true, returnState is set to false, we will return false" self computeBounds. ^ returnState! ]style[(8 2 132 2 16 8 7 2 5 33 5 53 77 9 4 19 11)f2b,f2,f2c149047000,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c149047000,f2,f2cmagenta;,f2,f2cmagenta;! ! !AndGate methodsFor: 'accessing'! initializeToStandAlone "Initialize the receiver so that it can live as a stand-alone morph" "Set up our polygon on an openInWorld request" | rootX rootY | self initialize. rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 7. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 12 @ rootY. verts at: 3 put: rootX + 19 @ (rootY + 5). verts at: 4 put: rootX + 21 @ (rootY + 10). verts at: 5 put: rootX + 19 @ (rootY + 15). verts at: 6 put: rootX + 12 @ (rootY + 20). verts at: 7 put: rootX @ (rootY + 20). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue.! ]style[(22 73 46 3 12 22 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 5 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 1 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 4 13 5 10 5 22 1 16 5 6)f2b,f2,f2c142040000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c142040000,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2c197197121,f2,f2cblue;i,f2,f2cblue;i,f2,f2c197197121,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c197197121,f2,f2cmagenta;,f2! ! !AndGate methodsFor: 'accessing'! openInWorld "Set up our polygon on an openInWorld request" | rootX rootY | rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 7. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 12 @ rootY. verts at: 3 put: rootX + 19 @ (rootY + 5). verts at: 4 put: rootX + 21 @ (rootY + 10). verts at: 5 put: rootX + 19 @ (rootY + 15). verts at: 6 put: rootX + 12 @ (rootY + 20). verts at: 7 put: rootX @ (rootY + 20). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. super openInWorld! ]style[(11 2 46 3 12 4 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 1 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 4 13 5 10 5 22 1 16 5 10 5 12)f2b,f2,f2c148046000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c148046000,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2c198198122,f2,f2cblue;i,f2,f2cblue;i,f2,f2c198198122,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c198198122,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! AndGate class instanceVariableNames: ''! !AndGate class methodsFor: 'parts-bin'! descriptionForPartsBin ^ self partName: 'AndGate' categories: #('Logic' ) documentation: 'An and gate morph'! ]style[(22 4 4 13 9 15 11 18 19)f2b,f2,f2cmagenta;,f2,f2c196196120,f2,f2c196196120,f2,f2c196196120! ! LogicGate variableSubclass: #InputGate instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !InputGate commentStamp: '' prior: 0! This is the basic input into a logic gate. Logic gates have either other logic gates as their inputs, or one of us, an InputGate.! !InputGate methodsFor: 'accessing'! clock "After we have set the state of this input, we call clock which sends our state upstream" outputsCollection do: [:output | output clock: self]! ]style[(96 2 17 8 8 2 6 8 4 1)f2b,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2! ! !InputGate methodsFor: 'accessing'! clock: shouldNotImplement self shouldNotImplement. ! ! !InputGate methodsFor: 'accessing'! getState state ifTrue: [color := Color green] ifFalse: [color := Color white]. self computeBounds. ^ state! ]style[(8 2 5 12 5 4 5 20 5 4 5 10 4 19 5)f2b,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;! ! !InputGate methodsFor: 'accessing'! handlesKeyboard: evt ^true! ! !InputGate methodsFor: 'accessing' stamp: 'Brian Tabone 1/18/2005 09:27'! handlesMouseOver: evt ^true! ! !InputGate methodsFor: 'accessing'! initializeToStandAlone "Set up our polygon on an openInWorld request" | rootX rootY | self initialize. rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 4. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 20 @ rootY. verts at: 3 put: rootX + 20 @ (rootY + 20). verts at: 4 put: rootX @ (rootY + 20). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. ! ]style[(22 2 46 3 13 22 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 4 13 5 10 5 22 1 16 5 8)f2b,f2,f2c149047000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c149047000,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cmagenta;,f2! ! !InputGate methodsFor: 'accessing'! keyStroke: evt "Handle a keystroke event." evt keyCharacter = 't' asCharacter | (evt keyCharacter = 'T' asCharacter) ifTrue: [self setState: true]. evt keyCharacter = 'f' asCharacter | (evt keyCharacter = 'F' asCharacter) ifTrue: [self setState: false]. "Force all wires to update their connections incase any have gotten disconnected. This overcomes what seems like a bug that can occur when you move a wire" LogicWire allInstances do: [:wire | wire connectionsChanged]. "Itterate over all input gates , sending the clock." InputGate allInstances do: [:inputGate | inputGate clock]! ]style[(11 3 3 27 2 3 16 3 16 3 16 3 25 4 11 4 4 3 16 3 16 3 16 3 25 4 11 5 163 9 21 6 2 4 24 52 2 9 21 11 2 9 7)f2b,f2cblue;b,f2,f2c150048000,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2c150048000,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2! ! !InputGate methodsFor: 'accessing'! mouseEnter: evt "Highlight our border" self borderColor: Color red. ! ]style[(15 30 4 14 5 10)f2b,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! !InputGate methodsFor: 'accessing'! mouseLeave: evt "Turn off border highlights" self borderColor: Color blue. ! ]style[(15 36 4 14 5 11)f2b,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! !InputGate methodsFor: 'accessing'! openInWorld "Set up our polygon on an openInWorld request" | rootX rootY | rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 4. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 20 @ rootY. verts at: 3 put: rootX + 20 @ (rootY + 20). verts at: 4 put: rootX @ (rootY + 20). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. super openInWorld! ]style[(11 2 46 3 13 4 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 4 13 5 10 5 22 1 16 5 8 5 12)f2b,f2,f2c150048000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c150048000,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! !InputGate methodsFor: 'accessing'! setState: stateBool state := stateBool. "force the update of our color" self getState! ]style[(10 9 3 5 4 59)f2b,f2cblue;b,f2,f2cmagenta;,f2,f2cblue;i! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! InputGate class instanceVariableNames: ''! !InputGate class methodsFor: 'as yet unclassified'! descriptionForPartsBin ^ self partName: 'Input' categories: #('Logic' ) documentation: 'An input which takes key strokes (t/f) to turn on and off. '! ]style[(22 4 4 13 7 15 11 18 61)f2b,f2,f2cmagenta;,f2,f2c195195119,f2,f2c195195119,f2,f2c195195119! ! LogicGate variableSubclass: #Inverter instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !Inverter commentStamp: '' prior: 0! Inverts its single input! !Inverter methodsFor: 'accessing'! addInput: input "Attach either a LogicGate into our input, we override here since we only ever have one input" inputsCollection := #() asOrderedCollection. inputsCollection add:input. input addOutput: self! ]style[(10 5 3 97 2 16 4 3 52 5 12 4)f2b,f2cblue;b,f2,f2c145043000,f2,f2cmagenta;,f2,f2c195195119,f2,f2cblue;i,f2,f2cmagenta;! ! !Inverter methodsFor: 'accessing'! getState "Get the inverse of our input state (Our only input is index 1, all other indexes are ignored" "If internal state is true, getstate returns false, turn our color white. The opposite is true for internal state of false" inputsCollection do: [:invertedInput | self computeBounds. state := invertedInput getState not. state ifTrue: [color := Color green] ifFalse: [color := Color white]. ^ state]! ]style[(8 2 225 2 16 8 15 6 4 19 5 4 13 18 5 14 5 4 5 22 5 4 5 14 5 1)f2b,f2,f2c150048000,f2,f2cmagenta;,f2,f2cred;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! !Inverter methodsFor: 'accessing'! initializeToStandAlone "Initialize the receiver so that it can live as a stand-alone morph" "Set up our polygon on an openInWorld request" | rootX rootY invertCircle | self initialize. rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 6. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 10 @ rootY. verts at: 3 put: rootX + 10 @ (rootY + 20). verts at: 4 put: rootX + 35 @ rootY. verts at: 5 put: rootX + 10 @ (rootY - 20). verts at: 6 put: rootX + 10 @ rootY. "Put the inverter circle on the tip of the triangle, we create that morph and place it here" invertCircle := CircleMorph new. invertCircle color: Color white. invertCircle bounds: (0 @ 0 corner: 6 @ 6). invertCircle position: rootX + 35 @ (rootY - 3). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. self addMorph: invertCircle.! ]style[(22 73 46 3 12 35 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 3 5 3 95 2 12 4 11 7 12 8 5 9 12 12 1 3 1 9 1 3 1 4 12 11 5 3 2 4 5 3 1 4 4 13 5 10 5 22 1 16 5 8 4 11 12 1)f2b,f2,f2c142040000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c142040000,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2c192192116,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c149047000,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2c199199123,f2,f2c199199123,f2,f2c199199123,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cblue;i,f2! ! !Inverter methodsFor: 'as yet unclassified'! openInWorld "Set up our polygon on an openInWorld request" | rootX rootY invertCircle | rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 6. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 10 @ rootY. verts at: 3 put: rootX + 10 @ (rootY + 20). verts at: 4 put: rootX + 35 @ rootY. verts at: 5 put: rootX + 10 @ (rootY - 20). verts at: 6 put: rootX + 10 @ rootY. "Put the inverter circle on the tip of the triangle, we create that morph and place it here" invertCircle := CircleMorph new. invertCircle color: Color white. invertCircle bounds: (0 @ 0 corner: 6 @ 6). invertCircle position: rootX + 35 @ (rootY - 3). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. self addMorph: invertCircle. super openInWorld! ]style[(11 2 46 3 26 4 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 1 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 3 5 3 95 2 12 4 11 7 12 8 5 9 12 12 1 3 1 9 1 3 1 4 12 11 5 3 2 4 5 3 1 4 4 13 5 10 5 22 1 16 5 8 4 11 12 3 5 12)f2b,f2,f2c150048000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c150048000,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c150048000,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2c200200124,f2,f2c200200124,f2,f2c200200124,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! Inverter class instanceVariableNames: ''! !Inverter class methodsFor: 'as yet unclassified'! descriptionForPartsBin ^ self partName: 'Inverter' categories: #('Logic' ) documentation: 'An inverter'! ]style[(22 4 4 13 10 15 11 18 13)f2b,f2,f2cmagenta;,f2,f2c197197121,f2,f2c197197121,f2,f2c197197121! ! NCAAConnectorMorph subclass: #LogicWire instanceVariableNames: 'orGate' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !LogicWire commentStamp: '' prior: 0! The Logic wire morph that connects our various logic gates! !LogicWire methodsFor: 'connection'! addInput: aMorph aMorph class == LogicWire ifTrue:[orGate addInput: aMorph internalGate] ifFalse:[ orGate addInput: aMorph.]! ]style[(10 6 89 6 11 6 2)f2b,f2cblue;b,f2,f2cmagenta;,f2,f2cblue;i,f2! ! !LogicWire methodsFor: 'connection'! addOutput: aMorph aMorph addInput: orGate.! ]style[(11 6 3 6 11 7)f2b,f2cblue;b,f2,f2cmagenta;,f2,f2cblue;i! ! !LogicWire methodsFor: 'accessing'! initializeToStandAlone super initializeToStandAlone. orGate := OrGate newGate.! ! !LogicWire methodsFor: 'accessing'! internalGate "Return the logic gate that holds our state" ^orGate! ! !LogicWire methodsFor: 'accessing'! openInWorld super openInWorld. orGate := OrGate newGate.! ! !LogicWire methodsFor: 'protected-notifications'! connectionsChanged "Detach ourselves from our intputs and outputs, re-attach ourselves to the new input and output morphs" | input output | orGate ifNotNil: [orGate removeAllConnections]. input := self sourceMorph. output := self destinationMorph. input ifNotNil:[self addInput: input.]. output ifNotNil:[self addOutput: output]. ! ]style[(18 2 106 3 13 4 6 14 6 25 5 4 4 15 6 4 4 20 5 11 4 11 5 5 6 11 4 12 6 5)f2b,f2,f2c150048000,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! LogicWire class instanceVariableNames: ''! !LogicWire class methodsFor: 'as yet unclassified' stamp: 'Brian Tabone 1/17/2005 22:39'! descriptionForPartsBin ^ self partName: 'Logic Wire' categories: #('Logic' ) documentation: 'Logical wire. Note, connect inputs before connection outputs'! ]style[(22 4 4 13 12 15 11 18 62)f2b,f2,f2cmagenta;,f2,f2c196196120,f2,f2c196196120,f2,f2c196196120! ! LogicGate variableSubclass: #OrGate instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Logic''s Gate'! !OrGate commentStamp: '' prior: 0! Or Logic gate. If any inputs are true, output is true. If all inputs are not true, output is false! !OrGate methodsFor: 'accessing'! getState "Return true if any inputs are true, return false if all inputs are false" inputsCollection do: [:input | input getState ifTrue: [color := Color green. self computeBounds. ^ true]]. "If we get here, all inputs were false, return false" color := Color white. self computeBounds. ^ false! ]style[(8 2 74 2 16 8 7 2 5 23 5 4 5 13 4 23 4 5 55 48 5)f2b,f2,f2c150048000,f2,f2cmagenta;,f2,f2cred;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2cmagenta;,f2,f2c150048000,f2,f2cmagenta;! ! !OrGate methodsFor: 'accessing'! initializeToStandAlone "Initialize the receiver so that it can live as a stand-alone morph" "Set up our polygon on an openInWorld request" | rootX rootY | self initialize. rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 10. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 12 @ rootY. verts at: 3 put: rootX + 18 @ (rootY + 5). verts at: 4 put: rootX + 19 @ (rootY + 10). verts at: 5 put: rootX + 18 @ (rootY + 15). verts at: 6 put: rootX + 12 @ (rootY + 20). verts at: 7 put: rootX @ (rootY + 20). verts at: 8 put: rootX + 4 @ (rootY + 15). verts at: 9 put: rootX + 5 @ (rootY + 10). verts at: 10 put: rootX + 4 @ (rootY + 5). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue.! ]style[(22 73 46 3 12 22 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 2 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 1 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 5 5 1 6 5 3 1 4 5 3 2 4 5 5 1 6 5 3 1 4 5 3 2 4 5 5 2 6 5 3 1 4 5 3 1 4 4 13 5 10 5 22 1 16 5 6)f2b,f2,f2c144042000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c144042000,f2,f2cblue;i,f2,f2c194194118,f2,f2cblue;i,f2,f2c194194118,f2,f2cblue;i,f2,f2c194194118,f2,f2cblue;i,f2,f2c194194118,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cblue;i,f2,f2c199199123,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c199199123,f2,f2cmagenta;,f2! ! !OrGate methodsFor: 'accessing'! openInWorld "Set up our polygon on an openInWorld request" | rootX rootY | rootX := self position x. rootY := self position y. "If our position is not initialized set our base to something reasonable" rootX < 0 ifTrue: [rootX := 10]. rootY < 0 ifTrue: [rootY := 10]. verts := Array new: 10. verts at: 1 put: rootX @ rootY. verts at: 2 put: rootX + 12 @ rootY. verts at: 3 put: rootX + 18 @ (rootY + 5). verts at: 4 put: rootX + 19 @ (rootY + 10). verts at: 5 put: rootX + 18 @ (rootY + 15). verts at: 6 put: rootX + 12 @ (rootY + 20). verts at: 7 put: rootX @ (rootY + 20). verts at: 8 put: rootX + 4 @ (rootY + 15). verts at: 9 put: rootX + 5 @ (rootY + 10). verts at: 10 put: rootX + 4 @ (rootY + 5). self vertices: verts color: Color white borderWidth: 1 borderColor: Color blue. super openInWorld! ]style[(11 2 46 3 12 4 5 4 4 14 5 4 4 14 73 2 5 3 1 12 5 4 2 4 5 3 1 12 5 4 2 4 5 4 5 6 2 3 5 5 1 6 5 3 5 3 5 5 1 6 5 3 2 3 5 3 5 5 1 6 5 3 2 4 5 3 1 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 3 2 4 5 3 2 4 5 5 1 6 5 4 5 3 2 4 5 5 1 6 5 3 1 4 5 3 2 4 5 5 1 6 5 3 1 4 5 3 2 4 5 5 2 6 5 3 1 4 5 3 1 4 4 13 5 10 5 22 1 16 5 8 5 12)f2b,f2,f2c150048000,f2,f2cblue;i,f2,f2cblue;i,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c150048000,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cblue;i,f2,f2c200200124,f2,f2cmagenta;,f2,f2cblue;i,f2,f2cmagenta;,f2,f2c200200124,f2,f2cmagenta;,f2,f2cmagenta;,f2! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! OrGate class instanceVariableNames: ''! !OrGate class methodsFor: 'parts-bin'! descriptionForPartsBin ^ self partName: 'OrGate' categories: #('Logic' ) documentation: 'An Or gate morph'! ]style[(22 4 4 13 8 15 11 18 18)f2b,f2,f2cmagenta;,f2,f2c198198122,f2,f2c198198122,f2,f2c198198122! !