/// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess da)
        {
            // reset everything, and let's start over..
            // things are botched up if this script runs more than once.
            if (_iteration++ != 0)
            {
                return;
            }

            string filePath = string.Empty;

            da.GetData(0, ref filePath);

            // Find the scripts in the current group.
            var scripts = FindObjectsOfTypeInCurrentGroup <Component_CSNET_Script>();

            if (scripts.Count != 1)
            {
                this.Message = "Error";
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "This component should be added in a group with exactly one C# script.");
                return;
            }

            this.TargetComponent = scripts.First();
            this.Message         = this.TargetComponent.NickName;

            try
            {
                string inputCode;
                using (StreamReader streamReader = new StreamReader(filePath))
                {
                    inputCode = streamReader.ReadToEnd();
                }

                if (this.TargetComponent != null)
                {
                    this.TargetComponent.SourceCodeChanged(new GH_ScriptEditor(GH_ScriptLanguage.CS));
                    var splitLines = new List <string>();
                    splitLines.Add("#region CustomUsing");
                    splitLines.Add("#endregion CustomUsing");

                    splitLines.Add("#region CustomScript");
                    splitLines.Add("#endregion CustomScript");

                    splitLines.Add("#region CustomAdditional");
                    splitLines.Add("#endregion CustomAdditional");

                    string[] inputs = inputCode.Split(splitLines.ToArray(), StringSplitOptions.None);
                    this.TargetComponent.ScriptSource.UsingCode      = inputs[1];
                    this.TargetComponent.ScriptSource.ScriptCode     = inputs[3];
                    this.TargetComponent.ScriptSource.AdditionalCode = inputs[5];

                    this.TargetComponent.ExpireSolution(true);
                }
            }
            catch (Exception e)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
            }
        }
        /// <summary>
        /// Write script to file using a template
        /// This is called from the UI thread / solve instance.
        /// </summary>
        /// <param name="script"></param>
        /// <param name="filename"></param>
        private bool WriteScriptToFile(Component_CSNET_Script script, string filename)
        {
            var methodArguments = ExtractScriptParameters(script);
            var output          = new ScriptOutput
            {
                InputOutput     = methodArguments,
                UniqueNamespace = "ns" + script.InstanceGuid.ToString().Replace("-", "").Substring(0, 5),
                // Regex to fix the padding to match 4 tabs.
                // somehow all code is still botched up. Not sure if I should use some other way to format code.
                SourceCode = Regex.Replace(script.ScriptSource.ScriptCode, @"^( {4})( *)", @"            $2$2",
                                           RegexOptions.Multiline | RegexOptions.IgnoreCase),
                AdditionalCode = Regex.Replace(script.ScriptSource.AdditionalCode, @"^( {2})( *)", @"        $2$2",
                                               RegexOptions.Multiline | RegexOptions.IgnoreCase),
            };
            var text = output.TransformText();

            try
            {
                File.WriteAllText(filename, text);
                return(true);
            }
            catch (Exception ex)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Could not write script to file {filename}, error: {ex.Message}");
                return(false);
            }
        }
        protected static void WriteScriptToComponent(Component_CSNET_Script scriptObject, string filename)
        {
            var fileContent = ReadFile(filename);
            var runscript   = GetRegion(fileContent, "Runscript");
            var rsLines     = runscript.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

            runscript = string.Join(Environment.NewLine, rsLines.Skip(2).Take(rsLines.Length - 3).ToList());
            scriptObject.SourceCodeChanged(new GH_ScriptEditor(GH_ScriptLanguage.CS));
            var additional = GetRegion(fileContent, "Additional");

            scriptObject.ScriptSource.ScriptCode     = runscript;
            scriptObject.ScriptSource.AdditionalCode = additional;
        }
