Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2014
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.21 KB | None | 0 0
  1. namespace UnityTest
  2.  
  3. open UnityEngine;
  4.  
  5. type guid
  6.   = System.Guid
  7.  
  8. module Guid =
  9.  
  10.   let private sync = new obj();
  11.   let mutable private set = Set.empty<guid>
  12.  
  13.   let Generate () =
  14.     System.Guid.NewGuid()
  15.  
  16.   let Exists id =
  17.     Set.contains id set
  18.  
  19.   let Insert id =
  20.     lock sync (fun () ->
  21.       if Set.contains id set
  22.         then failwith "Duplicate GUID"
  23.         else set <- set.Add id
  24.     )
  25.  
  26. type CanvasAsset() =
  27.   inherit ScriptableObject()
  28.  
  29.   [<DefaultValue>]
  30.   [<SerializeField>]
  31.   val mutable Binary : string
  32.  
  33. type SlotMode
  34.   = In
  35.   | Out
  36.  
  37. type DataType = {
  38.   Id : guid
  39.   Name : string
  40.   Color : Color
  41. }
  42.  
  43. type Slot = {
  44.   Id : guid
  45.   TypeId : guid
  46.   Name : string
  47.   Mode : SlotMode
  48. } with
  49.   member x.AllowMultiple =
  50.     false
  51.  
  52. type NodeType = {
  53.   Id : guid
  54.   Name : string
  55.   SlotsIn : Slot list
  56.   SlotsOut : Slot list
  57. } with
  58.   member x.CreateSlot (id : guid) (mode : SlotMode) (name : string) (dt : DataType) =
  59.     let s = {
  60.       Id = id;
  61.       Mode = mode;
  62.       Name = name;
  63.       TypeId = dt.Id;
  64.     }
  65.  
  66.     match mode with
  67.     | In -> {x with SlotsIn = s :: x.SlotsIn}
  68.     | Out -> {x with SlotsOut = s :: x.SlotsOut}
  69.  
  70.   member x.HasSlot (s:Slot) =
  71.     match s.Mode with
  72.     | In -> List.exists (fun s' -> s = s') x.SlotsIn
  73.     | Out -> List.exists (fun s' -> s = s') x.SlotsOut
  74.  
  75. type Node = {
  76.   Id : guid
  77.   Data : obj
  78.   TypeId : guid
  79.   Position : Vector3
  80.   DynamicType : NodeType option
  81. }
  82.  
  83. type Link = {
  84.   Id : guid
  85.   Data : obj
  86.   SourceId : guid
  87.   SourceSlotId : guid
  88.   TargetId : guid
  89.   TargetSlotId : guid
  90. }
  91.  
  92. type Context = {
  93.   Id : guid
  94.   Name : string
  95.   NodeTypes : Map<guid, NodeType>
  96.   DataTypes : Map<guid, DataType>
  97. } with
  98.   member x.HasDataType (dt:DataType) = x.DataTypes.[dt.Id] = dt
  99.   member x.HasNodeType (nt:NodeType) = x.NodeTypes.[nt.Id] = nt
  100.  
  101.   member x.AddDataType (dt:DataType) =
  102.     if x.HasDataType dt then
  103.       failwith "Data type already exists in context"
  104.  
  105.     {x with DataTypes = x.DataTypes.Add(dt.Id, dt)}
  106.  
  107.   member x.AddNodeType (nt:NodeType) =
  108.     if x.HasNodeType nt then
  109.       failwith "Node type already exists in context"
  110.  
  111.     {x with NodeTypes = x.NodeTypes.Add(nt.Id, nt)}
  112.  
  113.   member x.FindDataType (id:guid) = Map.find id x.DataTypes
  114.   member x.FindNodeType (id:guid) = Map.find id x.NodeTypes
  115.  
  116. module ContextLookup =
  117.   let private contexts = ref Map.empty<guid, Context>
  118.   let Register (ct:Context) = contexts := (!contexts).Add(ct.Id, ct)
  119.   let Find (id:guid) = Map.find id !contexts
  120.  
  121. type Canvas = {
  122.   Id : guid
  123.   ContextId : guid
  124.   Name : string
  125.   Nodes : Map<guid, Node>
  126.   Links : Map<guid, Link>
  127. } with
  128.   member x.Context = ContextLookup.Find x.ContextId
  129.   member x.ContainsNode (n:Node) =
  130.     match x.Nodes.TryFind n.Id with
  131.     | None -> false
  132.     | Some n' -> n = n'
  133.  
  134.   member x.FindNodeType (id:guid) =
  135.      Map.find id x.Context.NodeTypes
  136.  
  137.   member x.NodeHasLink (n:Node) (s:Slot) =
  138.     if not (x.NodeHasSlot n s) then
  139.       failwith "Slot does not exist on node"
  140.  
  141.     match s.Mode with
  142.     | In -> Map.exists (fun k l -> l.TargetId = n.Id && l.TargetSlotId = s.Id) x.Links
  143.     | Out -> Map.exists (fun k l -> l.SourceId = n.Id && l.SourceSlotId = s.Id) x.Links
  144.  
  145.   member x.DeleteLink (l:Link) =
  146.     {x with Links = x.Links.Remove l.Id}
  147.  
  148.   member x.DeleteNode (n:Node) =
  149.     let nodes = x.Nodes.Remove(n.Id)
  150.     let links = Map.filter (fun _ l -> l.SourceId <> n.Id && l.TargetId <> n.Id) x.Links
  151.     {x with Nodes = nodes; Links = links}
  152.  
  153.   member x.NodeHasSlot (n:Node) (s:Slot) =
  154.     let nt = x.FindNodeType n.TypeId
  155.     match nt.HasSlot s, n.DynamicType with
  156.     | true , _      -> true
  157.     | false, None   -> false
  158.     | false, Some dt -> dt.HasSlot s
  159.      
  160.   member x.CreateNode (nt:NodeType) =
  161.     if not (x.Context.HasNodeType nt) then
  162.       failwith "Node type does not exist in context"
  163.  
  164.     let node = {
  165.       Id = guid.NewGuid()
  166.       TypeId = nt.Id
  167.       Data = null
  168.       Position = Vector3.zero
  169.       DynamicType = None
  170.     }
  171.  
  172.     {x with Nodes = x.Nodes.Add(node.Id, node)}
  173.  
  174.   member x.CreateDynamicSlot (n:Node) (s:Slot) =
  175.     if not (x.ContainsNode n) then
  176.       failwith "Canvas does not contain node"
  177.  
  178.     match n.DynamicType with
  179.     | None ->
  180.       let d = {Id = guid.Empty; Name = ""; SlotsIn = []; SlotsOut = [];}
  181.       x.CreateDynamicSlot {n with DynamicType = Some d} s
  182.  
  183.     | Some d ->
  184.       let d =
  185.         match s.Mode with
  186.         | In -> {d with SlotsIn = s :: d.SlotsIn}
  187.         | Out -> {d with SlotsOut = s :: d.SlotsOut}
  188.  
  189.       let n = {n with DynamicType = Some d}
  190.       {x with Nodes = x.Nodes.Remove(n.Id).Add(n.Id, n)}
  191.  
  192.   member x.CreateLink (source:Node, target:Node, sourceSlot:Slot, targetSlot:Slot) =
  193.     if not (x.ContainsNode source) then
  194.       failwith "Canvas does not contain source node"
  195.  
  196.     if not (x.ContainsNode target) then
  197.       failwith "Canvas does not contain target node"
  198.  
  199.     if source.Id = target.Id then
  200.       failwith "Can't connect a node to iself"
  201.  
  202.     if not (x.NodeHasSlot source sourceSlot) then
  203.       failwith "Slot does not exist on source"
  204.  
  205.     if not (x.NodeHasSlot target targetSlot) then
  206.       failwith "Slot does not exist on target"
  207.  
  208.     if sourceSlot.TypeId <> targetSlot.TypeId then
  209.       failwith "Source and target slots dont have the same type"
  210.  
  211.     if sourceSlot.Mode <> SlotMode.Out then
  212.       failwith "Source slot is not an OUT slot"
  213.  
  214.     if targetSlot.Mode <> SlotMode.In then
  215.       failwith "Target slot is not an IN slot"
  216.  
  217.     if (x.NodeHasLink source sourceSlot) && not sourceSlot.AllowMultiple then
  218.       failwith "Source slot is already connected somewhere"
  219.  
  220.     if (x.NodeHasLink target targetSlot) && not targetSlot.AllowMultiple  then
  221.       failwith "Target slot is already connected somewhere"
  222.  
  223.     let link = {
  224.       Id = guid.NewGuid()
  225.       Data = null
  226.       SourceId = source.Id
  227.       SourceSlotId = sourceSlot.Id
  228.       TargetId = target.Id
  229.       TargetSlotId = targetSlot.Id
  230.     }
  231.  
  232.     {x with Links = x.Links.Add(link.Id, link)}
  233.  
  234. type NodeTypeCreator (context : Context ref, id : guid, name : string) =
  235.   let nodeType = ref { Id = id; Name = name; SlotsIn = []; SlotsOut = [] }
  236.  
  237.   member x.CreateSlot (id : guid) (mode : SlotMode) (name : string) (dt : DataType) =
  238.     if not ((!context).HasDataType dt) then
  239.       failwith "Canvas type does not contain the data type"
  240.  
  241.     nodeType := (!nodeType).CreateSlot id mode name dt
  242.  
  243.   interface System.IDisposable with
  244.     member x.Dispose() =
  245.       context := (!context).AddNodeType !nodeType
  246.       nodeType := Unchecked.defaultof<NodeType>
  247.  
  248. type ContextCreator (id : guid, name : string) =
  249.   let context = ref { Id = id; Name = name; DataTypes = Map.empty; NodeTypes = Map.empty }
  250.  
  251.   member x.CreateDataType (id : guid) (name : string) (clr : Color) =
  252.     let dt = { Id = id; Name = name; Color = clr}
  253.     context := (!context).AddDataType dt
  254.     dt
  255.  
  256.   member x.CreateNodeType (id : guid) (name : string) =
  257.     new NodeTypeCreator(context, id, name)
  258.  
  259.   member x.FindDataType (id : guid) =
  260.     (!context).FindDataType id
  261.  
  262.   interface System.IDisposable with
  263.     member x.Dispose() =
  264.       ContextLookup.Register !context
  265.       context := Unchecked.defaultof<Context>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement