Example #1
0
        // ----------------------------------------------------------------------
        public void RebuildStateConnection(iCS_EditorObject fromStatePort, iCS_EditorObject toStatePort)
        {
            if (fromStatePort == null || toStatePort == null)
            {
                return;
            }
            var commonParent = GraphInfo.GetCommonParent(fromStatePort, toStatePort);

            if (commonParent == null)
            {
                Debug.LogWarning("iCanScript: Unable to find common parent after relocating state !!!");
                return;
            }
            var transitionPackage = GetTransitionPackage(toStatePort);

            if (transitionPackage == null)
            {
                return;
            }
            if (transitionPackage.ParentNode == commonParent)
            {
                return;
            }
            ChangeParent(transitionPackage, commonParent);
            LayoutTransitionPackage(transitionPackage);
        }
        // ===================================================================
        // EDITOR ENTRY POINT
        // -------------------------------------------------------------------
        /// Port specific information.
        public void OnGUI()
        {
            // -- Display port name. --
            EditName("Port Name");

            // -- Edit the value of the port. --
            EditPortValue();

            // -- Edit port specification. --
            var variableType = ConvertEnum(vsObject.PortSpec, GraphInfo.GetAllowedPortSpecification(vsObject));

            variableType = EditorGUILayout.EnumPopup("Variable Specification", variableType);
            SetPortSpec(ConvertEnum(variableType, PortSpecification.Default));

            // -- Show port type. --
            var portValue = vsObject.Value;

            if (portValue != null)
            {
                EditorGUILayout.LabelField("Variable Type", iCS_Types.TypeName(portValue.GetType()));
            }

            // -- Show port index. --
            EditorGUILayout.IntField("Parameter Index", vsObject.PortIndex);

            // -- Edit port description. --
            EditDescription();
        }
Example #3
0
        // ===================================================================
        /// Returns the allowed types of variable the given port can support.
        ///
        /// @param port The port used to filter the types of variable.
        /// @return The filtered port specification.
        ///
        public static Enum GetAllowedPortSpecification(iCS_EditorObject port)
        {
            var producerPort = GetProducerPort(port);

            if (MustBeATypeVariable(producerPort))
            {
                return(TypeVariables.PublicVariable);
            }
            if (MustBeAParameter(producerPort))
            {
                return(ParameterVariable.Parameter);
            }
            if (producerPort.IsInDataOrControlPort)
            {
                var isFunctionDefinition = producerPort.ParentNode.IsFunctionDefinition;
                var runtimeType          = producerPort.RuntimeType;
                if (iCS_Types.IsA <UnityEngine.Object>(runtimeType))
                {
                    if (runtimeType == typeof(GameObject) ||
                        runtimeType == typeof(Transform))
                    {
                        if (isFunctionDefinition)
                        {
                            return(InFunctionDefinitionOwnerAndUnityObjectVariableType.PublicVariable);
                        }
                        return(InOwnerAndUnityObjectVariableType.PublicVariable);
                    }
                    else
                    {
                        if (isFunctionDefinition)
                        {
                            return(InFunctionDefinitionUnityObjectVariableType.PublicVariable);
                        }
                        if (GraphInfo.IsLocalType(producerPort))
                        {
                            return(InOwnerAndUnityObjectVariableType.Owner);
                        }
                        return(InUnityObjectVariableType.PublicVariable);
                    }
                }
                else
                {
                    if (isFunctionDefinition)
                    {
                        return(InFunctionDefinitionVariableType.PublicVariable);
                    }
                    if (GraphInfo.IsLocalType(producerPort))
                    {
                        return(InTypeVariableWithOwner.Owner);
                    }
                    return(InVariableType.PublicVariable);
                }
            }
            else if (producerPort.IsOutDataOrControlPort)
            {
                return(OutVariableType.PublicVariable);
            }

            return(TypeVariables.PublicVariable);
        }
        // -------------------------------------------------------------------------
        iCS_EditorObject[] FilterMultiSelectionUnderSameParent()
        {
            var multiSelectedObjects = GetMultiSelectedObjects();

            if (multiSelectedObjects == null || multiSelectedObjects.Length == 0)
            {
                Debug.LogWarning("No selected object found!!!");
                return(null);
            }
            // Find common parent.
            if (multiSelectedObjects.Length == 1)
            {
                return(multiSelectedObjects);
            }
            var commonParent = GraphInfo.GetCommonParent(multiSelectedObjects);
            // Special case for when the common parent is one of the selected objects.
            List <iCS_EditorObject> valid = new List <iCS_EditorObject>();

            foreach (var obj in multiSelectedObjects)
            {
                if (obj == commonParent)
                {
                    valid.Add(obj);
                }
            }
            if (valid.Count != 0)
            {
                return(valid.ToArray());
            }
            // Find the proper node just below common parent.
            foreach (var o in multiSelectedObjects)
            {
                var obj = o;
                while (obj.ParentNode != null && obj.ParentNode != commonParent)
                {
                    obj = obj.ParentNode;
                }
                if (obj.ParentNode == commonParent)
                {
                    valid.Add(obj);
                }
            }

            /*
             *  TODO : Filter for uniqu entries.
             */
            return(valid.ToArray());
        }
        // -------------------------------------------------------------------------
        /// Determines if the enable port is always _true_.
        ///
        /// @param enablePort The enable port.
        /// @return _true_ if the enable is always true. _false_ otherwise.
        ///
        public static bool IsEnableAlwaysTrue(iCS_EditorObject enablePort)
        {
            var producerPort = GraphInfo.GetProducerPort(enablePort);

            if (producerPort.IsInputPort)
            {
                var initialValue = producerPort.Value;
                if (initialValue is UndefinedTag)
                {
                    return(false);
                }
                var value = (bool)initialValue;
                return(value == true);
            }
            return(false);
        }
