Sharing constants between managed (C#) and native (C++) code

Started by monkey0506, Mon 29/09/2014 12:06:56

Previous topic - Next topic

monkey0506

I'm working on getting the game data file to build from the editor's managed code instead of from the native assembly, as part of supporting targeting multiple platforms from the editor (instead of just Windows). As I've gotten into the bulk of the code over the last couple days, and particularly the last several hours, I've come across several constant values that may appear in multiple places. Some of these are being moved to managed code, while others might remain in the native code.

What is the best way to make sure that the code duplication is kept to a minimum in these cases? In particular I'm concerned that a constant may be updated in one place but not another. For now I've been duplicating them in as narrow a scope as possible (until I can finish rewriting/porting the code and make sure it's at least functional), but it would be great to have a sense of direction in this.

Crimson Wizard

Which constants do you mean? If these are only used inside AGS.Native code, for instance, you may just move them all to C#, because AGS.Native references AGS.Types anyway.

monkey0506

Ultimately I think all of the related code should be moved out of the native assembly, but a lot of the unmanaged code isn't relevant to what I'm working on. I'll see if I can take advantage of AGS.Types for these constants (specifically I'm thinking of "scfilesig", "endfilesig", "ags_version", "SCOM_VERSION", various flags for inventory, cursors, etc.). I'm working with a huge amount of code, so wrapping my head around all of it at once is no small undertaking. Thanks for the reminder about AGS.Types, that's what I was looking for here.

Crimson Wizard

#3
For some reason part of my post was not posted. Maybe I forgot to click "Post" button when editing it for the second time :).

I meant to say that unfortunately this is inevitable that some code will be duplicated: the one that is currently shared by Editor and Engine, such as reading compiled data (game, rooms), for instance. This is the cost of having Engine and Editor written in two languages.
(BTW ENDFILESIG, and SCOM_VERSION constants are used by the engine too).

The only solution to unify constants that comes to mind is doing some kind of preprocessing that would create corresponding *.h/.cs files from a shared list of constants.
And moving code that unpacks binaries into stand-alone C++ utilities, or something.

Calin Leafshade

I've been going through replacing all the C++ stuff with managed code for a couple of weeks now.

The biggest duplication seems to be clib access. Things like getting and rendering fonts is especially problematic.

Crimson Wizard

#5
I am beginning to fear that you are doing duplicate work, because it looks like monkey_05_06 is moving clib functions to C# too.
Also, there was already a code which loads rooms in C# (probably incomplete):
https://github.com/monkey0506/ags/tree/multi_room_edit

Would not you like to sync what you do somehow?

monkey0506

As I completed the initial implementation of this feature (writing data file from editor assembly rather than native assembly), I realized that there are a rather unwieldy number of constant values that I needed for this that are also needed for the run-time engine. So, putting things in AGS.Types wasn't really a viable option. However, since the editor assembly references the native assembly, it's rather simple to pull in the values from the native code to the managed code just-in-time (e.g., when static readonly fields are initialized, the first time one of them is referenced).

The latest commit in my fork has this implemented. I welcome feedback if someone has a better way of handling this situation, but this seems pretty clean to me (if too many constants are added, it could improve look-up time to implement a map, but that felt like a bit much for now).

Crimson Wizard

I will check this more later, but at the moment, I suggest that if you move constants to another header, please move whole group (e.g. all GUIF_*), because it is important to know they are grouped therefore should not have duplicate values.

monkey0506

Ah, right. Good call. ;) In particular I'll note that I had to move constants around because of the conflict between the Windows GDI BITMAP type and the Allegro BITMAP type. The Windows headers are included in NativeMethods.cpp while the Allegro headers are included in the GUI headers. I was thinking it would be best to keep changes minimal, but you make a perfectly valid point.

SMF spam blocked by CleanTalk