Author Topic: [solved] Crash in handling empire stats and research web  (Read 992 times)

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
[solved] Crash in handling empire stats and research web
« on: August 05, 2012, 09:31:00 PM »
[SOLVED] Code updated to reflect the change

I have all my scripted governors calling the following code in order to grab the tech levels of the empire owning the planet.
Code: [Select]
const string@ str_Science="Science", str_EnergyPhysics="EnergyPhysics",
str_Materials="Materials", str_ParticlePhysics="ParticlePhysics",
str_Gravitics="Gravitics", str_WarpPhysics="WarpPhysics",
str_Metallurgy="Metallurgy", str_Chemistry="Chemistry",
str_Economics="Economics", str_Sociology="Sociology",
str_Biology="Biology", str_BeamWeapons="BeamWeapons",
str_Shields="Shields", str_Stealth="Stealth",
str_ProjWeapons="ProjWeapons", str_Missiles="Missiles",
str_Engines="Engines", str_ShipConstruction="ShipConstruction",
str_Nanotech="Nanotech", str_ShipSystems="ShipSystems",
str_Cargo="Cargo", str_Computers="Computers",
str_Sensors="Sensors", str_Armor="Armor",
str_MegaConstruction="MegaConstruction";

//when executed, will analyze an empires current tech levels and buffer those level
// values to empire state variables for more thread friendly read-only access.
void pushTechLvls( Empire@ emp ) {
ResearchWeb web;
web.prepare(emp);

//TODO: would an object lock benifit me here?
if( web.isTechVisible(str_Science) ) emp.setStat(str_Science, web.getItem(str_Science).level);
if( web.isTechVisible(str_EnergyPhysics) ) emp.setStat(str_EnergyPhysics, web.getItem(str_EnergyPhysics).level);
if( web.isTechVisible(str_Materials) ) emp.setStat(str_Materials, web.getItem(str_Materials).level);
if( web.isTechVisible(str_ParticlePhysics) ) emp.setStat(str_ParticlePhysics, web.getItem(str_ParticlePhysics).level);
if( web.isTechVisible(str_Gravitics) ) emp.setStat(str_Gravitics, web.getItem(str_Gravitics).level);
if( web.isTechVisible(str_WarpPhysics) ) emp.setStat(str_WarpPhysics, web.getItem(str_WarpPhysics).level);
if( web.isTechVisible(str_Metallurgy) ) emp.setStat(str_Metallurgy, web.getItem(str_Metallurgy).level);
if( web.isTechVisible(str_Chemistry) ) emp.setStat(str_Chemistry, web.getItem(str_Chemistry).level);
if( web.isTechVisible(str_Economics) ) emp.setStat(str_Economics, web.getItem(str_Economics).level);
if( web.isTechVisible(str_Sociology) ) emp.setStat(str_Sociology, web.getItem(str_Sociology).level);
if( web.isTechVisible(str_Biology) ) emp.setStat(str_Biology, web.getItem(str_Biology).level);
if( web.isTechVisible(str_BeamWeapons) ) emp.setStat(str_BeamWeapons, web.getItem(str_BeamWeapons).level);
if( web.isTechVisible(str_Shields) ) emp.setStat(str_Shields, web.getItem(str_Shields).level);
if( web.isTechVisible(str_Stealth) ) emp.setStat(str_Stealth, web.getItem(str_Stealth).level);
if( web.isTechVisible(str_ProjWeapons) ) emp.setStat(str_ProjWeapons, web.getItem(str_ProjWeapons).level);
if( web.isTechVisible(str_Missiles) ) emp.setStat(str_Missiles, web.getItem(str_Missiles).level);
if( web.isTechVisible(str_Engines) ) emp.setStat(str_Engines, web.getItem(str_Engines).level);
if( web.isTechVisible(str_ShipConstruction) ) emp.setStat(str_ShipConstruction, web.getItem(str_ShipConstruction).level);
if( web.isTechVisible(str_Nanotech) ) emp.setStat(str_Nanotech, web.getItem(str_Nanotech).level);
if( web.isTechVisible(str_ShipSystems) ) emp.setStat(str_ShipSystems, web.getItem(str_ShipSystems).level);
if( web.isTechVisible(str_Cargo) ) emp.setStat(str_Cargo, web.getItem(str_Cargo).level);
if( web.isTechVisible(str_Computers) ) emp.setStat(str_Computers, web.getItem(str_Computers).level);
if( web.isTechVisible(str_Sensors) ) emp.setStat(str_Sensors, web.getItem(str_Sensors).level);
if( web.isTechVisible(str_Armor) ) emp.setStat(str_Armor, web.getItem(str_Armor).level);
if( web.isTechVisible(str_MegaConstruction) ) emp.setStat(str_MegaConstruction, web.getItem(str_MegaConstruction).level);

return;
}

const string@ str_TechUpdateAllowed="str_TechUpdateAllowed";