Example #6
0
        // ===================================================================
        /// Sets the port specififcation.
        ///
        /// @param vsObject An object that is part of the connection.
        /// @param portSpec The new port specification.
        ///
        public static void SetPortSpec(iCS_EditorObject vsObject, PortSpecification portSpec)
        {
            var allConnectedPorts = GraphInfo.GetAllConnectedPorts(vsObject);

            foreach (var p in allConnectedPorts)
            {
                if (p.IsEnablePort)
                {
                    p.PortSpec = PortSpecification.Enable;
                }
                else
                {
                    p.PortSpec = portSpec;
                }
                AdjustPortIndexes(p.ParentNode);
            }
        }
Example #7
0
        // ======================================================================
        /// Sets the default port specification for the given port.
        ///
        /// @param p The port on which to set the default port specification.
        ///
        public static void SetDefaultPortSpec(iCS_EditorObject p)
        {
            // -- Setup spec for control ports. --
            var parentNode   = p.ParentNode;
            var producerPort = GraphInfo.GetProducerPort(p);

            // -- Only valid for the producer port. --
            if (producerPort != p)
            {
                return;
            }
            // -- Determine default port spec. --
            if (parentNode.IsFunctionDefinition)
            {
                if (p.IsInDataOrControlPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.Parameter);
                }
            }
            else if (parentNode.IsEventHandler)
            {
                if (p.IsFixDataPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.Parameter);
                }
                else
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                }
            }
            else if (parentNode.IsVariableDefinition)
            {
                if (p.IsOutDataOrControlPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                }
                else if (p.IsInDataOrControlPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.Constant);
                }
            }
            else if (parentNode.IsConstructor)
            {
                if (p.IsInDataOrControlPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.Constant);
                }
                else if (p.IsOutDataOrControlPort)
                {
                    // -- Determine if this is a local variable of not. --
                    bool isLocal = false;
                    parentNode.ForEachChildPort(
                        cp => {
                        if (cp.IsInDataOrControlPort)
                        {
                            if (cp.ProducerPort != null)
                            {
                                isLocal = true;
                            }
                        }
                    }
                        );
                    if (isLocal)
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.LocalVariable);
                    }
                    else
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                    }
                }
            }
            // TODO: Needs to be verified...
            else if (parentNode.IsKindOfFunction)
            {
                if (p.IsInDataOrControlPort)
                {
                    var initialValue = p.Value;
                    if (initialValue != null)
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.Constant);
                    }
                    else
                    {
                        var runtimeType = p.RuntimeType;
                        if (p.IsTargetPort &&
                            (runtimeType == typeof(GameObject) ||
                             runtimeType == typeof(Transform) ||
                             GraphInfo.IsLocalType(p)))
                        {
                            GraphEditor.SetPortSpec(p, PortSpecification.Owner);
                            p.Value = null;
                        }
                        else
                        {
                            GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                        }
                    }
                }
                else if (p.IsOutDataOrControlPort)
                {
                    if (GraphInfo.MustBeATypeVariable(p))
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.PrivateVariable);
                    }
                    else
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.LocalVariable);
                    }
                }
            }
            else if (parentNode.IsInstanceNode)
            {
                if (p.IsInDataOrControlPort)
                {
                    var runtimeType = p.RuntimeType;
                    if (p.IsTargetPort &&
                        (runtimeType == typeof(GameObject) ||
                         runtimeType == typeof(Transform) ||
                         GraphInfo.IsLocalType(p)))
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.Owner);
                        p.Value = null;
                    }
                    else
                    {
                        GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                    }
                }
            }
            else if (parentNode.IsKindOfPackage)
            {
                if (p.IsInDataOrControlPort)
                {
                    GraphEditor.SetPortSpec(p, PortSpecification.PublicVariable);
                }
            }
            else
            {
                GraphEditor.SetPortSpec(p, PortSpecification.LocalVariable);
            }
        }
