Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Request: Nitpick on GetBlocksOfType

Discussion in 'Programming Questions and Suggestions' started by Flux Faraday, Mar 21, 2015.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Flux Faraday Trainee Engineer

    Messages:
    94
    It would be nice if we had
    Code:
    GridTerminalSystem.GetBlocksOfType<T>(List<T>);
    
    instead of (or in addition to)
    Code:
    GridTerminalSystem.GetBlocksOfType<T>(List<IMyTerminalBlock>);
    
    Then we wouldn't have to manually convert the list to T.
     
  2. MisterSwift Apprentice Engineer

    Messages:
    367
    Out of curiosity, would this extension(?) method work?
    Code:
    void Main() {
       List<IMyTextPanel> newList = new List<IMyTextPanel>();
       newList = GridTerminalSystem.GetBlocksOfType<IMyTextPanel>();
    }
    
    public static List<T> GetBlocksOfType<T>(this IMyGridTerminalSystem GTS) {
       List<T> results = new List<T>();
       List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
       GTS.GetblocksOfType<T>(blocks);
       blocks.ForEach(results.Add(this));
       return results;
    }
    
     
    Last edited by a moderator: Mar 21, 2015
  3. Flux Faraday Trainee Engineer

    Messages:
    94
    No, it doesn't. I like the thought, then it's just one function to copy around. SE doesn't like it though, our "Main" function is in a class and extensions have to be top-level. You can use the evil terminate-the-program-block trick to get it in the top level, i.e.:
    Code:
    // place at bottom of file.
    }
    public static class Foo
    {
        public static List<T> GetBlocksOfType<T>(this IMyGridTerminalSystem GTS) where T : class
        {
            List<T> results = new List<T>();
            List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
            GTS.GetBlocksOfType<T>(blocks);
            blocks.ForEach(foo => {results.Add(foo as T);});
            return results;
        }
    
    
    But then, it's declaration appears to be too late for our code to see it.

    By the way, does the line "blocks.ForEach(results.Add(this));" work for you in other contexts? It did not here, so my variant above is the closest I could come with my limited C# skills.
     
  4. Flux Faraday Trainee Engineer

    Messages:
    94
    So, I also tried making a simple member function, but SE throws an exception saying that access to the function failed.

    Code:
    List<T> GetBlocksOfType<T>() where T : class
    {
        List<T> results = new List<T>();
        List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
        GridTerminalSystem.GetBlocksOfType<T>(blocks);
        blocks.ForEach(foo => {results.Add(foo as T);});
        return results;
    }
    
    ... inside Main():
    
        List<IMyInventoryOwner> blocks = 
            GetBlocksOfType<IMyInventoryOwner>();
     
    
     
  5. MisterSwift Apprentice Engineer

    Messages:
    367
    I'll give it a shot when I get home and update :)
     
  6. mze9412 Junior Engineer

    Messages:
    791
    It should work this way. You close the class which contains Main() with another } and then add your own class. Your own one cannot be closed with a } because SE adds the final } itself in the end.

     
    Last edited by a moderator: Mar 23, 2015
  7. Malware Master Engineer

    Messages:
    9,866
    We're not quite there yet... you need the static class around it as well.

    Code:
    void Main(){
       List<IMyTextPanel> newList =newList<IMyTextPanel>();
       newList =GridTerminalSystem.GetBlocksOfType<IMyTextPanel>();
    }
    
    } // Close off the main class
    
    public static class MyBlockExtensions {
        public static List<T>GetBlocksOfType<T>(this IMyGridTerminalSystem gts) where T: class, IMyTerminalBlock {
            List<T> results =new List<T>();
            List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
            gts.GetBlocksOfType<T>(blocks);
            blocks.ForEach(block => results.Add(block as T));
            return results;
        }
    // } omitted because the game will add that
    (warning: coded without access to the game)
     
    Last edited by a moderator: Mar 23, 2015
  8. MisterSwift Apprentice Engineer

    Messages:
    367
    I just tested it out, LordDevious' code snippet works perfectly.

    I double checked the ForEach method, I indeed couldn't get 'this' to work, but using foo => results.Add(foo) lambda works fine. Sorry about the confusion with that.
     
  9. mze9412 Junior Engineer

    Messages:
    791
    Yeah, right, forgot the static class again :D Damn :D I just should not post code when I am in a meeting coding on work stuff ;)
     
Thread Status:
This last post in this thread was made more than 31 days old.