//thread lock friendly tech level assessment
void popTechLvls( Empire@ emp
, float &out rlvl_city, float &out rlvl_farm, float &out rlvl_prod, float &out rlvl_cnst
, float &out rlvl_port, float &out rlvl_crgo, float &out rlvl_scif ) {

//TODO: would an object lock benifit me in this method ?
double update = emp.getStat(str_TechUpdateAllowed);
if( update < gameTime ) {
emp.postMessage("Buffering current tech levels");
pushTechLvls(emp);
emp.setStat(str_TechUpdateAllowed, gameTime + 30.0f);
}

rlvl_city = max(1.00, emp.getStat(str_Sociology));
rlvl_farm = max(0.75, emp.getStat(str_Biology));
rlvl_prod = max(1.00, emp.getStat(str_Metallurgy));
rlvl_cnst = max(1.00, emp.getStat(str_ShipConstruction));
rlvl_port = max(1.00, emp.getStat(str_Economics));
rlvl_crgo = max(1.00, emp.getStat(str_Cargo));
rlvl_scif = max(1.00, emp.getStat(str_Science));
}

Instantly when turning a governor on the game will lock up and crash with no useful information in the log.txt file.  Effectively what is happening is that each time a governor checks the tech levels of an empire it will pull those values from a set of temporary stats assigned to the empire. Only if those temporary values have not been updated in over 30 seconds will it call the research web.

The purpose of this is that calling the research web performs a thread lock, which will cause multiple threads executing governors to temporarily stall each other. Anytime after early gave I have had horrible reaction time from my scripted governors and im trying to eliminate all possible sources of inefficiency.

If anyone can see what could be causing a crash (probably a simple oversight) please let me know
« Last Edit: August 06, 2012, 09:20:29 AM by seronis »
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

Azalrion

  • Delusional
  • ****
  • Posts: 1325
  • Karma: +147/-1
  • Memory Murderer
    • View Profile
Re: Crash in handling empire stats and research web
« Reply #1 on: August 06, 2012, 12:32:44 AM »
The only thing I can think of is were you playing with all techs unlocked or not? A reoccuring theme in research web handling is that there is always an if check to see if the WebItem is visible before attempting to access its details first. That might have something to do with it but quite possibly not.

As for inefficiency since the AI will use your governors so you can guarantee that it will always be needed you could move it out of the governor scripts into a separate tick event and just update it for all empires at the same time since each planet's governor doesn't need to call it itself as doing it once sets it up for all of them (the setting the stat function that is).
« Last Edit: August 06, 2012, 12:38:20 AM by Azalrion »
GA - Mod Team
GA Forums

Jyin

  • Sentient
  • **
  • Posts: 66
  • Karma: +6/-0
    • View Profile
Re: Crash in handling empire stats and research web
« Reply #2 on: August 06, 2012, 01:20:41 AM »
Azalrion is correct, web.getItem() can return null, even if the name of tech is correct, when it is still locked.
Also, it is generally good idea to use the access method, rather than direct reference.

so I would go with:
if( web.getItem(str_XXX) !is null )
   emp.setStat( str_XXX, web.getItem(str_XXX).get_level() )

Azalrion

  • Delusional
  • ****
  • Posts: 1325
  • Karma: +147/-1
  • Memory Murderer
    • View Profile
Re: Crash in handling empire stats and research web
« Reply #3 on: August 06, 2012, 01:30:27 AM »
Azalrion is correct, web.getItem() can return null, even if the name of tech is correct, when it is still locked.
Also, it is generally good idea to use the access method, rather than direct reference.

so I would go with:
if( web.getItem(str_XXX) !is null )
   emp.setStat( str_XXX, web.getItem(str_XXX).get_level() )

Wouldn't do that either, two calls is kind of unnecessary use something like:

Code: [Select]
if(web.isTechVisible(str_XXX)
   emp.setStat( str_XXX, web.getItem(str_XXX).get_level() )

Still the reason I say it might not be that is because I would have expected the error handler to pick up on it and throw a null pointer error.
« Last Edit: August 06, 2012, 01:43:19 AM by Azalrion »
GA - Mod Team
GA Forums

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Crash in handling empire stats and research web
« Reply #4 on: August 06, 2012, 07:35:46 AM »
Didnt know it returned null for locked techs, had assumed null was just for misspelled names. But i was testing with all techs unlocked and set to lvl 20. Still have to adjust it to make it null safe I guess. Will test again a little later.
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.

seronis

  • Distracted
  • ***
  • Posts: 338
  • Karma: +25/-0
    • View Profile
    • Steam Profile Link
Re: Crash in handling empire stats and research web
« Reply #5 on: August 06, 2012, 09:18:43 AM »
And crash is gone.  Thanks guys, the null checks was all that was required
« Last Edit: August 06, 2012, 09:21:49 AM by seronis »
Any code/mods I post on this site should be considered Public Domain. Borrow it, steal it, shred it into little pieces to your hearts content. I dont require credit but I appreciate bug fixes and suggestions.