Example #4
0
        protected static void WriteScriptToComponent(Component_CSNET_Script scriptObject, string filename)
        {
            var usingCodePropertyInfo = scriptObject.ScriptSource.GetType().GetProperty("UsingCode");
            var fileContent           = ReadFile(filename);
            var runscript             = GetRegion(fileContent, "Runscript");
            var rsLines = runscript.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

            runscript = string.Join(Environment.NewLine, rsLines.Skip(2).Take(rsLines.Length - 3).ToList());
            scriptObject.SourceCodeChanged(new GH_ScriptEditor(GH_ScriptLanguage.CS));
            var additional = GetRegion(fileContent, "Additional");

            scriptObject.ScriptSource.ScriptCode     = runscript;
            scriptObject.ScriptSource.AdditionalCode = additional;
            if (usingCodePropertyInfo != null)
            {
                usingCodePropertyInfo.SetValue(scriptObject.ScriptSource, GetUsing(fileContent), null);
            }
        }
Example #5
0
        /// <summary>
        /// Extract the parameters of a script
        /// </summary>
        /// <param name="script"></param>
        /// <returns></returns>
        private string ExtractScriptParameters(Component_CSNET_Script script)
        {
            var elements = new List <string>();
            var map      = BuildMap();

            // todo: Add usings to script for RH6 support.
            foreach (var ghParam in script.Params.Input.OfType <Param_ScriptVariable>())
            {
                var th            = ghParam.TypeHint ?? new GH_NullHint();
                var key           = th.ToString().Replace("Grasshopper.Kernel.Parameters.Hints.", "");
                var objectType    = map[key][2];
                var itemString    = "";
                var cleanNickname = CleanNickname(ghParam.NickName);
                switch (ghParam.Access)
                {
                case GH_ParamAccess.tree:
                    itemString = $"DataTree<{objectType}> {cleanNickname}";
                    break;

                case GH_ParamAccess.list:
                    itemString = $"List<{objectType}> {cleanNickname}";
                    break;

                case GH_ParamAccess.item:
                    itemString = $"{objectType} {cleanNickname}";
                    break;
                }

                elements.Add(itemString);
            }

            foreach (var pso in script.Params.Output)
            {
                if (pso is Param_GenericObject)
                {
                    elements.Add($"ref object {CleanNickname(pso.NickName)}");
                }
            }

            var methodArguments = string.Join(", ", elements);

            return(methodArguments);
        }
Example #6
0
        protected override void SolveInstance(IGH_DataAccess da)
        {
            // reset everything, and let's start over..
            Cleanup();
            // things are botched up if this script runs more than once.
            if (_iteration++ != 0)
            {
                return;
            }
            if (!da.GetDataTree <GH_Boolean>(0, out var tree))
            {
                return;
            }
            if (!da.GetDataTree <GH_String>(1, out var stringTree))
            {
                return;
            }

            var folder = stringTree.AllData(true).OfType <GH_String>().Select(x => x.Value).FirstOrDefault();

            if (folder == null)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Scripts Folder was not set");
                return;
            }

            folder = folder.Trim();

            if (!TryGetDirectoryVerbose(folder))
            {
                return;
            }

            var allBooleans = tree.AllData(true).Select(c => c.ScriptVariable()).Cast <bool>().ToList();
            var success     = allBooleans.Count == 1 && allBooleans[0];

            if (!success)
            {
                return;
            }

            // Find the scripts in the current group.
            var scripts = FindObjectsOfTypeInCurrentGroup <Component_CSNET_Script>();

            if (scripts.Count != 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning,
                                  "This component should be added in a group with exactly one C# script.");
                return;
            }

            if (IsBusy)
            {
                return;
            }

            TargetComponent = scripts[0];


            Folder = folder;

            string directory;
            string filename;

            try
            {
                directory = Path.GetDirectoryName(FileNameSafe);
                filename  = Path.GetFileName(FileNameSafe);
                if (directory == null || filename == null)
                {
                    throw new Exception("No file name found");
                }
            }
            catch (Exception ex)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Invalid project name or component name, error {ex.Message}");
                return;
            }


            if (!WriteScriptToFile(TargetComponent, FileNameSafe))
            {
                return;
            }

            // Create a new FileSystemWatcher and set its properties.
            // http://stackoverflow.com/questions/721714/notification-when-a-file-changes
            AddEvents(directory, filename);

            WriteDefaultConfig(directory);

            EnsureProject(Path.Combine(directory, "GrasshopperScripts.csproj"));
        }