Debugging CivEffects is somewhat tricky and I decided to help myself debugging before really giving it a try. I decided to add all XML types to enums as this will give the XML Type rather than the int index during debugging. I'm working on a perl script, which reads all XML files in a list and then generate a header file based on that. Example output:
PHP:
enum FeatureTypes
{
NO_FEATURE = -1,
#ifndef WITHOUT_XML_HARDCODING
FEATURE_ICE,
FEATURE_JUNGLE,
FEATURE_FOREST,
FEATURE_LIGHT_FOREST,
#endif
NUM_FEATURE_TYPES = 4,
FIRST_FEATURE = 0,
};
I added a few clever abilities to this on top of just being a regular enum.
WITHOUT_XML_HARDCODING isn't set in the project. This allows the debugger to read all the numbers like the #ifndef isn't present. However it is set in the makefile, which mean if any of the individual features (or whatever) is used in the code, the compiler will cause an error. That should prevent accidental hardcoding to just a single mod.
FIRST_FEATURE or FIRST_* is something I started adding to the enum. It allows code like
PHP:
for (FeatureTypes eFeature = FIRST_FEATURE; eFeature < NUM_FEATURE_TYPES; ++eFeature)
That will result in cleaner and more readable code as and less typecasts. The last is important here because typecasts can hide bugs. Vanilla uses typecasts a lot and it can easily typecase UnitTypes to UnitClassTypes without anybody noticing. Without the typecasts, incorrect assignments like that will cause a compiler error.
The new header file is written in memory and once it's complete, it is compared with the existing one. It's then only written to the file if they aren't identical. This prevents the compiler from detecting the header as modified, which in turn prevents unneeded cpp recompilations.
I filled the list of xml files and it consistently use around 0.50-0.51 seconds to run through all xml files. That's not a lot and that got me thinking. If this script is called from the same location as fastdep is called, then it is called once every time the compiler is used. If MSVC is asked to start the game, it will compile and then start. The compilation is near instant if the DLL will not have to be recompiled. This mean if modders always start the game from MSVC, we will know XML and DLL is in sync, regardless of the modder working on DLL or XML edits.
In other words, if XML and DLL modders alike opens the project file and hit F5 to start the game each time he/she edited anything, then the compiler will know XML length and optimize for those, which in turn will make the code run faster. Also it makes DLL coding easier and helps a great deal regarding memory management. In fact I would be able to store XML info sequentially, which also would make the game run faster. Say we loop all units to look at one specific number. The CPU cache (hardware) will notice this pattern and start requesting info on the next units before the CPU reach the point where it needs those info. This does make looping all infos significantly faster than it is right now where each unit is stored in a random location and as such there will not be a pattern when looping.
What do you say? It it feasible to start the game from the project or should this enum setup stay for debugging only?