Example #8
0
        // ===================================================================
        /// Refreshes the port specififcation of a connection.
        ///
        /// @param vsObject An object that is part of the connection.
        ///
        public static void RefreshPortSpec(iCS_EditorObject vsObject)
        {
            var producerPort = GraphInfo.GetProducerPort(vsObject);

            SetPortSpec(producerPort, producerPort.PortSpec);
        }
        // ----------------------------------------------------------------------
        void RebuildDataConnection(iCS_EditorObject outputPort, iCS_EditorObject inputPort)
        {
#if DEBUG
            Debug.Log("iCanScript: RebuildDataConnection: output= " + outputPort.DisplayName + " input= " + inputPort.DisplayName);
#endif
            // Have we completed rebuilding ... if so return.
            if (inputPort == outputPort)
            {
                return;
            }
            var inputNode  = inputPort.ParentNode;
            var outputNode = outputPort.ParentNode;
            if (inputNode == outputNode)
            {
                return;
            }
            // outputPort is inside the node with the inputPort.
            var commonParentNode = GraphInfo.GetCommonParent(outputPort, inputPort);
            if (inputNode == commonParentNode)
            {
                // Rebuild moving down from the common parent towards the output port.
                var newInputNode = outputPort.ParentNode;
                while (newInputNode != inputNode && newInputNode.ParentNode != inputNode)
                {
                    newInputNode = newInputNode.ParentNode;
                }
                var existingPort = IStorage.FindPortWithSourceEndPoint(newInputNode, outputPort);
                if (existingPort != null)
                {
                    var prevSource = inputPort.ProducerPort;
                    if (prevSource != existingPort)
                    {
                        inputPort.ProducerPort = existingPort;
                        if (prevSource.IsDynamicDataPort && !inputPort.IsPartOfConnection(prevSource))
                        {
                            IStorage.CleanupHangingConnection(prevSource);
                        }
                    }
                    RebuildDataConnection(outputPort, existingPort);
                }
                else
                {
                    iCS_EditorObject newPort = IStorage.CreatePort(inputPort.DisplayName, newInputNode.InstanceId, inputPort.RuntimeType, VSObjectType.OutDynamicDataPort);
                    IStorage.SetBestPositionForAutocreatedPort(newPort, outputPort.GlobalPosition, inputPort.GlobalPosition);
                    newPort.ProducerPort   = inputPort.ProducerPort;
                    inputPort.ProducerPort = newPort;
                    RebuildDataConnection(outputPort, newPort);
                }
                return;
            }
            var inputNodeParent = inputNode.ParentNode;
            if (inputNodeParent == commonParentNode)
            {
                // Rebuild traversing from moving upwards to downwords.
                var newDstNode = outputPort.ParentNode;
                while (newDstNode != commonParentNode && newDstNode.ParentNode != commonParentNode)
                {
                    newDstNode = newDstNode.ParentNode;
                }
                var existingPort = IStorage.FindPortWithSourceEndPoint(newDstNode, outputPort);
                if (existingPort != null)
                {
                    var prevSource = inputPort.ProducerPort;
                    if (prevSource != existingPort)
                    {
                        inputPort.ProducerPort = existingPort;
                        if (prevSource.IsDynamicDataPort && !inputPort.IsPartOfConnection(prevSource))
                        {
                            IStorage.CleanupHangingConnection(prevSource);
                        }
                    }
                    RebuildDataConnection(outputPort, existingPort);
                }
                else
                {
                    iCS_EditorObject newPort = IStorage.CreatePort(inputPort.DisplayName, newDstNode.InstanceId, inputPort.RuntimeType, VSObjectType.OutDynamicDataPort);
                    IStorage.SetBestPositionForAutocreatedPort(newPort, outputPort.GlobalPosition, inputPort.GlobalPosition);
                    newPort.ProducerPort   = inputPort.ProducerPort;
                    inputPort.ProducerPort = newPort;
                    RebuildDataConnection(outputPort, newPort);
                }
                return;
            }
            else
            {
                // Rebuilding moving up from the consumer port towards the common parent.
                var existingPort = IStorage.FindPortWithSourceEndPoint(inputNodeParent, outputPort);
                if (existingPort != null)
                {
                    var prevSource = inputPort.ProducerPort;
                    if (prevSource != existingPort)
                    {
                        inputPort.ProducerPort = existingPort;
                        if (prevSource.IsDynamicDataPort && !inputPort.IsPartOfConnection(prevSource))
                        {
                            IStorage.CleanupHangingConnection(prevSource);
                        }
                    }
                    RebuildDataConnection(outputPort, existingPort);
                }
                else
                {
                    iCS_EditorObject newPort = IStorage.CreatePort(inputPort.DisplayName, inputNodeParent.InstanceId, inputPort.RuntimeType, VSObjectType.InDynamicDataPort);
                    IStorage.SetBestPositionForAutocreatedPort(newPort, outputPort.GlobalPosition, inputPort.GlobalPosition);
                    newPort.ProducerPort   = inputPort.ProducerPort;
                    inputPort.ProducerPort = newPort;
                    RebuildDataConnection(outputPort, newPort);
                }
            }
        }
 // ----------------------------------------------------------------------
 // Builds a list of parent nodes.  The list is sorted from the top most
 // parent to the bottom most leaf.
 public iCS_EditorObject[] BuildListOfParentNodes()
 {
     return(GraphInfo.BuildListOfParentNodes(this));
 }
