Some C++ Tips to make CvGameCoreDLL to run faster

hi,
well i got it and i didnt got it :)

im trying to save a specific event trigger:
Code:
python::enum_<EventTriggerTypes>("EventTriggerTypes")
        .value("NO_EVENTTRIGGER", NO_EVENTTRIGGER);
        for (int i = 0; i < GC.getNumEventTriggerInfos(); i++)
        {
            EventTriggerTypes eTrigger = (EventTriggerTypes)i;
            //getEventTriggerInfo(eTrigger).getEventTypes()
            CvEventTriggerInfo& kTrigger = GC.getEventTriggerInfo(eTrigger);
            if (GC.getEventTriggerInfo(eTrigger).getText(eTrigger) == L"EVENTTRIGGER_PALACE_UPGRADE")
                EventTriggerTypes.value(GC.getEventTriggerInfo(eTrigger), eTrigger);
        }
        ;

it fails to compile, ( i probably did the == wrong) but still fails.

1>..\CyEnumsInterface.cpp(2053): error C2143: syntax error : missing ';' before '.'
1>..\CyEnumsInterface.cpp(2053): error C2143: syntax error : missing ';' before '.'
 
EDIT: I think building info xml haven't been read yet when exposing enums to python. That is an issue there to look into.
I might as well tell how I solved this in WTP. First of all, the exe calls in this order:
  1. CvXMLLoadUtility::LoadPlayerOptions
  2. DLLPublishToPython()
  3. TXT_KEY and globalDefine loading
  4. CvXMLLoadUtility::LoadPreMenuGlobals
I added a single function, which loads all xml files. It is called in step 1 and 4. Next I modded CvXMLLoadUtility::SetGlobalClassInfo
PHP:
            if (bFirstRead)
            {
                bSuccess = pClassInfo->CvInfoBase::read(this);
            }
            else
            {
                bSuccess = pClassInfo->read(this);
            }
This way getType can be used on all info files both when setting up python and when reading all the files for real. As such reading order becomes less important and the need for readPass2+3 is reduced if not removed entirely.

A light version of this would be to make CvXMLLoadUtility::LoadPlayerOptions load types of selected files and then not touch the rest of the loading code. This will likely be easier to write and with less risk of messing up.

In CyEnumsPythonInterface(), I added
PHP:
    static bool bFirstRun = true;
    if (bFirstRun)
    {
        bFirstRun = false;
    }
    else
    {
        // run this function on reloads, thorugh skip it the first time as it is handled later in the xml reading order
        CyEnumsPythonInterfacePostApply();
    }
This means CyEnumsPythonInterfacePostApply won't be called the first time this function is called, but if somebody changes python files, they will be reloaded and CyEnumsPythonInterface will be called again, this time it will call CyEnumsPythonInterfacePostApply. This allows placing part of the loading process after all xml data has been read.

I even added a vector to allow adding a class first and then add more values to it in CyEnumsPythonInterfacePostApply. You can read my cpp file for details on how that works.

it fails to compile, ( i probably did the == wrong) but still fails.
The issue is indeed the ==. You are comparing two wchar pointers, which isn't what you want to do as you compare the address of the two pointer. This will be false even if the string values of both happens to be the same. You want to compare two strings.
PHP:
if (CvWString(GC.getEventTriggerInfo(eTrigger).getText()) == L"EVENTTRIGGER_PALACE_UPGRADE")
Here it creates a CvWString, uses the wchar pointer as a constructor and then it compares using the overloaded == operator of CvWString, which will then do what you expect it to do. The nameless CvWString will go out of scope and clean itself up as soon as you are done with the if testing. Also getText doesn't take an argument.

You may also want to consider breaking out of the loop once you have found the value you are looking for. Nothing bad will happen from continuing the loop, but this thread is about performance, so it should be pointed out.

Do note that vanilla will not have loaded EventTriggerInfos when DLLPublishToPython is called, hence GC.getNumEventTriggerInfos() will return 0 unless you mod xml loading order.
 
Last edited:
oh thanks for the info first.
My mod is based on AdvCiv, which i know you and f1rpo had exchange of knowledge as he used lots of stuff from WTP.
there are calls for readpas2 in advciv which i used for civics that i did .
ill compare the cpp you gave to mine, and try to mimic it with what you wrote as well. im not a cpp programmer so i dont have the basics acctually.

ill the .CvWString wrap, amd yes i forgot the "break" on the loop, tnx, just wrote a test code...

i hope i wont get complicated with this.
what if ill save a cached variable in the globals? of game?
 
what if ill save a cached variable in the globals? of game?
You can always do this:
PHP:
int localVariable = 0;
const int& variable = localVariable;
Header
PHP:
extern const int& variable;
This will make variable globally available, but it's read only. You can write to localVariable, but only in the same cpp file as the one declaring it. This means you can add a function in that cpp file, which sets localVariable to whatever you want, call that function after the data has been read from xml and then never again. That will make it act like an enum value, except it is set according to xml at runtime rather than the enum setup where it is set at compile time.

Naturally you can also add more variables to CvGlobals if you like. There is no upper limit.

My mod is based on AdvCiv, which i know you and f1rpo had exchange of knowledge as he used lots of stuff from WTP.
I know it has my first version of EnumMap in it (before I made it an overly complex template system), but I'm not aware of anything shared related to xml loading or caching.
 
"extern "
i didnt know. cool
by saving it, it will just let me read what is the index of the event i need.
so i wont have to read the string as before.
so that can work i guess.

size of the game/globals -> does it affect save game size? or such?

"I know it has my first version of EnumMap in it (before I made it an overly complex template system), but I'm not aware of anything shared related to xml loading or caching."
i see.
 
size of the game/globals -> does it affect save game size? or such?
No. Vanilla saves some cache in savegames and you can reduce the file size by not doing that and instead recalculate on load. However how to do that would be off topic for this thread. I feel like I hijacked it quite a bit already, but I do try to stay on topic.
 
I have read some C2C code, I found many cache in CvCity and CvPlayer
Before adding a cache for something try to optimize the code. A cache can introduce alot of problems when the cache invalidation isn't done correctly.

When you start a mod using another mod as base try to evaluate all the existing caching and only keep the absolutely necessary caches.
 
Top Bottom