/**
* Copyright CatHobo ( http://wonderfl.net/user/CatHobo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5bq1
*/
package {
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.system.System;
import net.hires.debug.Stats;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.display.Shape;
public class Main extends Sprite{
public function Main():void {
this.graphics.beginFill(0xFFFFBF);
this.graphics.drawRect(0,0
,this.stage.stageWidth,this.stage.stageHeight);
this.addChild(new Stats());
this.stage.frameRate=20;
ld.load(new URLRequest("http://www.clker.com/cliparts/c/7/2/0/1194989704344503149lightbulb_jon_phillips_05.svg.thumb.png")
,new LoaderContext(true));
ld.contentLoaderInfo.addEventListener(Event.COMPLETE,LoadDisplay);
LogicGUI.INIT(this); //Initialize GUI.
ElectricityQueue.RequestBitmapDraw(
Plug_Bitmap,new Rectangle(0,0,100,50),2);
Wonderfl.capture_delay(20);
}
public static var Plug_Bitmap:Bitmap=new Bitmap();
private function LoadDisplay(e:Event):void{
//ld.content.scaleX=0.5;
//ld.content.scaleY=0.5;
//ld.content.x=100;
//ld.content.y=200;
//var cropper:Rectangle=new Rectangle(36,710,77,90);
//ld.content.scrollRect=cropper;
//this.addChild(ld.content);
var bmp_data:BitmapData=new BitmapData(
ld.content.width,ld.content.height,true,0xFFFFFF);
var bmp:Bitmap=new Bitmap();
bmp_data.draw(ld);
bmp.bitmapData=bmp_data;
bmp.x=100;
bmp.y=100;
//bmp.scaleX=Electricity.SquareLength/bmp.width;
//bmp.scaleY=Electricity.SquareLength/bmp.height;
this.addChild(bmp);
//Console.Print(bmp.height);
//Console.Print(bmp.width);
var bmp2:Bitmap=new Bitmap();
bmp_data.draw(ld);
bmp2.bitmapData=bmp_data;
bmp2.x=300;
bmp2.y=300;
this.addChild(bmp2); //Draw bitmaps for no reason.
}
private var ld:Loader=new Loader();
//public static var LogicGatesArray:Array=new Array();
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.Stage;
import flash.display.Shape;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.display.SimpleButton;
final class LogicGUI{
//Static GUI class for the purpose of creating buttons
//that execute Functions() when clicked.
private static var AlreadyInit:Boolean=false;
private static var GUIContainer:Sprite=new Sprite();
private static var StageRef:Stage;
private static var DocumentClassRef:Main;
public static function INIT(DocumentClassRef:Main):void{
if(AlreadyInit){throw new Error("GUI already initialized.")};
LogicGUI.StageRef=DocumentClassRef.stage;
LogicGUI.DocumentClassRef=DocumentClassRef;
AlreadyInit=true;
GUIContainer.visible=false;
StageRef.addChild(GUIContainer);
StageRef.addEventListener(MouseEvent.CLICK,CreateGUIListener);
}
private static var TimerToActivate:Timer
=new Timer(100,1);
private static function CreateClassObject(
ClassObj:Class,init_x:Number,init_y:Number):Function{
return function():void{
/*Main.LogicGatesArray.push(
new ClassObj(init_x,init_y));
DocumentClassRef.addChild(
Main.LogicGatesArray[Main.LogicGatesArray.length-1]);*/
DocumentClassRef.addChild(new ClassObj(init_x,init_y));
}
} //Factory method that creates new Electricity sprites.
//Using it when clicking the Stage GUI buttons.
public static var GUIDisable:Boolean=false;
private static function CreateGUIListener(e:MouseEvent):void{
if(GUIDisable){
TimerToActivate.reset();
TimerToActivate.start();
TimerToActivate.addEventListener(
TimerEvent.TIMER_COMPLETE,
function(e:TimerEvent):void
{GUIDisable=false;});
return; //This code is still broken.
}
if(e.target is Stage){
var menu_items:Array=[
[CreateClassObject(InputSprite,e.stageX,e.stageY),null,[],"Create InputSprite"],
[CreateClassObject(BufferGate,e.stageX,e.stageY),null,[],"Create BufferGate"],
[CreateClassObject(NOTGate,e.stageX,e.stageY),null,[],"Create NOTGate"],
[CreateClassObject(ANDGate,e.stageX,e.stageY),null,[],"Create ANDGate"],
[CreateClassObject(ORGate,e.stageX,e.stageY),null,[],"Create ORGate"],
[CreateClassObject(XORGate,e.stageX,e.stageY),null,[],"Create XORGate"],
[CreateClassObject(NANDGate,e.stageX,e.stageY),null,[],"Create NANDGate"],
[CreateClassObject(NORGate,e.stageX,e.stageY),null,[],"Create NORGate"],
[CreateClassObject(XNORGate,e.stageX,e.stageY),null,[],"Create XNORGate"]
] //Creates new sprite objects and make them appear.
for each(var menu_item:Object in menu_items){
FunctionsArray.push(menu_item[0]);
ObjectRefArray.push(menu_item[1]);
ArgumentsArray.push(menu_item[2]);
ButtonNameArray.push(menu_item[3]);
}
GUIContainer.visible=true;
GUIContainer.graphics.clear();
CreateButtons();
}else if(e.target is GUIInterface){
var MenuItemArray:Array=e.target.ImplementMenuItems();
for each(var menu_item2:Object in MenuItemArray){
FunctionsArray.push(menu_item2[0]);
ObjectRefArray.push(menu_item2[1]);
ArgumentsArray.push(menu_item2[2]);
ButtonNameArray.push(menu_item2[3]);
}
GUIContainer.visible=true;
GUIContainer.graphics.clear();
CreateButtons();
}
GUIContainer.x
=(e.stageX-10+GUIContainer.width<StageRef.stageWidth
?e.stageX-10
:StageRef.stageWidth-GUIContainer.width);
GUIContainer.y
=(e.stageY-10+GUIContainer.height<StageRef.stageHeight
?e.stageY-10
:StageRef.stageHeight-GUIContainer.height+5);
//Set x and y such that the GUI is always "on-screen"
//and it doesn't make the GUI "off-bounds" and "unreadable".
GUIContainer.graphics.beginFill(0x000000);
GUIContainer.graphics.drawRoundRect(-3,-3
,GUIContainer.width+6,GUIContainer.height+6,20,20);
//Black round rectangle to hold the buttons.
GUIContainer.addEventListener(
MouseEvent.ROLL_OUT,HideGUIListener);
GUIContainer.addEventListener(
MouseEvent.CLICK,HideGUIListener);
}
private static function HideGUIListener(e:MouseEvent):void{
//If clicking a SimpleButton, or hovering out the GUI...
GUIContainer.visible=false;
for(var i:int=0
;i<GUIContainer.numChildren;i++){
GUIContainer.getChildAt(i)
.removeEventListener(
MouseEvent.CLICK,ButtonListeners[i]);
//Remove event listeners
//for each button, the complicated way.
}
while (GUIContainer.numChildren > 0) {
GUIContainer.removeChildAt(0);
} //Remove-all-children loop.
ClearButtonArrays();
GUIContainer.removeEventListener(
MouseEvent.ROLL_OUT,HideGUIListener);
GUIContainer.removeEventListener(
MouseEvent.CLICK,HideGUIListener);
}
private static var FunctionsArray:Vector.<Function>
=new Vector.<Function>();
private static var ObjectRefArray:Array=new Array();
private static var ArgumentsArray:Array=new Array();
private static var ButtonNameArray:Vector.<String>
=new Vector.<String>();
private static var ButtonListeners:Vector.<Function>
=new Vector.<Function>();
private static function CreateButtons():void{
for(var i:int=0;i<FunctionsArray.length;i++){
GUIContainer.addChild(
CreateAButton(FunctionsArray[i]
,ObjectRefArray[i]
,ArgumentsArray[i]
,ButtonNameArray[i]));
}
}
private static function ClearButtonArrays():void{
FunctionsArray.length=0;
ArgumentsArray.length=0;
ButtonNameArray.length=0;
ButtonListeners.length=0;
ObjectRefArray.length=0;
}
private static function CreateAButton(
ButtonFunction:Function,ObjRef:Object
,ButtonArguments:Array,ButtonName:String):SimpleButton{
var sb:SimpleButton=new SimpleButton(
CreateAButtonFrame(0x7F7F7F,ButtonName),//Un-highlighted
CreateAButtonFrame(0x7F7FFF,ButtonName),//highlighted
CreateAButtonFrame(0xFF7F00,ButtonName),//Clicked
CreateAButtonFrame(0xFFFFFF,ButtonName));//Area to click?
var WhenClickedCallThis:Function=
function(e:MouseEvent):void{
ButtonFunction.apply(ObjRef,ButtonArguments);
} //Anonymous listener that will call the function
//with the proper arguments used.
ButtonListeners.push(WhenClickedCallThis);
sb.addEventListener(
MouseEvent.CLICK,WhenClickedCallThis);
return sb;
}
private static function CreateAButtonFrame(
color:uint,message:String="Call Function()"):Sprite{
var spr:Sprite=new Sprite();
//For button graphics and container for TextField.
var tf:TextField=new TextField();
tf.defaultTextFormat=new TextFormat(
"Verdana",19,0xFFFFFF,true,true);
tf.width=250;
tf.wordWrap=true;
tf.text=message;
tf.width=tf.textWidth+5;
//Set width smaller if there's little text.
tf.autoSize=TextFieldAutoSize.LEFT;
spr.addChild(tf);
spr.graphics.lineStyle(2,0x000000);
spr.graphics.beginFill(color);
spr.y=GUIContainer.height;
//For each new button, move the button down.
spr.graphics.drawRoundRect(0,0
,tf.width,tf.height,20,20);
return spr;
}
}
interface GUIInterface{
function ImplementMenuItems():Array;
/*Implements a multi-dimensional array that returns
the form [[Function object,object reference,[Arguments Array],ButtonName],
[Function object,object reference,[Arguments Array],ButtonName],
[Function object,object reference,[Arguments Array],ButtonName],
...]
so that the GUI can call sprite functions by clicking buttons.*/
}
import flash.display.Sprite;
//Attempting to see how inheritance works.
class Entity extends Sprite{
private static var _EntitiesCreated:int=0;
public static function EntitiesCreated():int{
return _EntitiesCreated;
}
protected var ID:int=++_EntitiesCreated;
protected var _Type:String="Type N/A";
public function get Type():String{
return _Type;
}
public function GetID():int{
return ID;
}
override public function toString():String{
return super.toString()+" ID #"+ID;
//toString with just ID # added.
}
public function Entity(init_x:Number=0,init_y:Number=0):void{
x=init_x;
y=init_y;
}
}
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.utils.Dictionary;
class WireSprite extends Entity implements GUIInterface{
public function ImplementMenuItems():Array{
return [
[RemoveWireObject,this,[],"Remove Wire"]
]
}
public function WireSprite(
e_in:Electricity,e_in_node:Sprite
,e_out:Electricity,e_out_node:Sprite,input_num:int):void{
_Type="WireSprite";
this.buttonMode=true;
function UpdateGraphics(e:Event):void{
try{
graphics.clear();
graphics.lineStyle(5,
e_out.IsPowerON()?0x3FFF3F:0xFF3F3F);
graphics.moveTo(e_out_node.x+6
,e_out_node.y);
graphics.lineTo(e_in.x+e_in_node.x-e_out.x-6
,e_in.y+e_in_node.y-e_out.y);
//Console.Print("This will appear until you delete wires.");
}catch(E:Error){
RemoveWireObject();
}
}
function WhenClickedRemoveWire(e:MouseEvent=null):void{
if(CalledOnce){return;}
CalledOnce=true;
//Console.Print("Deleted wire name \""+name+"\"");
e_out.AsOutputDisconnectInput(e_in,input_num);
e_in.Run(); //Update inputs as Output is disconnected.
RemoveSelf();
//removeEventListener(MouseEvent.CLICK,WhenClickedRemoveWire);
removeEventListener(Event.ENTER_FRAME,UpdateGraphics);
}
//this.addEventListener(MouseEvent.CLICK,WhenClickedRemoveWire);
this.addEventListener(Event.ENTER_FRAME,UpdateGraphics);
this.RemoveWireObject=WhenClickedRemoveWire;
}
private var CalledOnce:Boolean=false;
public var RemoveWireObject:Function;
//Function closure used to "delete"
//the Event listeners and the object.
private function RemoveSelf():void{
this.parent.removeChild(this);
//Remove self using the Electricity class object (parent)
//where it is added.
}
}
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Rectangle;
import flash.display.Shape;
import flash.events.Event;
import flash.display.Sprite;
final class ElectricityQueue{
//Custom static class for the purpose of calling the function Run()
//of each ElectricityEvent object (When DispatchToObj is called),
//and preloading images for the gates.
private static var EveryFrameCall:Sprite=new Sprite();
//private static var ld:Loader=new Loader();
//private static var LoadedComplete:Boolean=false;
private static var LoaderArray:Vector.<Loader>
=new Vector.<Loader>();
private static var LoadedCompleteArray:Vector.<Boolean>
=new Vector.<Boolean>();
//New code that can load multiple pictures and can wait when
//one of the pictures are still loading.
{
EveryFrameCall.addEventListener(Event.ENTER_FRAME,StartDispatch);
EveryFrameCall.addEventListener(Event.ENTER_FRAME,PictureLoadedDispatch);
LoaderArray.push(new Loader(),new Loader(),new Loader());
LoadedCompleteArray.push(false,false,false);
LoaderArray[0].load(new URLRequest(
"http://openclipart.org/image/800px/svg_to_png/12885/nobody_Digital_logic_gates.png")
,new LoaderContext(true));
LoaderArray[0].contentLoaderInfo.addEventListener(Event.COMPLETE,LoadDisplay);
LoaderArray[1].load(new URLRequest(
"http://www.clker.com/cliparts/8/7/1/6/1351019548860867760Power%20Symbol.svg.thumb.png")
,new LoaderContext(true));
LoaderArray[1].contentLoaderInfo.addEventListener(Event.COMPLETE,LoadDisplay);
LoaderArray[2].load(new URLRequest(
"http://www.clker.com/cliparts/F/0/4/Y/f/a/power-cable-us-th.png")
,new LoaderContext(true));
LoaderArray[2].contentLoaderInfo.addEventListener(Event.COMPLETE,LoadDisplay);
/*ld.load(new URLRequest(
"http://openclipart.org/image/800px/svg_to_png/12885/nobody_Digital_logic_gates.png")
,new LoaderContext(true));
ld.contentLoaderInfo.addEventListener(Event.COMPLETE,LoadDisplay);*/
} //Static Initializer.
private static function LoadDisplay(e:Event):void{
//LoadedComplete=true;
for(var i:int=0;i<LoadedCompleteArray.length;i++){
if(e.target==LoaderArray[i].contentLoaderInfo){
LoadedCompleteArray[i]=true;
}
}
e.target.removeEventListener(Event.COMPLETE,LoadDisplay);
//Allow PictureLoadedDispatch to process drawing cropped bitmaps.
}
private static function PictureLoadedDispatch(e:Event):void{
//if(!LoadedComplete){return;}
if(BitmapToDrawQueue.length==0){return;}
var InfiniteLoop:int=0
while(BitmapToDrawQueue.length!=0){
if(++InfiniteLoop>=1000)
{throw new Error("Infinite loop.");}
if(!LoadedCompleteArray[PictureNumberQueue[0]]){
return;
}//If picture number is still loading, don't go to next code.
var picture_i:int=PictureNumberQueue.shift();
var bmp:Bitmap=BitmapToDrawQueue.shift();
var crop_rectangle:Rectangle=CropQueue.shift();
//Pop bitmap reference and rectangle from queue.
//ld.content.scrollRect=crop_rectangle;
LoaderArray[picture_i].content.scrollRect=crop_rectangle;
var bmp_data:BitmapData=new BitmapData(
crop_rectangle.width,crop_rectangle.height,true,0xFFFFFF);
//bmp_data.draw(ld); //Draw from loaded picture.
bmp_data.draw(LoaderArray[picture_i]);
bmp.bitmapData=bmp_data;
bmp.x+=Electricity.BorderLength;
bmp.y+=Electricity.BorderLength;
bmp.scaleX
=(Electricity.SquareLength-Electricity.BorderLength*2)/bmp.width;
bmp.scaleY
=(Electricity.SquareLength-Electricity.BorderLength*2)/bmp.height;
//Make the size the same as the size of the gates.
}
}
public static function RequestBitmapDraw(
bitmap_ref:Bitmap,crop_rectangle:Rectangle,pic_num:int=0):void{
BitmapToDrawQueue.push(bitmap_ref);
CropQueue.push(crop_rectangle);
PictureNumberQueue.push(pic_num);
} //Push bitmap reference so that it will be drawn when
//the picture is loaded, as well as the "crop" rectangle
//that will get the x, y, width, and height it will draw.
private static var BitmapToDrawQueue:Vector.<Bitmap>
=new Vector.<Bitmap>();
private static var CropQueue:Vector.<Rectangle>
=new Vector.<Rectangle>();
private static var PictureNumberQueue:Vector.<int>
=new Vector.<int>();
private static function StartDispatch(e:Event):void{
if(ElectricitySpriteQueue.length==0){return;}
//var Count:uint=0;
var InfiniteLoop:int=0
var PreviousLength:int=ElectricitySpriteQueue.length;
//To prevent an infinite loop, get previous length
//of ElectricitySpriteQueue, as calling it in
//the while loop is a problem (it keeps changing).
while(PreviousLength!=0){
if(++InfiniteLoop>=1000)
{throw new Error("ElectricitySpriteQueue too big.");}
var obj:Electricity=ElectricitySpriteQueue.shift();
obj.Run();
//++Count;
--PreviousLength;
//Console.Print(obj.Type+"("+obj.GetID()+")");
}
//Console.Print(Count+" have been called to Run() in queue.");
//Count debug to see if there's a problem with this Event class.
}
public static var ElectricitySpriteQueue:Array=new Array();
//If multiple Electricity sprites calls DispatchToObj,
//the queue will try to add all of them to call Run() above.
public static function DispatchToObj(E:Electricity):void{
for each(var obj:Electricity in ElectricitySpriteQueue){
if(E==obj){return;} //No duplicates are necessary.
}
ElectricitySpriteQueue.push(E);
}
}
import flash.geom.Rectangle;
final class LOGIC_GATE_ENUMS{
public static var BUFFER:Rectangle=new Rectangle(36,710,77,90);
public static var NOT:Rectangle=new Rectangle(36,710,96,90);
public static var AND:Rectangle=new Rectangle(313,0,130,110);
public static var NAND:Rectangle=new Rectangle(313,0,145,110);
public static var OR:Rectangle=new Rectangle(313,235,145,110);
public static var NOR:Rectangle=new Rectangle(313,235,162,110);
public static var XOR:Rectangle=new Rectangle(313,460,165,120);
public static var XNOR:Rectangle=new Rectangle(313,460,183,120);
}
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.SimpleButton;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
class NodeOutput extends Sprite implements GUIInterface{
public function ImplementMenuItems():Array{
return [
[ConnectTo,this,[],"Connect Output To"]
]
}
private function ConnectTo():void{
/*Console.Print("Connecting "+(this.parent as Electricity).Type
+"("+(this.parent as Electricity).GetID()+") to..."); */
this.root.stage.addEventListener(
MouseEvent.CLICK,ClickListener); //Using stage for mouse clicks.
(this.root as Main).addChild(Main.Plug_Bitmap);
Main.Plug_Bitmap.x=this.parent.x+this.x;
Main.Plug_Bitmap.y=this.parent.y+this.y;
}
private function ClickListener(e:MouseEvent):void{
if(e.target is NodeInput){
(this.parent as Electricity).AsOutputConnectToInput(
e.target.parent as Electricity,
e.target.GetNodeInputID()); //Connect wire.
}else if(!(e.target is SimpleButton)){
//Console.Print("Cancelled.");
}
//Click anywhere to cancel,
//but click an input node to connect.
LogicGUI.GUIDisable=true;
if(!(e.target is SimpleButton)||e.target is NodeInput){
this.root.stage.removeEventListener(
MouseEvent.CLICK,ClickListener);
(this.root as Main).removeChild(Main.Plug_Bitmap);
}
}
}
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.SimpleButton;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
class NodeInput extends Sprite implements GUIInterface{
public function ImplementMenuItems():Array{
return [
[ConnectTo,this,[],"Connect Input "+NodeInputID+" To"]
]
}
public function NodeInput(Init_ID:int):void{
NodeInputID=Init_ID;
}
private var NodeInputID:int;
public function GetNodeInputID():int{
return NodeInputID;
}
private function ConnectTo():void{
/*Console.Print("Connecting "+(this.parent as Electricity).Type
+"("+(this.parent as Electricity).GetID()+") to..."); */
this.root.stage.addEventListener(
MouseEvent.CLICK,ClickListener);
//Using stage for mouse clicks.
(this.root as Main).addChild(Main.Plug_Bitmap);
Main.Plug_Bitmap.x=this.parent.x+this.x;
Main.Plug_Bitmap.y=this.parent.y+this.y;
} //Then click a Node Input sprite to connect gates.
private function ClickListener(e:MouseEvent):void{
if(e.target is NodeOutput){
(e.target.parent as Electricity).AsOutputConnectToInput(
this.parent as Electricity,NodeInputID); //Connect wire.
}else if(!(e.target is SimpleButton)){
//Console.Print("Cancelled.");
}
//Click anywhere to cancel,
//but click an input node to connect.
LogicGUI.GUIDisable=true;
if(!(e.target is SimpleButton)||e.target is NodeOutput){
this.root.stage.removeEventListener(
MouseEvent.CLICK,ClickListener);
(this.root as Main).removeChild(Main.Plug_Bitmap);
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.display.Bitmap;
import flash.geom.Rectangle;
class Electricity extends Entity{
public static const SquareLength:Number=48;
public static const BorderLength:Number=4;
public function Electricity(
init_power:Boolean=false,init_x:Number=0
,init_y:Number=0,max_inputs:int=0,type:String="Type N/A"):void{
super(init_x,init_y);
_Type=type;
PowerON=init_power;
if(this is InputSprite){
DrawBodyColor(init_power?0x7F7FFF:0xBF3F3F);
//Fill as "on" or "off".
}else{
DrawBodyColor(0x7F7F7F); //Fill as "disconnected".
}
CreateNode(OutputNode,this.width,this.height/2-1);
MaxInputs=max_inputs;
if(MaxInputs==0){
InputNodes=null;
}else{
for(var i:int=0;i<MaxInputs;i++){
InputNodes.push(new NodeInput(i+1));
CreateNode(InputNodes[i],0
,(this.height/(MaxInputs-1+2))*(i+1)-1);
} //Create variable number of input nodes.
}
var UseCrop:Rectangle; //To crop bitmap pictures with.
var UsePictureNumber:int; //Load specific picture number.
switch(_Type){
case "BufferGate":
UseCrop=LOGIC_GATE_ENUMS.BUFFER;
UsePictureNumber=0;
break;
case "NOTGate":
UseCrop=LOGIC_GATE_ENUMS.NOT;
UsePictureNumber=0;
break;
case "ANDGate":
UseCrop=LOGIC_GATE_ENUMS.AND;
UsePictureNumber=0;
break;
case "ORGate":
UseCrop=LOGIC_GATE_ENUMS.OR;
UsePictureNumber=0;
break;
case "XORGate":
UseCrop=LOGIC_GATE_ENUMS.XOR;
UsePictureNumber=0;
break;
case "NANDGate":
UseCrop=LOGIC_GATE_ENUMS.NAND;
UsePictureNumber=0;
break;
case "NORGate":
UseCrop=LOGIC_GATE_ENUMS.NOR;
UsePictureNumber=0;
break;
case "XNORGate":
UseCrop=LOGIC_GATE_ENUMS.XNOR;
UsePictureNumber=0;
break;
case "InputSprite":
UseCrop=new Rectangle(0,0,97,99);
UsePictureNumber=1;
}
if(UseCrop){ //If UseCrop rectangle isn't null.
ElectricityQueue.RequestBitmapDraw(BitmapPicture
,UseCrop,UsePictureNumber);
this.addChild(BitmapPicture);
}
//Temporary code to see the ID of each Sprite.
/*ID_T.text="ID #"+String(ID);
ID_T.selectable=false;
ID_T.autoSize=TextFieldAutoSize.LEFT;
this.addChild(ID_T);*/
}
//private var ID_T:TextField=new TextField();
private function CreateNode(spr_ref:Sprite,
init_x:Number,init_y:Number):void{
spr_ref.x=init_x;
spr_ref.y=init_y;
spr_ref.graphics.beginFill(PowerON?0x007F00:0x7F0000);
spr_ref.graphics.drawCircle(0,0,6);
spr_ref.buttonMode=true;
this.addChild(spr_ref);
}
protected function DrawBodyColor(color:uint):void{
this.graphics.beginFill(color);
this.graphics.drawRoundRect(0,0,SquareLength,SquareLength,20,20);
}
private var BitmapPicture:Bitmap=new Bitmap();
protected var OutputNode:NodeOutput=new NodeOutput();
protected var InputNodes:Vector.<NodeInput>=new Vector.<NodeInput>();
protected var PowerON:Boolean=false;
public function IsPowerON():Boolean{
return PowerON;
}
protected var MaxInputs:int;
protected var InputsConnected:Boolean=false;
public function IsInputsConnected():Boolean{
return InputsConnected;
}
public function Run():void{}
//Will be implemented by other classes.
//protected var InputDictionary:Dictionary=new Dictionary(true);
//protected var OutputDictionary:Dictionary=new Dictionary(true);
protected var InputArray:Array=new Array();
protected var OutputArray:Array=new Array();
public function AsOutputConnectToInput(
e_in:Electricity,input_num:int=1):void{
if(!OutputArray){
throw new Error(
"Object "+this.Type+" doesn't have Outputs.");
}
//this.OutputDictionary[e_in]=null;
//e_in.InputDictionary[this]=input_num;
this.OutputArray.push(e_in);
var old_output:Electricity=e_in.InputArray[input_num-1];
if(old_output){
old_output.AsOutputDisconnectInput(e_in,input_num);
} //Delete old input connections if there are any.
e_in.InputArray[input_num-1]=this;
var w_s:WireSprite=new WireSprite(
e_in,e_in.InputNodes[input_num-1]
,this,this.OutputNode,input_num);
w_s.name=GetWireName(this,e_in,input_num);
//Console.Print("Added wire name \""+w_s.name+"\"");
//name used to delete specific wires.
this.addChildAt(w_s,0);
this.CallRunForOthers();
}
private function GetWireName(
e_out:Electricity,e_in:Electricity,input_num:int):String{
return "Output("+e_out.GetID()+")"+
"Input("+e_in.GetID()+","+input_num+")";
} //input_num from 1 to ...
public function AsOutputDisconnectInput(e_in:Electricity,
input_num:int):void{
if(!OutputArray){
throw new Error(
"Object "+this.Type+" doesn't have Outputs.");
}
var i:int;
//delete e_in.InputDictionary[this];
//delete this.OutputDictionary[e_in];
var stupid_infinite_loop:int=0;
for(i=0;i<this.OutputArray.length;i++){
if(this.OutputArray[i]==e_in){
//If we found the respective Electricity object,
//cycle through the other Array,
//to find the specific input number
//where it was connected to as Output to disconnect.
//Ex: (Disconnecting ID #1 output connecting to ID #2's
//input #2, and disconnecting ID #2's input #2
//at the same time. If there's an ID #2 input #1,
//don't disconnect that one.)
for(var j:int=0;j<e_in.InputArray.length;j++){
if(e_in.InputArray[j]==this&&input_num-1==j){
e_in.InputArray[j]=null;
//this.OutputArray[i]=null;
OutputArray.splice(i,1);
//Fixing OutputArray so that
//an item is "popped" out at some index.
var FoundWire:WireSprite=(this.getChildByName(
GetWireName(this,e_in,input_num)) as WireSprite);
if(FoundWire){
FoundWire.RemoveWireObject();
} //Delete WireSprite.
}
if(++stupid_infinite_loop>=1000){
throw new Error("infinite loop2.");
}
}
}
if(++stupid_infinite_loop>=1000){
throw new Error("infinite loop.");
}
}
this.CallRunForOthers();
}
public function DisconnectAllWires():void{
//Console.Print("Attempting to delete all wires for ID #"+this.ID);
var stop_infinite_loop:int=0;
while(this.OutputArray.length!=0){
//Delete output connections for this object.
if(++stop_infinite_loop>1000){
throw new Error("Infinite loop.");
}
//Using the first item to delete (this.OutputArray[0]), find
//the index so that the input number (j+1)
//is found to use the AsOutputDisconnectInput function.
var FirstItem:Electricity=this.OutputArray[0];
for(var j:int=0;j<FirstItem.InputArray.length;j++){
if(FirstItem.InputArray[j]==this){
this.AsOutputDisconnectInput(FirstItem,j+1);
break;
}
}
}
for(var i:int=0;i<this.InputArray.length;i++){
var output_obj:Electricity=this.InputArray[i] as Electricity;
if(output_obj){
output_obj.AsOutputDisconnectInput(this,i+1);
} //Delete input connections for this object.
}
}
public function CallRunForOthers():void{
/*for(var output_obj:Object in OutputDictionary){
ElectricityQueue.DispatchToObj(output_obj as Electricity);
} //Call other Electricity object's Run().*/
for(var i:int=0;i<this.OutputArray.length;i++){
if(this.OutputArray[i]){
ElectricityQueue.DispatchToObj(this.OutputArray[i]);
} //Dispatch only defined Electricity objects.
}
}
override public function toString():String{
return super.toString()+", Power ("+(PowerON?"ON)":"OFF)");
}
protected function GetStringInputsAndOutputs():String{
var TempString:String="";
var HasOutputs:Boolean=false;
/*for(var obj_output:Object in OutputDictionary){
TempString+=obj_output.Type+" (ID #"+obj_output.GetID()
+")("+(obj_output.PowerON?"ON":"OFF")+"),";
HasOutputs=true;
}//Gets the outputs it is connected to.*/
var i:int;
for(i=0;i<this.OutputArray.length;i++){
if(OutputArray[i]){
TempString+=OutputArray[i].Type+" (ID #"
+OutputArray[i].GetID()
+")("+(OutputArray[i].PowerON?"ON":"OFF")+"),";
HasOutputs=true;
}
}
if(!HasOutputs){
TempString+=" N/A...";
}else{
TempString+="..."
}
TempString+=" Max Inputs = "+MaxInputs+"...";
/*for(var obj_input:Object in InputDictionary){
TempString+=" Input #"+InputDictionary[obj_input]
+"("+obj_input.Type+" ID #"+obj_input.GetID()
+")("+(obj_input.PowerON?"ON":"OFF")+"),";
}*/
for(i=0;i<InputArray.length;i++){
if(InputArray[i]){
TempString+=" Input #"+(i+1)
+"("+InputArray[i].Type+" ID #"+InputArray[i].GetID()
+")("+(InputArray[i].PowerON?"ON":"OFF")+"),";
}
}
return TempString;
} //To add to toString in NonWireSprite class.
protected function ChangeColorNode(node_ref:Sprite,b:Boolean):void{
var ct:ColorTransform=new ColorTransform();
ct.color=(b?0x007F00:0x7F0000);
node_ref.transform.colorTransform=ct;
}
protected function DragThisSprite():void{
this.addEventListener(MouseEvent.MOUSE_MOVE,StartDrag);
this.dispatchEvent(
new MouseEvent(MouseEvent.MOUSE_MOVE
,false,false));
//Dispatch a custom mouse event.
Old_z=this.parent.getChildIndex(this);
this.parent.addChild(this); //Move to front using document class.
}
private var Old_z:int;
private function StartDrag(e:MouseEvent):void{
this.x=this.parent.mouseX-SquareLength/2;
this.y=this.parent.mouseY-SquareLength/2;
//Code to move the sprite in the middle.
//Excluding the wires using the
//SquareLength constant.
e.updateAfterEvent();
this.parent.addEventListener(
MouseEvent.CLICK,StopDrag);
LogicGUI.GUIDisable=true;
}
private function StopDrag(e:MouseEvent):void{
this.root.removeEventListener(
MouseEvent.CLICK,StopDrag);
this.removeEventListener(MouseEvent.MOUSE_MOVE,StartDrag);
this.parent.addChildAt(this,Old_z);
//Put back in old position, because wires block the input nodes.
}
public function DeleteSprite():void{
DisconnectAllWires();
this.addEventListener(
Event.ENTER_FRAME,FinallyDeleteSprite);
}
private function FinallyDeleteSprite(e:Event):void{
if(!this.InputsConnected||this is InputSprite){
this.removeEventListener(
Event.ENTER_FRAME,FinallyDeleteSprite);
this.parent.removeChild(this);
}
}
protected var SharedMenuItems:Array=[
[DragThisSprite,this,[],"Drag This Sprite"],
[DeleteSprite,this,[],"Delete This Sprite"],
[DisconnectAllWires,this,[],"Disconnect All Wires"]
] //Functions for GUI Interface buttons.
}
import flash.display.Sprite;
class NonWireSprite extends Electricity{
public function NonWireSprite(
init_power:Boolean=false,init_x:Number=0,
init_y:Number=0,max_inputs:int=0,type:String="Type N/A"):void{
super(init_power,init_x,init_y,max_inputs,type);
}
override public function toString():String{
var TempString:String=", Outputs To object(s):";
TempString+=GetStringInputsAndOutputs();
return super.toString()+", position (x="
+x+", y="+y+")"+TempString;
}
}
//WireSprite extends Electricity is moved as it extends Entity.
import flash.display.Sprite;
class InputSprite extends NonWireSprite implements GUIInterface{
public function ImplementMenuItems():Array{
return super.SharedMenuItems.concat([
[SetPower,this,[!super.PowerON],
"Turn Power "+(!super.PowerON?"On":"Off")]
])
}
public function InputSprite(
init_x:Number=0,init_y:Number=0,init_power:Boolean=false):void{
super(init_power,init_x,init_y,0,"InputSprite");
InputsConnected=true;
}
public function SetPower(b:Boolean):void{
super.PowerON=b;
CallRunForOthers();
ChangeColorNode(OutputNode,b);
DrawBodyColor(b?0x7F7FFF:0xBF3F3F);
}
}
import flash.display.Sprite;
class LogicGate extends NonWireSprite{
public function LogicGate(init_x:Number=0,init_y:Number=0,
start_bool:Boolean=false,
use_inverse:Boolean=false,max_inputs:int=0,type:String="Type N/A"):void{
super(false,init_x,init_y,max_inputs,type);
this.start_bool=start_bool;
this.use_inverse=use_inverse;
}
private var start_bool:Boolean;
private var use_inverse:Boolean;
override public function Run():void{
var obj_count:int=0;
var bool_result:Boolean=start_bool;
/*for(var obj_input:Object in InputDictionary){
try{
if(!obj_input.IsInputsConnected()){
this.PowerON=false;
ChangeColorNode(OutputNode,false);
this.InputsConnected=false;
this.CallRunForOthers();
return;
} //If InputsConnected is false in one object,
//make this as well and turn the power OFF.
obj_count++;
bool_result=FunctionToUse(
bool_result,obj_input.IsPowerON());
ChangeColorNode(
InputNodes[InputDictionary[obj_input]-1]
,obj_input.IsPowerON());
}catch(E:Error){
delete InputDictionary[obj_input];
this.PowerON=false;
ChangeColorNode(OutputNode,false);
this.InputsConnected=false;
this.CallRunForOthers();
return;
}
}*/
var InputSpriteConnected:Boolean=false;
//Assume we're disconnected.
for(var i:int=0;i<InputArray.length;i++){
if(!InputArray[i]){
this.PowerON=false;
ChangeColorNode(InputNodes[i],false);
continue; //If null/undefined, don't count this.
}
if(InputArray[i].IsInputsConnected()
&&InputArray[i]!=this){
if(!(InputArray[i] is InputSprite)){
var PreviousInputsConnected:Boolean=true;
for(var j:int=0;
j<InputArray[i].InputArray.length;j++){
if(!InputArray[i].InputArray[j].IsInputsConnected()){
PreviousInputsConnected=false;
break;
}
}
if(PreviousInputsConnected){
this.PowerON=true;
ChangeColorNode(InputNodes[i],true);
this.InputsConnected=true;
InputSpriteConnected=true;
}
}else{
this.PowerON=true;
ChangeColorNode(InputNodes[i],true);
this.InputsConnected=true;
InputSpriteConnected=true;
}
}
obj_count++;
bool_result=FunctionToUse(
bool_result,InputArray[i].IsPowerON());
ChangeColorNode(
InputNodes[i],InputArray[i].IsPowerON());
}
if(obj_count!=MaxInputs||!InputSpriteConnected){
this.PowerON=false;
ChangeColorNode(OutputNode,false);
this.InputsConnected=false;
DrawBodyColor(0x7F7F7F);
this.CallRunForOthers();
return;
}
//All inputs should be connected for the logic gate
//to turn ON, or it will be OFF.
var bool_result2:Boolean
=(use_inverse?(!bool_result):bool_result);
this.PowerON=bool_result2;
ChangeColorNode(OutputNode,bool_result2);
this.InputsConnected=true;
DrawBodyColor(bool_result2?0x7F7FFF:0xBF3F3F);
this.CallRunForOthers();
}
protected var FunctionToUse:Function
=function(a:Boolean,b:Boolean):Boolean{return true;};
//Subclasses will determine which function to use below.
protected function UseAND(a:Boolean,b:Boolean):Boolean{
return a && b;
}
protected function UseOR(a:Boolean,b:Boolean):Boolean{
return a || b;
}
protected function UseXOR(a:Boolean,b:Boolean):Boolean{
return (a && !b)||(!a && b);
}
}
import flash.display.Sprite;
class BufferGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function BufferGate(init_x:Number=0,init_y:Number=0):void{
super(init_x,init_y,false,false,1,"BufferGate");
FunctionToUse=UseOR;
}
} //Truth Table (true passes true and false passes false)
import flash.display.Sprite;
class NOTGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function NOTGate(init_x:Number=0,init_y:Number=0):void{
super(init_x,init_y,false,true,1,"NOTGate");
FunctionToUse=UseOR;
}
} //Truth Table (true passes false and false passes true)
import flash.display.Sprite;
class ANDGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function ANDGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,true,false,(max_inputs>=2?max_inputs:2),"ANDGate");
FunctionToUse=UseAND;
}
}
import flash.display.Sprite;
class ORGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function ORGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,false,false,(max_inputs>=2?max_inputs:2),"ORGate");
FunctionToUse=UseOR;
}
}
import flash.display.Sprite;
class XORGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function XORGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,false,false,(max_inputs>=2?max_inputs:2),"XORGate");
FunctionToUse=UseXOR;
}
}
import flash.display.Sprite;
class NANDGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function NANDGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,true,true,(max_inputs>=2?max_inputs:2),"NANDGate");
FunctionToUse=UseAND;
}
}
import flash.display.Sprite;
class NORGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function NORGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,false,true,(max_inputs>=2?max_inputs:2),"NORGate");
FunctionToUse=UseOR;
}
}
import flash.display.Sprite;
class XNORGate extends LogicGate implements GUIInterface{
public function ImplementMenuItems():Array{
return SharedMenuItems;
}
public function XNORGate(init_x:Number=0,init_y:Number=0,
max_inputs:int=2):void{
super(init_x,init_y,false,true,(max_inputs>=2?max_inputs:2),"XNORGate");
FunctionToUse=UseXOR;
}
}