// -----------------------------------------------------------------------
        void DisplayVisualScriptErrorsAndWarnings(List <ErrorWarning> errors, List <ErrorWarning> warnings)
        {
            // -- Get error/warning information --
            var nbOfErrors   = errors.Count;
            var nbOfWarnings = warnings.Count;

            // -- Display scene error/warning icon --
            var r    = GetVisualScriptErrorWarningIconRect();
            var icon = nbOfErrors != 0 ? ErrorController.ErrorIcon : ErrorController.WarningIcon;

            ErrorController.DisplayErrorOrWarningIconWithAlpha(r, icon);

            // -- Initiate the display of the scene error/warning details when mouse is over the icon --
            if (r.Contains(WindowMousePosition))
            {
                showErrorDetails = true;
                if (showErrorDetailTimer == null)
                {
                    showErrorDetailTimer = TimerService.CreateTimedAction(1f, () => { showErrorDetails = false; });
                    showErrorDetailTimer.Schedule();
                }
                else
                {
                    showErrorDetailTimer.Restart();
                }
            }

            // -- Display scene errors/warnings --
            if (showErrorDetails)
            {
                var nbOfMessages = Mathf.Min(10, nbOfErrors + nbOfWarnings);
                r = ErrorController.DetermineErrorDetailRect(position, r, nbOfMessages, true);
                if (r.Contains(WindowMousePosition))
                {
                    showErrorDetailTimer.Restart();
                }
                ErrorController.DisplayErrorAndWarningDetails(r, errors, warnings);
            }
        }
Ejemplo n.º 2
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);
        }