1. This forum is obsolete and read-only. Feel free to contact us at support.keenswh.com

SEScriptTool: A tool to generate one script file from multiple class files

Discussion in 'Programming Guides and Tools' started by Haarmees, Jun 10, 2017.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Haarmees

    Haarmees Trainee Engineer

    Messages:
    3
    Hey Engineers!

    I would like to share a tool I created with you: SEScriptBuilder. I created this tool because working in one file does not allow you to reuse any code. Of course you can copy paste your code between scripts, but this is hard to maintain. Hence this tool: it analyzes your script file, and injects all the code that is used. The tool uses the project files (.csproj) created by visual studio.

    It will check the project for a file with a class that extends MyGridProgram. If found it will analyze this file and inject any code used by this 'main' file. For example you can have a class file in your project or a referenced project:

    Code:
    // BatteryGroup.cs
    using System;
    ...
    namespace MyProject {
    public Class BatteryGroup {
    
    List<IMyBatteryBlock> batteries;
    
    public BatteryGroup(List<IMyBatteryBlock> b)
    {
    this.batteries = b;
    }
    
    // other code
    
    }
    }
    
    Now assume you have a 'program'file as follows:
    Code:
    // MyShipProgram.cs
    using System;
    ...
    namespace MyProject {
    public Class MyShipProgram : MyGridProgram {
    
    BatteryGroup batGroup;
    
    public MyShipProgram()
    {
    // constructor code (will become program function)
    }
    
    public void Main(){
    {
    this.batGroup = new BatteryGroup(aListWithBatteryBlocks)
    }
    
    // other code
    
    }
    }
    Running the tool in debug mode will create a file called Script.cs with the following code:

    Code:
    // Script.cs
    #if DEBUG
    using System;
    ...
    namespace MyProject {
    public Class Program : MyGridProgram {
    #endif
    BatteryGroup batGroup;
    
    public Program()
    {
    // constructor code (will become program function)
    }
    
    public void Main(){
    {
    this.batGroup = new BatteryGroup(aListWithBatteryBlocks)
    }
    
    // other code
    
    public Class BatteryGroup {
    
    List<IMyBatteryBlock> batteries;
    
    public BatteryGroup(List<IMyBatteryBlock> b)
    {
    this.batteries = b;
    }
    
    // other code
    
    }
    #if DEBUG
    }
    }
    #endif
    Note that the BatteryGroup class is injected in the program class. The class name and constructor are rewritten to 'Program'. The #if DEBUG and #endif are added in debug mode and allow you to simply copy all code to your program block. The program block will ignore these regions, so the code will run.

    This is only a short example. I have written a more extensive guide here: https://github.com/Haarmees/SEVSToo...c48893ed03601/SEScriptBuilder/docs/SetupVS.md
    Note that this guide is still a first draft, let me now if you find any mistakes. The guide also shows how to run the tool with Visual Studio itself.

    Why use the tool?
    The reason I created this tool is so you can create libraries of reusable code and have the benefits of OOP. One of the next steps of this tool is to support NuGet packages. This way programmers can create libraries and share these with other programmers.

    Will it work?
    I am still in the process of testing the tool. It should be fairly stable (at leas has been for me).
    If the tool does not work for you please tell me the console output and show me the code you're trying to build. I will work on stabilizing the tool more.

    Roadmap
    • Allow NuGet packages to work with the tool
    • Check the code for errors during the build process
    • Let the tool log more detailed information
    • Make tool part of Visual Studio plugin, so no setup is required
    Download the tool here
    Make sure to check the guide first.

    Known Issues
    • Classes should have a unique name, as they are directly imported
    Changelog

    0.1.1
    • Fixed importing/injecting virtual and override methods
     
    Last edited: Jun 13, 2017
  2. SDragon42

    SDragon42 Apprentice Engineer

    Messages:
    146
    I am definitely going to check this out! It sounds like just what I want.
     
  3. susu

    susu Trainee Engineer

    Messages:
    13
    Awesome tool! Already sent a PR about doc fixes:)
     
  4. SDragon42

    SDragon42 Apprentice Engineer

    Messages:
    146
    Anyone have this stop working correctly?

    It is stripping out code that is still referenced if it is in a for look or in an embedded class. Even on scripts that I haven't changed and were built correctly before.
    I am think it is probably related to the vs2017 update that happened a day or two ago (since it worked before that update).

    Just odd that is works in same cases now, but not in others.

    Going to try to repair my VS install to see if that corrects it.
     
  5. Haarmees

    Haarmees Trainee Engineer

    Messages:
    3
    Hey everyone, sorry I've been away for a while. I know of one bug, where a functions marked with override do not get imported. I hope to find some time this weekend to fix this.

    @susu thanks for the PR! How is the tool working for you?

    @SDragon42 Could you show me some code that does not work? It's is probably a use case I haven't thought of.

    p.s. The tool also works with nuget packages that expose their source files. (Like this https://nikcodes.com/2013/10/23/packaging-source-code-with-nuget/)

    p.p.s I've also started to incorporate this tool in a plugin (nowhere finished though), so it becomes more plug and play
     
  6. SDragon42

    SDragon42 Apprentice Engineer

    Messages:
    146
    @Haarmees
    Source:
    Code:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using VRageMath;
    using VRage.Game;
    using VRage.Collections;
    using Sandbox.ModAPI.Ingame;
    using VRage.Game.Components;
    using VRage.Game.ModAPI.Ingame;
    using Sandbox.ModAPI.Interfaces;
    using Sandbox.Game.EntityComponents;
    using SpaceEngineers.Game.ModAPI.Ingame;
    using VRage.Game.ObjectBuilders.Definitions;
    
    public sealed class ScriptProgram : MyGridProgram
    {
    
        List<IMyTextPanel> _displays = new List<IMyTextPanel>();
    
        public void Main(string argument)
        {
            GridTerminalSystem.GetBlocksOfType(_displays);
            if (_displays.Count == 0) return;
    
            foreach (var panel in _displays) UpdateDisplay(panel, "Hello World!");
        }
    
        private void UpdateDisplay(IMyTextPanel panel, string text)
        {
            panel.ShowPublicTextOnScreen();
            panel.WritePublicText(text);
        }
    }
    
    Debug Output:
    Code:
    #if DEBUG
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using VRageMath;
    using VRage.Game;
    using VRage.Collections;
    using Sandbox.ModAPI.Ingame;
    using VRage.Game.Components;
    using VRage.Game.ModAPI.Ingame;
    using Sandbox.ModAPI.Interfaces;
    using Sandbox.Game.EntityComponents;
    using SpaceEngineers.Game.ModAPI.Ingame;
    using VRage.Game.ObjectBuilders.Definitions;
    
    public sealed class Program: MyGridProgram
    {
    #endif
    
        List<IMyTextPanel> _displays = new List<IMyTextPanel>();
    
        public void Main(string argument)
        {
            GridTerminalSystem.GetBlocksOfType(_displays);
            if (_displays.Count == 0) return;
    
            foreach (var panel in _displays) UpdateDisplay(panel, "Hello World!");
        }
    #if DEBUG
    }
    
    #endif
    
    I am pretty sure that it is something on my PC that is causing it.
    Other code projects were being output correctly before, but now do not work (exhibit the behavior above)

    And now today, the process seems to crash after it starts "Analyzing source code"
    I might try reinstalling VS to see if something happened to it (since I first saw problems after a vs update)
     
  7. Haarmees

    Haarmees Trainee Engineer

    Messages:
    3
    I think your problem is that the csproj file is not updated correctly. (At least I have had this) It keeps track of all cs file like this:
    Code:
    ...
    <Compile Include="Properties\AssemblyInfo.cs" />
    ...
    but sometimes adding a new class file does not update it. To solve this, you could either try to build the project/library (i.e. create the dll file). Or you could edit the csproj file yourself and add them.
     
  8. SDragon42

    SDragon42 Apprentice Engineer

    Messages:
    146
    All the CS files are in the csproj file.
    To be clear, this has worked perfectly before. But now it is not.
    I've tried reinstalling VS2017 to see if that would correct the issue. (Running version 15.3.2)

    Code:
      <ItemGroup>
        <Compile Include="LCD Test.cs" />
        <Compile Include="Properties\AssemblyInfo.cs" />
      </ItemGroup>
    I'll keep looking at my system to see what may have changed to cause the issues I am having.
     
Thread Status:
This last post in this thread was made more than 31 days old.