logging

logging

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

Post Reply
greenail
Spring Developer
Posts: 80
Joined: 13 Dec 2005, 20:16

logging

Post by greenail »

is there a way to suppress logging? my last game generated about 800MB in logs. if there isn't i'd like to nominate it for the todo list. perhaps passing the decision to log to the ai would be prudent.

I would also like to see a GotChatMsg method in the groupAI.
Kelson
Posts: 76
Joined: 29 Oct 2005, 08:32

Post by Kelson »

Suppress logging? As in...the logging the debug header I sent you generated? Just comment out the output statements in void Send(). In general, you can set the AI-output threshhold in your game options. This corresponds to the IAICallback::SendTextMsg(msg,priority) - if your priority is higher than the option'd priority, then it will be ignored.

So, for the un-needed stuff, assign a lower priority. If you need, I can modify the debug header to take that into account (default 0, assign for your pleasure).
greenail
Spring Developer
Posts: 80
Joined: 13 Dec 2005, 20:16

Post by greenail »

no a lot of them were cant' read destination, and build pos blocked. i improved my code a bit and dont' see them soo much.
User avatar
Veylon
AI Developer
Posts: 174
Joined: 21 Sep 2005, 19:45

Post by Veylon »

I use a macro in my AI such like:

Code: Select all

#ifdef DOLOGGING
  #define LOG(a) GS->LogFile << a
#else
  #define LOG(a)
#endif
So I'll be releasing two DLL's, one with the DOLOGGING defined to produce logs and one without.
Kelson
Posts: 76
Joined: 29 Oct 2005, 08:32

Post by Kelson »

Veylon wrote:I use a macro in my AI such like:

Code: Select all

#ifdef DOLOGGING
  #define LOG(a) GS->LogFile << a
#else
  #define LOG(a)
#endif
So I'll be releasing two DLL's, one with the DOLOGGING defined to produce logs and one without.
What is GS? Also, a better solution (imo) is use inline functions (same functionality as #defines in this case, but safer) with default parameters. Inside the function, one could use a static that, based on the parameters (specified on, specified off, not-specified), could toggle logging on or off.

On second look - perhaps I misunderstood your comment and you'd meant two AI dlls (I was wondering why you were releasing logging dlls...doh...same suggestion though).
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

GS looks likes his global structure, just as I have G->L->print() to do similair things, G being the global structure and L the logging class.

I also have

L->open(bool plaintext=true) // if false then coloured plaintext logging is used
L->close()
L->print() //normal message
L->eprint() // exceptions errors etc
L->iprint() // print to console
L->gametime() // returns the gametime formatted in minutes hours and seconds rather than grame frame number.

All dealt with as std::string type.

edit:: oh and L->verbose() which if set to true outputs all logging to the screen
User avatar
Veylon
AI Developer
Posts: 174
Joined: 21 Sep 2005, 19:45

Post by Veylon »

The reason for using directives instead of inline functions is that with inline functions the code to write the logging is still compiled and when the function is called, it has to check to see whether the logging flag is enabled or not every time it comes up, costing a few CPU cycles. Not really a big deal, but that's why.
Kelson
Posts: 76
Joined: 29 Oct 2005, 08:32

Post by Kelson »

Veylon wrote:The reason for using directives instead of inline functions is that with inline functions the code to write the logging is still compiled and when the function is called, it has to check to see whether the logging flag is enabled or not every time it comes up, costing a few CPU cycles. Not really a big deal, but that's why.
I don't think you understand what 'inline' means in C/C++. Find out here!. Using #define is equivalent to __forceinline...in most cases - #define is a string replacement call, which can have unintended (and unobvious) consequences that the compiler can not warn you about. By using inline, you indicated to the compiler the code 'should' be inlined (though it makes the final choice...unless you use __forceinline) while maintaining all the safety checks of normal function calls (better compiler feedback / debugger utilization).
User avatar
Veylon
AI Developer
Posts: 174
Joined: 21 Sep 2005, 19:45

Post by Veylon »

Yes, but directives are applied before the code is compiled, so __forceinline never comes up. Thus:

Code: Select all

int a;
LOG(a);
int b;
Would convert to this with DOLOGGING defined:

Code: Select all

int a;
GS->LogFile << a;
int b;
and this without:

Code: Select all

int a;
;
int b;
Whereas, with a inline function, it would go something like this:

Code: Select all

_inline void LogFunction(bool Logging = false, char *Text)
{
  if(Logging)
    GS->LogFile << Text;
}
...
int a;
LogFunction(true, "Stuff");
int b;
and would be equivalent to this:

Code: Select all

int a;
if(Logging)
  GS->LogFile << "Stuff";
int b;
So that if statement would still have to be evaluated even if logging was disabled, costing a few insignificant CPU cycles.

I deliberately chose to use text replacement directives because of their flexibility as well as the fact that, if disabled, all logging code disappears entirely from the compiled DLL, costing no CPU cycles at run time.

As for debuggers, I haven't yet found any that work conveniently with a DLL or have I had any bugs that have been traced to my use of directives.
Kelson
Posts: 76
Joined: 29 Oct 2005, 08:32

Post by Kelson »

The compiler using version A or version B of the #define is irrespective of #define. It is based on the #ifdef - the same functionality exists with inline functions. For example, if I know I don't want my function to output anything in non-debug mode, then...

Code: Select all

inline void MyLogFunc(string Msg, bool output=true)
{
  #ifdef DebugMode
     if(output)   cout << Msg << endl;
  #endif
}
Same exact functionality, with none of the risks of #defines. I don't mean to sound like #defines are always a bad choice (there are some very cool and useful things one can do with them), but I think inline functions are more efficient, powerful, and safe in this case.

With that being said, one would need #defines to handle __LINE__ type macros in a meaningful, debug-oriented, way. For example...

Code: Select all

inline void MyLogFunc(string Msg, int LineNum, bool output=true)
{
  #ifdef DebugMode
     if(output)   cout << LineNum << ") " << Msg << endl;
  #endif
}

#define DebugLog(a)   MyLogFunc((a),__LINE__)
#define DebugLog(a,b) MyLogFunc((a),__LINE__,(b))
Post Reply

Return to “AI”