C#, Angband and Unity

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AnonymousHero
    Veteran
    • Jun 2007
    • 1393

    #16
    Originally posted by Dean Anderson
    {#5:} Did I mention preprocessor definitions? In C# these are all boolean. Either a term is #defined or it isn't. You can't #define a term as a value and then use the term as a macro for that value elsewhere in your code. Well, you can for value types, but the syntax is different. They're declared as variables but with the "const" decorator. You can't do things like "#define SUM(A,B) (A) + (B)" though.
    This is one of those things where I've just gone through all the C code and changed the macros to functions (well, almost all). It's not like anybody's going to notice any performance difference these days.

    Originally posted by Dean Anderson
    {#6}: In C#, everything is in an encapsulated unit of code. The majority of the time these are classes but you also have enumerations, interfaces and structs (although the latter are mostly there for API compatibility with C and there's no reason to ever use them in native C# code). There's no such thing as a global scope for variables or functions{..} Every single one of those 269 times need to be prefixed with the name of the class in which you've declared it in C#.
    I actually wondered at one point whether one should just copy everything into a single class (aside from pure struct declarations, etc., obviously), get that working and then just start using IDE refactorings to split things out.

    It'd be a monster file (~140SLOC for T2.x on current master), but it really would be "just" a matter of going through from one end to the other. (Of course now you have to deal with clashing compilation-unit local statics, but I bet that's a smaller problem.)

    Originally posted by Dean Anderson
    But I have to port it as-is first and get everything working before I start doing the refactoring. Trying to port and refactor the code in a single pass will just end up in a mess.
    Agreed. I might consider a similar port in future, but I think I'm going to go a slightly different way and to get rid of some of the absolutely ridiculous amount of code (near-)duplication (using C++ and possibly a little bit of templates) before even attempting it.
    Last edited by AnonymousHero; April 17, 2015, 19:25.

    Comment

    • AnonymousHero
      Veteran
      • Jun 2007
      • 1393

      #17
      Re: Duplicate code: Case in point: just removed 715 (EDIT: 754) lines of redundant code with completely trivial template use
      Last edited by AnonymousHero; April 17, 2015, 19:23.

      Comment

      • ekolis
        Knight
        • Apr 2007
        • 921

        #18
        C# 5.0 will support static imports, much like Java, so instead of saying

        import System;
        ...
        Console.WriteLine("hello world");
        Console.WriteLine("isn't it annoying to have to type Console all the time?");

        you can say

        import System.Console;
        ...
        WriteLine("hello world");
        WriteLine("yay I don't have to type Console anymore ");
        You read the scroll labeled NOBIMUS UPSCOTI...
        You are surrounded by a stasis field!
        The tengu tries to teleport, but fails!

        Comment

        • Dean Anderson
          Adept
          • Nov 2009
          • 193

          #19
          Originally posted by AnonymousHero
          I actually wondered at one point whether one should just copy everything into a single class (aside from pure struct declarations, etc., obviously), get that working and then just start using IDE refactorings to split things out.

          It'd be a monster file (~140SLOC for T2.x on current master), but it really would be "just" a matter of going through from one end to the other. (Of course now you have to deal with clashing compilation-unit local statics, but I bet that's a smaller problem.)
          I should have thought of that. In C# it wouldn't even need to all be in a single monster file because you can use the "partial" keyword when defining a class to indicate that it's split between files.

          Comment

          • Dean Anderson
            Adept
            • Nov 2009
            • 193

            #20
            Interesting things I learned today #1: The Angband code still contains "goto" statements!

            Interesting things I learned today #2: "goto" statements will compile under C# without error.

            Those things are so coming out when I do the refactoring!

            Comment

            • Derakon
              Prophet
              • Dec 2009
              • 9022

              #21
              GOTO isn't innately bad. In particular, it's basically the only clean way I'm aware of to do "exception handling" in pure C. That doesn't mean that C# doesn't have a better construct to do whatever Angband's GOTOs are doing, of course.

              Comment

              • Dean Anderson
                Adept
                • Nov 2009
                • 193

                #22
                So, it's two (and a bit) years later. What's the current situation?

                Well, as you might have guessed from the fact that I stopped posting on the thread, I gave up. I'd been approaching the project in the wrong way and it wasn't really progressing.

                However, a couple of months ago - in the Summer - I decided to revisit Cthangband again. I started by making some changes to the program - I've got a Cthangband 5.1.0 sitting on my hard drive now with various fixes and enhancements. But then I decided to have another go at porting it to C#.

                I approached it from a different angle this time. This time my method was:
                1. Remove all the redundant code and code for other systems (I'd already done this in Cthangband 5.1.0).
                2. Wrap all the code so that it is all in one big stonking class spanning 51 files (using C#'s ability to declare "partial" classes that span files).
                3. Comment out all the C code.
                4. Go through the code a function at a time replacing each commented out C function with a C# equivalent.
                5. Only after getting everything converted and working would I then start refactoring things to make it object oriented.


                This might look similar to the prior attempt, but the significant difference is in #2. Previously I'd made each .c file into a static class while doing the conversion (so object1.c would be a class called Object1 and cmd4.c would be a class called Cmd4, and so forth). This meant that everything was static and I needed to reference between the classes constantly.

                This time, by making it all one single class, I could just create an instance of the class and all the functions and variables could see each other just like in the C version of the code.

                Similarly, in #4, I haven't been going through it file by file. Instead I've been going though it commenting out calls to functions that haven't yet been re-written and then slowly putting them back in in the right order to always have a runnable program.

                So I started out with a program that would compile and run. Then one that would show the splash screen. Then one that would show the splash screen and let you start a new game. Then one that would also take you through character generation. Then one that would create a town. Then one that would have monsters. Then one that had objects. Then one in which the monsters also moved. And so forth.

                And that made all the difference in the world. I now have a fully working and fully featured C# version of Cthangband 5.1.0 as well as a C version. There's no remaining un-ported code left.

                So I've finished #4 and I'm currently most of the way through step #5 - refactoring everything to make it object oriented. Of the 51 original source files that I converted, I've moved all the code out of 38 of them and partially out of the remaining 13; moving the code into a proper object model and doing further re-writes as I go.

                I haven't gone with Unity or anything as a front end for the moment. It's effectively just a Console app (I say "effectively", because technically it doesn't actually use the console window - they're horribly slow to update, so it uses a custom window that looks like a console but is actually just user-drawn graphics).

                Comment

                • Pete Mack
                  Prophet
                  • Apr 2007
                  • 6883

                  #23
                  Originally posted by Derakon
                  GOTO isn't innately bad. In particular, it's basically the only clean way I'm aware of to do "exception handling" in pure C. That doesn't mean that C# doesn't have a better construct to do whatever Angband's GOTOs are doing, of course.
                  There is another way, but it's not a lot better than GOTO:
                  Code:
                  do {
                       ...
                       return;
                  } while (false);
                  Handle exception here

                  Comment

                  • kandrc
                    Swordsman
                    • Dec 2007
                    • 299

                    #24
                    Originally posted by Pete Mack
                    There is another way, but it's not a lot better than GOTO:
                    Code:
                    do {
                         ...
                         return;
                    } while (false);
                    Handle exception here
                    By "not a lot better", I think you mean "a lot worse". This solution doesn't handle the fall-through, reverse-ordered de-init that is (sometimes, often) necessary. Goto gets you that for free. I (and most old systems programmers like myself) would argue that this is not only an "acceptable" or "not bad" use of goto, but that it's actually good and elegant. It's certainly more elegant than exception handling in C++ or other "modern" languages unwinding my stack (yes, I know that many will argue with this claim, but not old systems programmers).

                    ITT: "Fixing" things that aren't broken.

                    Comment

                    • Pete Mack
                      Prophet
                      • Apr 2007
                      • 6883

                      #25
                      Oh I agree that GOTO is generally preferred to "do...while false."
                      That said, long jump GOTO really is horrible; I have to disagree on this one.

                      Comment

                      • Dean Anderson
                        Adept
                        • Nov 2009
                        • 193

                        #26
                        Of course, C# has the classic:

                        Code:
                        try
                        {
                            code here
                        }
                        catch (Exception e)
                        {
                            exception code for handling exceptions here
                        }
                        finally
                        {
                            clean-up code here
                        }
                        In the above, the catch can handle some types of exception or all exceptions (and you can have more than one catch block for different types of exception), and any that are not caught will be propagated back to the code that called the function - which is what will also happen if you don't put a try/catch block in at all and an exception happens.

                        The code in the finally block is guaranteed to execute before the function returns regardless of whether or not there is an exception and regardless of whether or not it is handled.

                        Having said that, I've not got any exception handling code in there yet. At the moment, I want exceptions to be unhandled and to be caught by the debugger so that I can see what's going wrong.

                        Comment

                        • Gwarl
                          Administrator
                          • Jan 2017
                          • 1025

                          #27
                          Does this mean real consoles are no longer supported?

                          Comment

                          • Pete Mack
                            Prophet
                            • Apr 2007
                            • 6883

                            #28
                            @Dean:
                            Yes, I agree C# is a nice language, tho I think it's biggest contributions are ad hoc functional programming (LINQ) and a cleaner implementation of attributes than Java has. The task library is very well done, too. MSR deserves real kudos for these contributions.

                            Comment

                            • Dean Anderson
                              Adept
                              • Nov 2009
                              • 193

                              #29
                              Originally posted by Gwarl
                              Does this mean real consoles are no longer supported?
                              Hmm... I'm not quite sure what you mean here.

                              The current architecture is that it's a Windows desktop application. The main window uses WPF to display its contents.

                              That's not ideal (I'm not a big fan of WPF) but - at least initially - I wanted something that would work "out of the box" rather than something that relied on third party libraries and complex install sequences.

                              That left me with three options:

                              1) Console
                              2) WinForms
                              3) WPF

                              I experimented with making it a pure console application, but the C# console implementation isn't all that quick, and things like wiping the screen and displaying a page full of text are noticeably slow. It's also restricted in colour usage to a pre-defined set of sixteen colours, and that set doesn't match the default Angband colours, so you have to put up with some merging and

                              So that left me options 2 and 3. Given that WPF takes advantage of hardware acceleration, and WinForms doesn't, I went for that. It has the advantage that you can easily change the font and window size on the fly without needing a re-start, and all the text takes advantage of ClearType font rendering so it looks nice and crisp regardless of resolution.

                              However, I do say that this is the current front end. I've deliberately abstracted the front end so I can switch to a different technology or library very easily.

                              Comment

                              • Pete Mack
                                Prophet
                                • Apr 2007
                                • 6883

                                #30
                                Originally posted by Dean Anderson

                                So that left me options 2 and 3. Given that WPF takes advantage of hardware acceleration, and WinForms doesn't, I went for that. It has the advantage that you can easily change the font and window size on the fly without needing a re-start, and all the text takes advantage of ClearType font rendering so it looks nice and crisp regardless of resolution.

                                However, I do say that this is the current front end. I've deliberately abstracted the front end so I can switch to a different technology or library very easily.
                                This sounds great. Too bad it's so difficult to do the same thing with Angband, because of the C++mangling in WPF. The benefit of Win32 is that at least it's compatible with gcc/mingw. Installing MSVS is a big, big deal: rather too much for the casual angband hacker. Your effort is pretty impressive in any case. Hand porting from onr language to another is non-trivial.

                                Comment

                                Working...
                                😀
                                😂
                                🥰
                                😘
                                🤢
                                😎
                                😞
                                😡
                                👍
                                👎