Example #11
0
        // ----------------------------------------------------------------------
        /// Performs a snaity check on the visual script object.
        ///
        /// @param serviceKey The service key to use when registering with the
        ///					  error controller.
        /// @return _true_ is return if object is sane. _false_ otherwise.
        ///
        public bool SanityCheck(string serviceKey)
        {
            var visualScript = IStorage.VisualScript;

            // Verify that the runtime portion still exists.
            if (IsKindOfFunction)
            {
                var runtimeType = RuntimeType;
                var memberInfo  = runtimeType != null?LibraryController.LibraryDatabase.GetLibraryType(runtimeType) : null;

                if (memberInfo == null && !GraphInfo.IsLocalType(this))
                {
                    var message = "Unable to find the runtime code for " + FullName;
                    ErrorController.AddError(serviceKey, message, visualScript, InstanceId);
                    return(false);
                }
            }
            if (IsTargetPort)
            {
                if (ProducerPort == null || ProducerPort == this)
                {
                    var parentNode = ParentNode;
                    if (parentNode.IsKindOfFunction)
                    {
                        if (!IsOwner && !IsTypeVariable)
                        {
                            var message = "<color=red><b>Value</b></color> for <b>Target</b> port is not valid for node: <b>" + FullName + "</b>";
                            ErrorController.AddError(serviceKey, message, visualScript, InstanceId);
                            return(false);
                        }
                        else
                        {
                            if (parentNode.IsFunction("get_transform", "GameObject", "UnityEngine"))
                            {
                                var message = "When <b>'Target'</b> is set to <b>'Owner'</b>, the generated code has no effect.  The node can be removed safely: <b>" + ParentNode.FullName + "</b>";
                                ErrorController.AddWarning(serviceKey, message, visualScript, ParentNode.InstanceId);
                            }
                        }
                    }
                }
            }
            if (IsEnablePort)
            {
                var producerPort = SegmentProducerPort;
                if (producerPort != this)
                {
                    // -- Verify for unnecessary OR function --
                    var producerNode = producerPort.ParentNode;
                    if (producerNode.IsFunction("Or", "iCS_Boolean", ""))
                    {
                        if (producerPort.SegmentEndConsumerPorts.Length <= 1)
                        {
                            var message = "Consider using additional 'Enable(s)' ports instead of an OR function. => " + producerNode.FullName;
                            ErrorController.AddWarning(serviceKey, message, visualScript, producerNode.InstanceId);
                            ErrorController.AddWarning(serviceKey, message, visualScript, producerNode.InstanceId);
                        }
                    }
                    // -- Verify for unnecessary trigger->enble binding when
                    //    data flow already exist --
                    var parentNode = ParentNode;
                    if (producerPort.IsTriggerPort &&
                        producerNode.IsKindOfFunction && parentNode.IsKindOfFunction)
                    {
                        bool doesDataFlowExist = false;
                        parentNode.ForEachChildPort(
                            p => {
                            if (p.IsInDataPort)
                            {
                                var pp = p.SegmentProducerPort;
                                if (pp.ParentNode == producerNode)
                                {
                                    doesDataFlowExist = true;
                                }
                            }
                        }
                            );
                        if (doesDataFlowExist)
                        {
                            var message = "<b>Trigger</b> to <b>Enable</b> connection not needed since data flow already exist between nodes.  Consider removing the control flow.";
                            ErrorController.AddWarning(serviceKey, message, visualScript, InstanceId);
                            ErrorController.AddWarning(serviceKey, message, visualScript, producerPort.InstanceId);
                        }
                        // -- Determine if self to target connection should be used for
                        //    sequencing operation on same object.
                        var producerNodeTargetPort = producerNode.TargetPort;
                        var parentNodeTargetPort   = parentNode.TargetPort;
                        if (producerNodeTargetPort != null && parentNodeTargetPort != null)
                        {
                            var targetProducerPort = parentNodeTargetPort.SegmentProducerPort;
                            if (producerNodeTargetPort.SegmentProducerPort == targetProducerPort)
                            {
                                var targetProducerNode   = targetProducerPort.ParentNode;
                                var producerNodeSelfPort = producerNode.SelfPort;
                                var message = "Consider connecting the <b>Self</b> port of '<b>" + producerNode.DisplayName
                                              + "</b>' to the <b>Target</b> port of '<b>" + parentNode.DisplayName
                                              + "</b> to sequence operations on <b>" + targetProducerNode.DisplayName
                                              + "</b>.";
                                ErrorController.AddWarning(serviceKey, message, visualScript, parentNodeTargetPort.InstanceId);
                                ErrorController.AddWarning(serviceKey, message, visualScript, producerNodeSelfPort.InstanceId);
                            }
                        }
                    }
                }
            }
            return(true);
        }