From 05951c99b7888085154ec36d42de61c0542a4860 Mon Sep 17 00:00:00 2001 From: Giorgos Vyronos Date: Wed, 2 Mar 2022 03:04:37 +0000 Subject: [PATCH] Added all ap1919 implementations. --- src/Renderer/DrawBlock/Symbol.fs | 729 +++++++++++-------------------- 1 file changed, 267 insertions(+), 462 deletions(-) diff --git a/src/Renderer/DrawBlock/Symbol.fs b/src/Renderer/DrawBlock/Symbol.fs index e20f0e9..cd053cf 100644 --- a/src/Renderer/DrawBlock/Symbol.fs +++ b/src/Renderer/DrawBlock/Symbol.fs @@ -16,16 +16,20 @@ open System.Text.RegularExpressions /// --------- STATIC VARIABLES --------- /// let GridSize = 30 - /// ---------- SYMBOL TYPES ---------- /// +type Rotation = R0 | R90 | R180 | R270 + +type PortOrientation = Right | Bottom | Left | Top + type PortOrientationOffset = { - Side: int // Designated which side of symbol port is on (0 -> right, 1 -> top, 2 -> left, 3 -> bottom). to have coherency with STransform. - Offset: XYPos //Offset from top left corver of symbol, no matter orientation + Side: PortOrientation // Designated which side of symbol port is on (0 -> right, 1 -> top, 2 -> left, 3 -> bottom). to have coherency with STransform. + Offset: XYPos } + type Symbol = { Pos: XYPos - STransform: int // Describes how symbol is rotated/flipped (0 -> 0 deg, 1 -> 90 deg, 2 -> 180 deg, -> 3 -> 270 deg). + STransform: Rotation // Describes how symbol is rotated/flipped (0 -> 0 deg, 1 -> 90 deg, 2 -> 180 deg, -> 3 -> 270 deg). InWidth0: int option InWidth1: int option Id : ComponentId @@ -77,21 +81,6 @@ type Msg = | WriteMemoryLine of ComponentId * int64 * int64 // For Issie Integration | WriteMemoryType of ComponentId * ComponentType -//---------------------------------helper types and functions----------------// - -// ----- helper functions for titles ----- // -//STransform Finite State Machine -let stransform_fsm(prev_state:int):int = - match prev_state with - | 0 -> 1 - | 1 -> 2 - | 2 -> 3 - | 3 -> 0 - | _ -> 0 - -//Map to return new coordinates of Position of ports and symbol - - //---------------------------------helper types and functions----------------// let posDiff (a:XYPos) (b:XYPos) = @@ -102,6 +91,16 @@ let posAdd (a:XYPos) (b:XYPos) = let posOf x y = {X=x;Y=y} + +// ----- helper functions for titles ----- // +//STransform Finite State Machine +let stransform_fsm(prev_state:Rotation):Rotation = + match prev_state with + | R0 -> R90 + | R90 -> R180 + | R180 -> R270 + | R270 -> R0 + ///Insert titles compatible with greater than 1 buswidth let title t (n) = if n = 1 then t else t + "(" + string(n-1) + "..0)" @@ -156,40 +155,34 @@ let gateDecoderType (comp:Component) = | _ -> "" -let portDecNameM (comp:Component) = //(input port names, output port names) +let createCustomPortNamesMap inputLabels outputLabels = + let adder x ((name:string),n) (portType:PortType)= + let key = + match portType with + |PortType.Input -> "I"+ string x + |PortType.Output -> "O"+ string x + [(key,name)] + let inputList = if (List.length inputLabels) < 1 then [] else ( [0..((List.length inputLabels)-1)] |> List.collect (fun x -> (adder x inputLabels[x] PortType.Input))) + let outputList = if (List.length outputLabels) < 1 then [] else ( [0..((List.length outputLabels)-1)] |> List.collect (fun x -> (adder x outputLabels[x] PortType.Output))) + + [inputList;outputList] |> List.concat |> Map.ofList + +// Input and Output names of the ports depending on their ComponentType +// returns map with (port key in APortOffsetsMap, port name) +let portNameMap (comp:Component) = match comp.Type with - // | Decode4 -> (["Sel";"Data"],["0"; "1";"2"; "3"]) | NbitsAdder _ -> Map [ ("I0", "Cin"); ("I1", "A"); ("I2","B");("O0","Sum");("O1","Cout") ] | Decode4 -> Map [ ("I0", "Sel"); ("I1", "Data"); ("O0","0");("O1","1"); ("O2","2");("O3","3") ] - // | Register _ -> (["D"],["Q"]) - // | RegisterE _ -> (["D"; "EN"],["Q"]) - // | ROM1 _ |AsyncROM1 _ -> (["Addr"],["Dout"]) - // | RAM1 _ -> (["Addr"; "Din";"Wen" ],["Dout"]) - // | AsyncRAM1 _ -> (["Addr"; "Din";"Wen" ],["Dout"]) - // | DFF -> (["D"],["Q"]) - // | DFFE -> (["D";"EN"],["Q"]) + | Register _ |DFF -> Map [ ("I0", "D"); ("O0","Q") ] + | RegisterE _ |DFFE -> Map [ ("I0", "D"); ("I1","EN"); ("O0","Q") ] + | ROM1 _ |AsyncROM1 _ -> Map [ ("I0", "Addr");("O0","Dout") ] + | RAM1 _ -> Map [ ("I0", "Addr"); ("I1", "Din"); ("I2","Wen");("O0","Dout") ] + | AsyncRAM1 _ -> Map [ ("I0", "Addr"); ("I1", "Din"); ("I2","Wen");("O0","Dout") ] | Mux2 -> Map [ ("I0", "0"); ("I1", "1"); ("I2","SEL");("O0","OUT") ] | Demux2 -> Map [ ("I0", "IN"); ("I1", "SEL"); ("O0","0");("O1","1") ] | NbitsXor _ -> Map [ ("I0", "P"); ("I1", "Q"); ("O0","Out") ] - // | Custom x -> (List.map fst x.InputLabels), (List.map fst x.OutputLabels) + | Custom x -> createCustomPortNamesMap x.InputLabels x.OutputLabels |_ -> Map.empty -// Input and Output names of the ports depending on their ComponentType -let portDecName (comp:Component) = //(input port names, output port names) - match comp.Type with - | Decode4 -> (["Sel";"Data"],["0"; "1";"2"; "3"]) - | NbitsAdder _ -> (["Cin";"A";"B"],["Sum "; "Cout"]) - | Register _ -> (["D"],["Q"]) - | RegisterE _ -> (["D"; "EN"],["Q"]) - | ROM1 _ |AsyncROM1 _ -> (["Addr"],["Dout"]) - | RAM1 _ -> (["Addr"; "Din";"Wen" ],["Dout"]) - | AsyncRAM1 _ -> (["Addr"; "Din";"Wen" ],["Dout"]) - | DFF -> (["D"],["Q"]) - | DFFE -> (["D";"EN"],["Q"]) - | Mux2 -> (["0"; "1";"SEL"],["OUT"]) - | Demux2 -> (["IN" ; "SEL"],["0"; "1"]) - | NbitsXor _ -> (["P"; "Q"], ["Out"]) - | Custom x -> (List.map fst x.InputLabels), (List.map fst x.OutputLabels) - |_ -> ([],[]) // |Mux4 -> (["0"; "1"; "2"; "3" ;"SEL"],["OUT"]) // |Demux4 -> (["IN"; "SEL"],["0"; "1";"2"; "3";]) // |Demux8 -> (["IN"; "SEL"],["0"; "1"; "2" ; "3" ; "4" ; "5" ; "6" ; "7"]) @@ -289,7 +282,7 @@ let createNewSymbol (pos: XYPos) (comptype: ComponentType) (label:string) = let comp = makeComp pos comptype id label { Pos = { X = pos.X - float comp.W / 2.0; Y = pos.Y - float comp.H / 2.0 } - STransform = 0; + STransform = R0; ShowInputPorts = false ShowOutputPorts = false InWidth0 = None // set by BusWire @@ -310,6 +303,8 @@ let addToPortModel (model: Model) (sym: Symbol) = let addedInputPorts = (model.Ports, sym.Compo.InputPorts) ||> List.fold addOnePort (addedInputPorts, sym.Compo.OutputPorts) ||> List.fold addOnePort + +//////////////////////KEEP ONLY SO THAT THE CODE COMPILES -> IT AFFECTS GV319'S CODE /////////////////////////////////// //-----------------------------------------GET PORT POSITION--------------------------------------------------- // Function that calculates the positions of the ports @@ -331,8 +326,7 @@ let getPortPos (comp: Component) (port:Port) = {X = posX; Y = posY} let getPortPosModel (model: Model) (port:Port) = getPortPos (Map.find (ComponentId port.HostId) model.Symbols).Compo port - - +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //-----------------------------------------DRAWING HELPERS --------------------------------------------------- // Text adding function with many parameters (such as bold, position and text) let private addText posX posY name txtPos weight size= @@ -340,38 +334,13 @@ let private addText posX posY name txtPos weight size= {defaultText with TextAnchor = txtPos; FontWeight = weight; FontSize = size} [makeText posX posY name text] -// Generate circles -let private portCircles x y = - [makeCircle x y portCircle] -// Define the name of each port -let private portText x y name portType = - let xPos = - if portType = PortType.Output - then x - 5. - else x + 5. - let test = if portType = PortType.Output then "end" else "start" - (addText xPos (y - 7.0) name test "normal" "12px") -// Print the name of each port -let private drawPortsText (portList: Port List) (listOfNames: string List) (comp: Component)= - if listOfNames.Length < 1 - then [] - else - [0..(portList.Length-1)] - |> List.map2 (fun name x -> (portText (getPortPos comp portList[x]).X (getPortPos comp portList[x]).Y name (portList.Head.PortType))) listOfNames - |> List.collect id - -// Function to draw ports using getPortPos. The ports are equidistant -let private drawPorts (portList: Port List) (printPorts:bool) (comp: Component)= - if (portList.Length) < 1 - then [] - else - if printPorts - then [0..(portList.Length-1)] |> List.collect (fun x -> (portCircles (getPortPos comp portList[x]).X (getPortPos comp portList[x]).Y)) - else [] - -/////// NEW FUNCTIONS FOR APORTOFFSET MAP ////// +/////// APORTOFFSET MAP HELPERS ////// let offsethelper (comp: Component) orientation (port:Port) = + let inline getPortPosEdgeGap (ct: ComponentType) = + match ct with + | MergeWires | SplitWire _ -> 0.25 + | _ -> 1.0 let (ports, posX) = if port.PortType = (PortType.Input) then (comp.InputPorts, 0.0) @@ -379,16 +348,11 @@ let offsethelper (comp: Component) orientation (port:Port) = (comp.OutputPorts, float( comp.W )) let index = float( List.findIndex (fun (p:Port) -> p = port) ports ) let gap = getPortPosEdgeGap comp.Type - let posY = (float(comp.H))* (( index + gap )/( float( ports.Length ) + 2.0*gap - 1.0)) // the ports are created so that they are equidistant - // let side original o = (original+o)%4 + let posY = (float(comp.H))* (( index + gap )/( float( ports.Length ) + 2.0*gap - 1.0)) // the ports are created so that they are equidistant {X=posX;Y=posY} - // match orientation with - // |0-> {Side=(side 2 orientation);Offset=posY} - // if posX = 0.0 then {Side=(side 2 orientation);Offset=posY} //needs to change side 0->1->2->3->0 - // else {Side=(side 0 orientation);Offset=posY} /////change name -let portListToMapN (portList: Port List) (symbol: Symbol) : Map= +let portListToMap (portList: Port List) (symbol: Symbol) : Map= let adder (symbol: Symbol) (port: Port) = let num = match port.PortNumber with |Some n -> n |_->(-1) let key = @@ -397,193 +361,137 @@ let portListToMapN (portList: Port List) (symbol: Symbol) : Map "O"+ string num let value = match port.PortType with - |PortType.Input -> {Side=2;Offset=offsethelper symbol.Compo symbol.STransform port} - |PortType.Output -> {Side=0;Offset=offsethelper symbol.Compo symbol.STransform port} + |PortType.Input -> {Side=Left;Offset=offsethelper symbol.Compo symbol.STransform port} + |PortType.Output -> {Side=Right;Offset=offsethelper symbol.Compo symbol.STransform port} [(key,value)] if (portList.Length) < 1 then [] |> Map.ofList else ( [0..(portList.Length-1)] |> List.collect (fun x -> (adder symbol portList[x])) ) |> Map.ofList -let genAPortOffsetsN(symbol: Symbol) : Map = - let inputList = symbol.Compo.InputPorts - let outputList = symbol.Compo.OutputPorts - let map1 = portListToMapN inputList symbol - let map2 = portListToMapN outputList symbol - Map.fold (fun acc key value -> Map.add key value acc) map1 map2 - - -let genAPortOffsetsMux (symbol: Symbol) = - let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0)) - let temp = [ ("I0", {Side=2;Offset={X=0.0;Y=(getPosY 0.0)}});("I1", {Side=2;Offset={X=0.0;Y=(getPosY 1.0)}});("I2", {Side=1;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.9}});("O0", {Side=0;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/2.0}})] - temp |> Map.ofList - -let genAPortOffsetsAdder (symbol: Symbol) = - let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0)) - let temp = [ ("I2", {Side=2;Offset={X=0.0;Y=(getPosY 1.0)}});("I1", {Side=2;Offset={X=0.0;Y=(getPosY 0.0)}});("I0", {Side=1;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)}});("O0", {Side=0;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}});("O1", {Side=3;Offset={X=float(symbol.Compo.W)-30.0;Y=0.0}})] - temp |> Map.ofList - let genAPortOffsets (symbol: Symbol) (cType: ComponentType) : Map = + //generator for MUX + let genAPortOffsetsMux (symbol: Symbol) = + let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0)) + let temp = [ ("I0", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}});("I2", {Side=Left;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.9}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/2.0}})] + temp |> Map.ofList + + //generator for NBitsAdder + let genAPortOffsetsAdder (symbol: Symbol) = + let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0)) + let temp = [ ("I2", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}});("I0", {Side=Bottom;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}});("O1", {Side=Top;Offset={X=float(symbol.Compo.W)-30.0;Y=0.0}})] + temp |> Map.ofList + + //generator for everything else + let genAPortOffsets' (symbol: Symbol) : Map = + let inputList = symbol.Compo.InputPorts + let outputList = symbol.Compo.OutputPorts + let map1 = portListToMap inputList symbol + let map2 = portListToMap outputList symbol + Map.fold (fun acc key value -> Map.add key value acc) map1 map2 + match cType with |Mux2 -> genAPortOffsetsMux symbol |NbitsAdder _ -> genAPortOffsetsAdder symbol - |_ -> genAPortOffsetsN symbol + |_ -> genAPortOffsets' symbol + let rotatePortMap (map:Map) (symbol:Symbol) = - map |> Map.map (fun key port -> - match port.Side with - |0 -> {Side=1;Offset={X=port.Offset.Y;Y=port.Offset.X}} - |1 -> {Side=2;Offset={X=0.0;Y=port.Offset.X}} - // |1 -> {Side=2;Offset={X=0.0;Y=port.Offset.X}} - |2 -> {Side=3;Offset={X=port.Offset.Y;Y=port.Offset.X}} - // |3 -> {Side=0;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}} - |3 -> {Side=0;Offset={X=float(symbol.Compo.W);Y=port.Offset.X}} - |_ -> {Side=0;Offset={X=port.Offset.X;Y=port.Offset.Y}} - ) //MUX + ADDER requires special treatment + let rotatePortMap' (map:Map) (symbol:Symbol) = + map |> Map.map (fun key port -> + match port.Side with + |Right -> {Side=Bottom;Offset={X=port.Offset.Y;Y=port.Offset.X}} + |Bottom -> {Side=Left;Offset={X=0.0;Y=port.Offset.X}} + |Left -> {Side=Top;Offset={X=port.Offset.Y;Y=port.Offset.X}} + |Top -> {Side=Right;Offset={X=float(symbol.Compo.W);Y=port.Offset.X}} + ) //MUX + ADDER requires special treatment + + match symbol.Compo.Type with + |MergeWires |SplitWire _ |Mux2 |NbitsAdder _ -> map + |_ -> rotatePortMap' map symbol -// OLD IMPLEMENTATION -> NOT WORKING -> keep for readme.md +////////////////////// OLD IMPLEMENTATION -> NOT WORKING -> keep for readme.md let rotatePortMapOLD (map:Map) (symbol:Symbol) = let h,w = match symbol.STransform with - |0|2 -> symbol.Compo.H, symbol.Compo.W - |1|3 -> symbol.Compo.W, symbol.Compo.H - |_ -> symbol.Compo.H, symbol.Compo.W + |R0|R180 -> symbol.Compo.H, symbol.Compo.W + |R90|R270 -> symbol.Compo.W, symbol.Compo.H map |> Map.map (fun key port -> match port.Side with - |0 -> {Side=1;Offset={X=port.Offset.Y;Y=port.Offset.X}} + |Right -> {Side=Bottom;Offset={X=port.Offset.Y;Y=port.Offset.X}} // |1 -> {Side=2;Offset={X=0.0;Y=port.Offset.X}} - |1 -> {Side=2;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}} - |2 -> {Side=3;Offset={X=port.Offset.Y;Y=port.Offset.X}} - |3 -> {Side=0;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}} + |Bottom -> {Side=Left;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}} + |Left -> {Side=Top;Offset={X=port.Offset.Y;Y=port.Offset.X}} + |Top -> {Side=Right;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}} // |3 -> {Side=0;Offset={X=float(symbol.Compo.W);Y=port.Offset.X}} - |_ -> {Side=0;Offset={X=port.Offset.X;Y=port.Offset.Y}} ) //mux requires special treatment - - - -// let newDrawPorts (portMap: Map) showInput (symbol: Symbol) = -// if Map.isEmpty portMap then [] -// else if showInput then -// let mid = portMap |> Map.map (fun k {Side=orientation;Offset=offset} -> -// match orientation with -// |0 -> makeCircle symbol.Compo.W offset portCircle -// |2 -> makeCircle 0.0 offset portCircle -// |_ -> makeCircle 0.0 offset portCircle //to change -// ) -// mid |> Map.values |> List.ofSeq -// else [] - -// let newD {Side = orientation; Offset = offset} (symbol:Symbol) o= -// match (orientation+o)%4 with -// |0 -> makeCircle offset.X offset.Y portCircle -// |1 -> makeCircle offset.X offset.Y portCircle -// |2 -> makeCircle 0.0 offset.Y portCircle -// |3 -> makeCircle offset.Y 0.0 portCircle -// |_ -> makeCircle 0.0 offset.Y portCircle //to change - -// let newDrawPorts (portMap: Map) o (showInput:bool) (showOutput:bool) (symbol: Symbol) : ReactElement List= -// if Map.isEmpty portMap then [] -// else -// let mid = portMap |> Map.map (fun key port -> -// match key[0] with -// |'I' -> if showInput then (newD port symbol o) else nothing -// |'O' -> if showOutput then (newD port symbol o) else nothing -// |_ -> nothing -// ) -// mid |> Map.values |> List.ofSeq - - +////////////////////////////////////////////////////////// let newDrawPorts (portMap: Map) o (showInput:bool) (showOutput:bool) (symbol: Symbol) : ReactElement List= if Map.isEmpty portMap then [] else - portMap |> Map.map (fun key port -> + let mid = portMap |> Map.map (fun key port -> match key,port with |k,{Side=side;Offset={X=x;Y=y}} -> if (k[0] = 'I' && showInput) || (k[0]='O' && showOutput) then makeCircle x y portCircle else nothing - ) |> Map.toList |> List.map snd + ) + mid |> Map.toList |> List.map snd -let private newaddText posX posY name txtPos weight size= - let text = - {defaultText with TextAnchor = txtPos; FontWeight = weight; FontSize = size} - makeText posX posY name text -let newDT {Side = side; Offset = offset} name (symbol:Symbol) o = - // let test = if symbol.Compo.portType = PortType.Output then "end" else "start" - // let text = {defaultText with TextAnchor = txtPos; FontWeight = weight; FontSize = size} - // [makeText posX posY name text] - match side with - |0-> newaddText (offset.X-5.0) (offset.Y-7.0) name "end" "normal" "12px" - |1 -> newaddText (offset.X) (offset.Y-20.0) name "Middle" "normal" "12px" - |2-> newaddText (offset.X+5.0) (offset.Y-7.0) name "start" "normal" "12px" - |3 -> newaddText (offset.X) (offset.Y+7.0) name "Middle" "normal" "12px" - |_ -> nothing - -////CONTINUE WITH TEXT -let newDrawPortsText (portMap:Map) (comp: Component) symbol orientation : ReactElement List = - let namesM = portDecNameM comp +let newDrawPortsText (portMap:Map) (comp: Component) symbol orientation = + let namesM = portNameMap comp if (Map.isEmpty portMap || Map.isEmpty namesM) then [] else let inline charToInt c = int c - int '0' let mid = portMap |> Map.map (fun key port -> - newDT port namesM[key] symbol orientation - // match key[0] with - // |'I' -> newDT port namesM[key] symbol orientation - // |'O' -> newDT port namesO[0] symbol orientation - // |_-> nothing - ) + let name = namesM[key] + match port.Side with + |Right-> (addText (port.Offset.X-5.0) (port.Offset.Y-7.0) name "end" "normal" "12px")[0] //[0] to extract react element from list + |Bottom -> (addText (port.Offset.X) (port.Offset.Y-20.0) name "Middle" "normal" "12px")[0] //they are added in a list at the end + |Left-> (addText (port.Offset.X+5.0) (port.Offset.Y-7.0) name "start" "normal" "12px")[0] + |Top -> (addText (port.Offset.X) (port.Offset.Y+7.0) name "Middle" "normal" "12px")[0] ) mid |> Map.toList |> List.map snd - -// [0..(portList.Length-1)] -// |> List.map2 (fun name x -> (portText (getPortPos comp portList[x]).X (getPortPos comp portList[x]).Y name (portList.Head.PortType))) listOfNames -// |> List.collect id //------------------------------HELPER FUNCTIONS FOR DRAWING SYMBOLS------------------------------------- -let rotate90 points = - match points with - |[x1;y1;x2;y2;x3;y3;x4;y4] -> [y1;x1;y2;x2;y3;x3;y4;x4] - |[x1;y1;x2;y2;x3;y3] -> [y1;x1;y2;x2;y3;x3] - |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y1;x1;y5;x5;y4;x4;y3;x3;y2;x2] - |_->points - //TO ADD OTHER SYMBOLS AS WELL +let rotatePoints points rotation = + let rotate90 points = + match points with + |[x1;y1;x2;y2;x3;y3;x4;y4] -> [y1;x1;y2;x2;y3;x3;y4;x4] + |[x1;y1;x2;y2;x3;y3] -> [y1;x1;y2;x2;y3;x3] + |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y1;x1;y5;x5;y4;x4;y3;x3;y2;x2] + |_->points + //TO ADD OTHER SYMBOLS AS WELL -let rotate180 points = - match points with - |[x1;y1;x2;y2;x3;y3;x4;y4] -> [x1;y2;x2;y1;x3;y4;x4;y3] - // |[x1;y1;x2;y2;x3;y3] -> [x1;y2;x2;y1;x2;y3] - |[x1;y1;x2;y2;x3;y3] -> [x2+x2;y1;x1+x2;y2;x2+x2;y3] - |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[x3-x2;y1;x3;y2;x3;y4;x3-x2;y5;x1;y3] //input,output - |_->points - //TO ADD OTHER SYMBOLS AS WELL + let rotate180 points = + match points with + |[x1;y1;x2;y2;x3;y3;x4;y4] -> [x1;y2;x2;y1;x3;y4;x4;y3] + |[x1;y1;x2;y2;x3;y3] -> [x2+x2;y1;x1+x2;y2;x2+x2;y3] + |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[x3-x2;y1;x3;y2;x3;y4;x3-x2;y5;x1;y3] //input,output + |_->points + //TO ADD OTHER SYMBOLS AS WELL -let rotate270 points = - match points with - |[x1;y1;x2;y2;x3;y3;x4;y4] -> [y2;x1;y3;x4;y4;x3;y1;x2] - |[x1;y1;x2;y2;x3;y3] -> [x2/2.0;y3;x2;y3+y3;x1;y3+y3] - // |[x1;y1;x2;y2;x3;y3] -> [x2+x2;y1;x1+x2;y2;x2+x2;y3] - |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y3;0.0;y5;x3-x2;y4;x3;y1;x3;y2;x3-x2] //input,output - |_->points - //TO ADD OTHER SYMBOLS AS WELL - - -let rotate points rotation = + let rotate270 points = + match points with + |[x1;y1;x2;y2;x3;y3;x4;y4] -> [y2;x1;y3;x4;y4;x3;y1;x2] + |[x1;y1;x2;y2;x3;y3] -> [x2/2.0;y3;x2;y3+y3;x1;y3+y3] + |[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y3;0.0;y5;x3-x2;y4;x3;y1;x3;y2;x3-x2] //input,output + |_->points + //TO ADD OTHER SYMBOLS AS WELL + match rotation with - |0 -> points - |1 -> rotate90 points - |2 -> rotate180 points - |3 -> rotate270 points - |_ -> points + |R0 -> points + |R90 -> rotate90 points + |R180 -> rotate180 points + |R270 -> rotate270 points - -let getPointsString coordList rotation = - let rotatedPoints = rotate coordList rotation +let getPointsString coordList = let rec combine lst = match lst with | fst::snd::tl -> (fst.ToString()+",") :: (snd.ToString()+" ") :: (combine tl) |[_] -> [] |[] -> [] - combine rotatedPoints |> String.concat "" + combine coordList |> String.concat "" let private createPolygon points colour opacity = @@ -595,32 +503,40 @@ let createBiColorPolygon points colour strokeColor opacity strokeWidth= else [makePolygon points {defaultPolygon with Fill = colour; FillOpacity = opacity; StrokeWidth = strokeWidth}] -let addInvertor points rotation colour opacity = - // let symbolpoints = (sprintf "%i,%i %i,%i %i,%i" posX (posY) (posX+9) (posY) posX (posY-8)) - let getLine points rotation = - match rotation with - |0-> (match points with [x1;y1;x2;y2;x3;y3;x4;y4] -> [x3;y3/2.0;(x3+9.0);y3/2.0;x3;(y3/2.0)-8.0] |[_]->[]|[]->[]) - |1-> (match points with [x1;y1;x2;y2;x3;y3;x4;y4] -> [x3/2.0;y3;x3/2.0;y3+9.0;(x3/2.0)+8.0;y3] |[_]->[]|[]->[]) - // |2 ->(match points with [x1;y1;x2;y2;x3;y3;x4;y4] -> [0.0;y2;x2;y2] |[_]->[]|[]->[]) - |_ -> failwithf"Not implemented" - let linepoints = getLine points rotation - createPolygon (getPointsString linepoints 0) colour opacity let addClock posX posY colour opacity = let points = (sprintf "%i,%i %i,%i %i,%i" posX (posY-1) (posX+8) (posY-7) posX (posY-13)) createPolygon points colour opacity |> List.append (addText (float(posX+10)) (float(posY-13)) " clk" "start" "normal" "12px") -let addConstantLine points rotation opacity = - let getLine points rotation = - match rotation with - |0-> (match points with [x1;y1;x2;y2;x3;y3] -> [x2;y2;x2*2.0;y2] |[_]->[]|[]->[]) - |1-> (match points with [x1;y1;x2;y2;x3;y3] -> [x2;y2;x2;y2*2.0] |[_]->[]|[]->[]) - |2 ->(match points with [x1;y1;x2;y2;x3;y3] -> [0.0;y2;x2;y2] |[_]->[]|[]->[]) - |_ -> failwithf"Not implemented" - let linepoints = getLine points rotation - createPolygon (getPointsString linepoints 0) "lightgray" opacity +let addInvertorNew w h rotation colour opacity = + // let points = (sprintf "%i,%i %i,%i %i,%i" posX (posY) (posX+9) (posY) posX (posY-8)) + // let w,h = float(width),float(height) + let points = + match rotation with + |R0 -> [w;h/2.0;w+9.0;h/2.0;w;h/2.0-8.0] + |R90 -> [w/2.0;h;w/2.0;h+9.0;w/2.0+8.0;h] + |R180 -> [0.0;h/2.0;(-9.0);h/2.0;0.0;h/2.0+8.0] + |R270 -> [w/2.0;0.0;w/2.0;(-9.0);w/2.0-8.0;0.0] + createPolygon (getPointsString points) colour opacity + +let addConstantLineNew w h rotation opacity = + // let points = (sprintf "%i,%f %i,%f" posX1 posY posX2 posY) + let points = + match rotation with + |R0 -> [w/2.0;h/2.0;w;h/2.0] + |R90 -> [w/2.0;h/2.0;w/2.0;h] + |R180 -> [w/2.0;h/2.0;0.0;h/2.0] + |R270 -> [w/2.0;h/2.0;w/2.0;0.0] + createPolygon (getPointsString points) "lightgray" opacity + +let drawGateType w h comp = + let gType = gateDecoderType comp + let posX,posY = + match comp.Type with + |_ -> (w/2.0), (h/2.0 - 7.0) + addText posX posY gType "middle" "bold" "14px" let outlineColor (color:string) = match color.ToLower() with @@ -635,227 +551,115 @@ let addHorizontalColorLine posX1 posX2 posY opacity (color:string) = // TODO: Li [makePolygon points {defaultPolygon with Fill = "olcolor"; Stroke=olColor; StrokeWidth = "2.0"; FillOpacity = opacity}] -let drawLabel label width height orientation = - match orientation with - |0 -> addText (width/2.0) (-20.0) (label) "middle" "normal" "16px" - |1 -> addText (width+5.0) (height/2.0 - 8.0) label "Start" "normal" "16px" - |2 -> addText (width/2.0) (height+10.0) (label) "middle" "normal" "16px" - |3 -> addText (-5.0) (height/2.0 - 8.0) label "End" "normal" "16px" - |_ -> addText (width/2.0) (-20.0) (label) "middle" "normal" "16px" +let drawLabel label width height rotation = + match rotation with + |R0 -> addText (width/2.0) (-20.0) (label) "middle" "normal" "16px" + |R90 -> addText (width+5.0) (height/2.0 - 8.0) label "Start" "normal" "16px" + |R180 -> addText (width/2.0) (height+10.0) (label) "middle" "normal" "16px" + |R270 -> addText (-5.0) (height/2.0 - 8.0) label "End" "normal" "16px" + + /// --------------------------------------- SYMBOL DRAWING ------------------------------------------------------ /// -let drawInput (comp:Component) x h w o colour opacity showInput showOutput symbol= - let points = rotate [0.0; 0.0; (float(w)*(0.66)); 0.0; float(w); float(h)/2.0; (float(w)*(0.66)); float(h); 0.0; float(h)] (o) - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (addText (float(wR/2)) ((float(hR)/3.0)) (title "" x) "middle" "normal" "12px") - // |> List.append (drawPorts comp.OutputPorts showOutput comp) - |> List.append (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) - // |> List.append (addText (float (wR/2)) (-20.0) (comp.Label) "middle" "normal" "16px") - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - - -let drawMux (comp:Component) h w o colour opacity showInput showOutput symbol= - let points = rotate [0.0; 0.0; float(w); (float(h)*0.2); float(w); (float(h)*0.8); 0.0; float(h)] (o) - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - // (drawPorts comp.InputPorts showInput comp) - // |> List.append (drawPorts comp.OutputPorts showOutput comp) - - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) //need symbol.APortOffsetMap instead of temp -> need to create APortOffsetMap when I create the symbol, Now it assigns an empty table - - // |> List.append (drawPortsText comp.InputPorts (fst(portDecName comp)) comp) - // |> List.append (drawPortsText comp.OutputPorts (snd(portDecName comp)) comp) - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - // |> List.append (addText (float (wR/2)) (-20.0) (comp.Label) "middle" "normal" "16px") - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - -let drawDemux (comp:Component) h w o colour opacity showInput showOutput symbol= - let points = rotate [0.0; (float(h)*0.2); float(w); 0.0; float(w); float(h); 0.0; (float(h)*0.8)] (o) - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) //need symbol.APortOffsetMap instead of temp -> need to create APortOffsetMap when I create the symbol, Now it assigns an empty table - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - // |> List.append (addText (float (wR/2)) (-20.0) (comp.Label) "middle" "normal" "16px") - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - - -let drawBasic (comp:Component) h w o colour opacity showInput showOutput symbol = - //need to make xorN larger giati den xwraei to gateDecoderType (OR-> allagi sto name -> make smaller) - let points = rotate [0.0; 0.0; float(w); 0.0; float(w); float(h); 0.0; float(h)] o - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - // |> List.append (addText (float (wR/2)) (-20.0) (comp.Label) "middle" "normal" "16px") - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (addText (float(wR)/2.0) (float(hR)/2.0 - 7.0) (gateDecoderType comp) "middle" "bold" "14px") - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - -let addInvertorNew w h rotation colour opacity = - // let points = (sprintf "%i,%i %i,%i %i,%i" posX (posY) (posX+9) (posY) posX (posY-8)) - // let w,h = float(width),float(height) - let points = - match rotation with - |0 -> [w;h/2.0;w+9.0;h/2.0;w;h/2.0-8.0] - |1 -> [w/2.0;h;w/2.0;h+9.0;w/2.0+8.0;h] - |2 -> [0.0;h/2.0;(-9.0);h/2.0;0.0;h/2.0+8.0] - |3 -> [w/2.0;0.0;w/2.0;(-9.0);w/2.0-8.0;0.0] - |_ -> [] - createPolygon (getPointsString points 0) colour opacity - -let addConstantLineNew w h rotation opacity = - // let points = (sprintf "%i,%f %i,%f" posX1 posY posX2 posY) - let points = - match rotation with - |0 -> [w/2.0;h/2.0;w;h/2.0] - |1 -> [w/2.0;h/2.0;w/2.0;h] - |2 -> [w/2.0;h/2.0;0.0;h/2.0] - |3 -> [w/2.0;h/2.0;w/2.0;0.0] - |_-> [] - createPolygon (getPointsString points 0) "lightgray" opacity - -let drawBasicInverted (comp:Component) h w o colour opacity showInput showOutput symbol = - //need to make xorN larger giati den xwraei to gateDecoderType (OR-> allagi sto name -> make smaller) - let points = rotate [0.0; 0.0; float(w); 0.0; float(w); float(h); 0.0; float(h)] o - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - |> List.append (addInvertorNew (float(wR)) (float(hR)) o colour opacity) - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (addText (float(wR)/2.0) (float(hR)/2.0 - 7.0) (gateDecoderType comp) "middle" "bold" "14px") - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - -let drawViewer (comp:Component) x h w o colour opacity showInput showOutput symbol= - let points = rotate [(float(w))*(0.2); 0.0; 0.0; float(h)/2.0; float(w)*(0.2); float(h); float(w); float(h); float(w); 0.0] 0 - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (addText (float(w/2)) ((float(h)/2.7)-1.25) (title "" x) "middle" "normal" "9px") - // |> List.append (drawPorts comp.OutputPorts showOutput comp) - |> List.append (newDrawPorts symbol.APortOffsetsMap 0 showInput showOutput symbol) - // |> List.append (addText (float (wR/2)) (-20.0) (comp.Label) "middle" "normal" "16px") - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) 0) - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - -let drawBus (comp:Component) h w o colour opacity showInput showOutput symbol = - let points = rotate [0.0; 0.0; 0.0; float(h); (0.6*(float(w))); float(h); (0.8*(float(w))); (0.7*(float(h))); float(w); (0.7*(float(h))); float(w); (0.3*(float(h))); (0.8*(float(w))); (0.3*(float(h))); (0.6*(float(w))); 0.0] o - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (addText (float(wR)/2.0) (float(hR)/2.0 - 7.0) (gateDecoderType comp) "middle" "bold" "14px") - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - -let drawConstant (comp:Component) txt h w o colour opacity showInput showOutput symbol = - let points = rotate [0.0; 0.0; float(w)/2.0; float(h)/2.0; 0.0; float(h)] o - let hR,wR = match o with |1|3 -> w,h |_ -> h,w - (newDrawPorts symbol.APortOffsetsMap o showInput showOutput symbol) - |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol o) - |> List.append (addConstantLineNew (float(wR)) (float(hR)) o opacity) - |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) o) - |> List.append (addText (float (float(w)/2.0)-5.0) (float(h)-8.0) txt "middle" "normal" "12px") - |> List.append (addText (float(wR)/2.0) (float(hR)/2.0 - 7.0) (gateDecoderType comp) "middle" "bold" "14px") - |> List.append (createBiColorPolygon (getPointsString points 0) colour "black" opacity "1.0") - - let compSymbol (symbol:Symbol) (comp:Component) (colour:string) (showInputPorts:bool) (showOutputPorts:bool) (opacity: float)= - match comp.Type with - | Input (x) -> drawInput comp x comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | Output (x) -> drawInput comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol - | Mux2 -> drawMux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | Demux2 -> drawDemux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | Viewer (x) -> drawViewer comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol - | Decode4 | NbitsXor _ | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | And | Or |Xor -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | Nand | Nor | Not | Xnor -> drawBasicInverted comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - | BusSelection _ |BusCompare _ -> drawBus comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - |Constant1 (_,_,txt) -> drawConstant comp txt comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol - |_ -> [] + // match comp.Type with + // | Input (x) -> drawInput comp x comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | Output (x) -> drawInput comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol + // | Mux2 -> drawMux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | Demux2 -> drawDemux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | Viewer (x) -> drawViewer comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol + // | Decode4 | NbitsXor _ | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | And | Or |Xor -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | Nand | Nor | Not | Xnor -> drawBasicInverted comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // | BusSelection _ |BusCompare _ -> drawBus comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // |Constant1 (_,_,txt) -> drawConstant comp txt comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol + // |_ -> [] // | _ -> [] // | _ -> [] - // let h = (comp.H) - // let w = (comp.W) - // let halfW = (comp.W/2) - // let halfH = (comp.H/2) - // let hF = float(comp.H) //float representation of height - // let wF = float(comp.W) //float representation of width - // let halfWF = float(comp.W/2) //float representation of halfWidth - // let halfHF = float(comp.H/2) //float representation of halfHeight + let h = (comp.H) + let w = (comp.W) + let halfW = (comp.W/2) + let halfH = (comp.H/2) + + let hF = float(comp.H) //float representation of height + let wF = float(comp.W) //float representation of width + let halfWF = float(comp.W/2) //float representation of halfWidth + let halfHF = float(comp.H/2) //float representation of halfHeight - // let rotation = symbol.STransform+1 + let rotation = symbol.STransform - // let mergeSplitLine posX1 posX2 posY msb lsb = - // let text = - // match msb = lsb, msb >= lsb with - // | _, false -> "" - // | true, _ -> sprintf $"({msb})" - // | false, _ -> sprintf $"({msb}:{lsb})" - // addHorizontalColorLine posX1 posX2 (posY*float(h)) opacity colour @ - // addText (float (posX1 + posX2)/2.0) (posY*float(h)-11.0) text "middle" "bold" "9px" + let hR,wR = match symbol.STransform with |R90|R270 -> w,h |_ -> h,w + + let mergeSplitLine posX1 posX2 posY msb lsb = + let text = + match msb = lsb, msb >= lsb with + | _, false -> "" + | true, _ -> sprintf $"({msb})" + | false, _ -> sprintf $"({msb}:{lsb})" + addHorizontalColorLine posX1 posX2 (posY*float(h)) opacity colour @ + addText (float (posX1 + posX2)/2.0) (posY*float(h)-11.0) text "middle" "bold" "9px" - // let points = // Points that specify each symbol - // match comp.Type with - // | Input _ -> [0.0; 0.0; (wF*(0.66)); 0.0; wF; halfHF; (wF*(0.66)); hF; 0.0; hF] - // | Constant1 _ -> [0.0; 0.0; halfWF; halfHF; 0.0; hF] - // | IOLabel -> [(wF)*(0.33); 0.0; 0.0; halfHF; ((wF)*(0.33)); hF; ((wF)*(0.66)); hF; wF; halfHF; (wF*(0.66)); 0.0] - // | Output _ -> [(wF)*(0.2); 0.0; 0.0; halfHF; (wF)*(0.2); hF; wF; hF; wF; 0.0] - // | Viewer _ -> [(wF)*(0.2); 0.0; 0.0; halfHF; (wF)*(0.2); hF; wF; hF; wF; 0.0] - // | MergeWires -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF))] - // | SplitWire _ -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF)); 0.0] - // | Demux2 -> [0.0; (hF*0.2); 0.0; (hF*0.8); wF; hF; wF; 0.0] - // | Mux2 -> [0.0; 0.0; wF; (hF*0.2); wF; ((hF)*0.8); 0.0; hF] - // // // EXTENSION: |Mux4|Mux8 ->(sprintf "%i,%i %i,%f %i,%f %i,%i" 0 0 w (float(h)*0.2) w (float(h)*0.8) 0 h ) - // // // EXTENSION: | Demux4 |Demux8 -> (sprintf "%i,%f %i,%f %i,%i %i,%i" 0 (float(h)*0.2) 0 (float(h)*0.8) w h w 0) - // | BusSelection _ |BusCompare _ -> [0.0; 0.0; 0.0; hF; (0.6*(wF)); hF; (0.8*(wF)); (0.7*(hF)); wF; (0.7*(hF)); wF; (0.3*(hF)); (0.8*(wF)); (0.3*(hF)); (0.6*(wF)); 0.0] - // | _ -> [0.0; 0.0; wF; 0.0; wF; hF; 0.0; hF] - // let additions = // Helper function to add certain characteristics on specific symbols (inverter, enables, clocks) - // match comp.Type with - // | Constant1 (_,_,txt) -> (addConstantLine (rotate points rotation) rotation opacity @ addText (float (halfW)-5.0) (float(h)-8.0) txt "middle" "normal" "12px") - // | Nand | Nor | Xnor |Not -> (addInvertor (rotate points rotation) rotation colour opacity) - // | MergeWires -> - // let lo, hi = - // match symbol.InWidth0, symbol.InWidth1 with - // | Some n, Some m -> n, m - // | _ -> -1,-1 - // let msb = hi + lo - 1 - // let midb = lo - // let midt = lo - 1 - // mergeSplitLine 0 halfW (1.0/6.0) midt 0 @ - // mergeSplitLine 0 halfW (5.0/6.0) msb midb @ - // mergeSplitLine halfW w 0.5 msb 0 - // | SplitWire mid -> - // let msb, mid' = match symbol.InWidth0 with | Some n -> n - 1, mid | _ -> -100, -50 - // let midb = mid' - // let midt = mid'-1 - // mergeSplitLine halfW w (1.0/6.0) midt 0 @ - // mergeSplitLine halfW w (5.0/6.0) msb midb @ - // mergeSplitLine 0 halfW 0.5 msb 0 - // | DFF |DFFE -> (addClock 0 h colour opacity) - // | Register _ |RegisterE _ -> (addClock 0 h colour opacity) - // | ROM1 _ |RAM1 _ | AsyncRAM1 _ -> (addClock 0 h colour opacity) - // | BusSelection(x,y) -> (addText (float(w/2)-5.0) ((float(h)/2.7)-2.0) (bustitle x y) "middle" "normal" "12px") - // | BusCompare (_,y) -> (addText (float(w/2)-6.0) (float(h)/2.7-1.0) ("=" + NumberHelpers.hex(int y)) "middle" "bold" "10px") - // | Input (x) -> (addText (float(w/2)-5.0) ((float(h)/2.7)-3.0) (title "" x) "middle" "normal" "12px") - // | Output (x) -> (addText (float(w/2)) ((float(h)/2.7)-3.0) (title "" x) "middle" "normal" "12px") - // | Viewer (x) -> (addText (float(w/2)) ((float(h)/2.7)-1.25) (title "" x) "middle" "normal" "9px") - // | _ -> [] + let points = // Points that specify each symbol + match comp.Type with + | Input _ -> rotatePoints [0.0; 0.0; (float(w)*(0.66)); 0.0; float(w); float(h)/2.0; (float(w)*(0.66)); float(h); 0.0; float(h)] rotation + | Constant1 _ -> rotatePoints [0.0; 0.0; float(w)/2.0; float(h)/2.0; 0.0; float(h)] rotation + | IOLabel -> rotatePoints [float(w)*(0.33); 0.0; 0.0; float(h)/2.0; (float(w)*(0.33)); float(h); (float(w)*(0.66)); float(h); float(w); float(h)/2.0; (float(w)*(0.66)); 0.0] rotation + | Output _ -> rotatePoints [0.0; 0.0; (float(w)*(0.66)); 0.0; float(w); float(h)/2.0; (float(w)*(0.66)); float(h); 0.0; float(h)] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work + | Viewer _ -> rotatePoints [0.0; 0.0; (float(w)*(0.8)); 0.0; float(w); float(h)/2.0; (float(w)*(0.8)); float(h); 0.0; float(h)] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work + | MergeWires -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF))] + | SplitWire _ -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF)); 0.0] + | Demux2 -> rotatePoints [0.0; (float(h)*0.2); float(w); 0.0; float(w); float(h); 0.0; (float(h)*0.8)] rotation + | Mux2 -> rotatePoints [0.0; 0.0; float(w); (float(h)*0.2); float(w); (float(h)*0.8); 0.0; float(h)] rotation + // EXTENSION: |Mux4|Mux8 ->(sprintf "%i,%i %i,%f %i,%f %i,%i" 0 0 w (float(h)*0.2) w (float(h)*0.8) 0 h ) + // EXTENSION: | Demux4 |Demux8 -> (sprintf "%i,%f %i,%f %i,%i %i,%i" 0 (float(h)*0.2) 0 (float(h)*0.8) w h w 0) + | BusSelection _ |BusCompare _ -> rotatePoints [0.0; 0.0; 0.0; float(h); (0.6*(float(w))); float(h); (0.8*(float(w))); (0.7*(float(h))); float(w); (0.7*(float(h))); float(w); (0.3*(float(h))); (0.8*(float(w))); (0.3*(float(h))); (0.6*(float(w))); 0.0] rotation + | _ -> rotatePoints [0.0; 0.0; float(w); 0.0; float(w); float(h); 0.0; float(h)] rotation + let additions = // Helper function to add certain characteristics on specific symbols (inverter, enables, clocks) + match comp.Type with + | Constant1 (_,_,txt) -> (addConstantLineNew (float(wR)) (float(hR)) rotation opacity @ addText (float (float(w)/2.0)-5.0) (float(h)-8.0) txt "middle" "normal" "12px") + | Nand | Nor | Xnor |Not -> (addInvertorNew (float(wR)) (float(hR)) rotation colour opacity) + | MergeWires -> + let lo, hi = + match symbol.InWidth0, symbol.InWidth1 with + | Some n, Some m -> n, m + | _ -> -1,-1 + let msb = hi + lo - 1 + let midb = lo + let midt = lo - 1 + mergeSplitLine 0 halfW (1.0/6.0) midt 0 @ + mergeSplitLine 0 halfW (5.0/6.0) msb midb @ + mergeSplitLine halfW w 0.5 msb 0 + | SplitWire mid -> + let msb, mid' = match symbol.InWidth0 with | Some n -> n - 1, mid | _ -> -100, -50 + let midb = mid' + let midt = mid'-1 + mergeSplitLine halfW w (1.0/6.0) midt 0 @ + mergeSplitLine halfW w (5.0/6.0) msb midb @ + mergeSplitLine 0 halfW 0.5 msb 0 + | DFF |DFFE -> (addClock 0 h colour opacity) + | Register _ |RegisterE _ -> (addClock 0 h colour opacity) + | ROM1 _ |RAM1 _ | AsyncRAM1 _ -> (addClock 0 h colour opacity) + | BusSelection(x,y) -> (addText (float(wR/2)-5.0) ((float(hR)/2.7)-2.0) (bustitle x y) "middle" "normal" "12px") + | BusCompare (_,y) -> (addText (float(wR/2)-6.0) (float(hR)/2.7-1.0) ("=" + NumberHelpers.hex(int y)) "middle" "bold" "10px") + | Input (x) -> (addText (float(wR/2)) ((float(hR)/3.0)) (title "" x) "middle" "normal" "12px") + | Output (x) -> (addText (float(wR/2)) ((float(hR)/3.0)) (title "" x) "middle" "normal" "12px") + | Viewer (x) -> (addText (float(w/2)) ((float(h)/2.7)-1.25) (title "" x) "middle" "normal" "9px") + | _ -> [] - // let olColour, strokeWidth = - // match comp.Type with - // | SplitWire _ | MergeWires -> outlineColor colour, "2.0" - // | _ -> "black", "1.0" + let olColour, strokeWidth = + match comp.Type with + | SplitWire _ | MergeWires -> outlineColor colour, "2.0" + | _ -> "black", "1.0" - // // Put everything together - - // (drawPorts comp.OutputPorts showOutputPorts comp) - // |> List.append (drawPorts comp.InputPorts showInputPorts comp) - // |> List.append (drawPortsText comp.InputPorts (fst(portDecName comp)) comp) - // |> List.append (drawPortsText comp.OutputPorts (snd(portDecName comp)) comp) - // |> List.append (addText (float halfW) (+5.0) (gateDecoderType comp) "middle" "bold" "14px") - // |> List.append (addText (float halfW) (-20.0) comp.Label "middle" "normal" "16px") - // |> List.append (additions) - // |> List.append (createBiColorPolygon (getPointsString points rotation) colour olColour opacity strokeWidth) + // Put everything together + (newDrawPorts symbol.APortOffsetsMap symbol.STransform showInputPorts showOutputPorts symbol) + |> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol symbol.STransform) + |> List.append (drawGateType (float(wR)) (float(hR)) comp) + |> List.append (additions) + |> List.append (drawLabel comp.Label (float(wR)) (float(hR)) symbol.STransform) + |> List.append (createBiColorPolygon (getPointsString points) colour olColour opacity "1.0") let init () = { Symbols = Map.empty; CopiedSymbols = Map.empty; Ports = Map.empty ; InputPortsConnected= Set.empty ; OutputPortsConnected = Map.empty}, Cmd.none @@ -909,13 +713,13 @@ let view (model : Model) (dispatch : Msg -> unit) = |> ofList |> TimeHelpers.instrumentInterval "SymbolView" start + //------------------------GET BOUNDING BOXES FUNCS--------------------------------used by sheet. // Function that returns the bounding box of a symbol. It is defined by the height and the width as well as the x,y position of the symbol let getBoundingBoxofSymbol (sym:Symbol): BoundingBox = match sym.STransform with - | 0 | 2 -> {X = float(sym.Pos.X) ; Y = float(sym.Pos.Y) ; H = float(sym.Compo.H) ; W = float(sym.Compo.W)} - | 1 | 3 -> {X = float(sym.Pos.X) ; Y = float(sym.Pos.Y) ; H = float(sym.Compo.W) ; W = float(sym.Compo.H)} - | _ -> failwithf"STransform value not implemented" + | R0 | R180 -> {X = float(sym.Pos.X) ; Y = float(sym.Pos.Y) ; H = float(sym.Compo.H) ; W = float(sym.Compo.W)} + | R90 | R270 -> {X = float(sym.Pos.X) ; Y = float(sym.Pos.Y) ; H = float(sym.Compo.W) ; W = float(sym.Compo.H)} let getBoundingBoxes (symModel: Model): Map = Map.map (fun sId (sym:Symbol) -> (getBoundingBoxofSymbol sym)) symModel.Symbols @@ -930,9 +734,8 @@ let getSymbolPos (symbolModel: Model) compId = symbol.Pos // Function to generate Port Positions of each port from Symbol Location and Orientation -//currentSymbol.Pos is the upper left side corner // Input: Symbol -> Take the symbol for which to extract positions of ports -// Output: XYPos list-> Return a list of XYPos positions of the ports starting from inputs, anticlockwise. +// Output: XYPos list -> Return a list of XYPos positions of the ports starting from inputs, anticlockwise. let canvasPortLocation (sym:Symbol) : XYPos list = sym.APortOffsetsMap |> Map.toList @@ -940,7 +743,9 @@ let canvasPortLocation (sym:Symbol) : XYPos list = |> List.map (fun prevCoor -> prevCoor.Offset) |> List.map (fun i -> {X=i.X+sym.Pos.X;Y=i.Y + sym.Pos.Y}) - +// Function to generate the true XYPos of a specified Port on the Canvas given the port and symbol +// Input: Symbol, Port -> Take the symbol and the specified port +// Output: XYPos-> Return the XYPos position of the ports depending on being inputs or outputs let getGlobalPortPos (sym: Symbol) (port:Port) :XYPos = let (typePort,ports) = if port.PortType = (PortType.Input) then @@ -1430,7 +1235,7 @@ let update (msg : Msg) (model : Model): Model*Cmd<'a> = comp.H, comp.W ComponentId comp.Id, { Pos = xyPos - STransform = 0 + STransform = R0 ShowInputPorts = false //do not show input ports initially ShowOutputPorts = false //do not show output ports initially Colour = "lightgrey" // initial color