Pluggable Factories & unecessary statics

Discussions related to programming Transport Empire.

Moderator: Transport Empire Moderators

Post Reply
User avatar
iLess
Engineer
Engineer
Posts: 38
Joined: 23 Apr 2006 01:21

Pluggable Factories & unecessary statics

Post by iLess »

Hey Hellfire.

I looked a little at your code. I like the PacketFactory approach but i think it could be written more flexible. As it is now, for each new Packet you define, the factory code has to be changed too. I will change it a little so this is not necessary anymore. Look at this: http://www.gamedev.net/reference/articl ... cle841.asp. Its a really elegant solution.

I noticed that you put in every file:

Code: Select all

  static std::string Author;
  static std::string Name;
  static std::string Abbreviation;
  static long Count;
Whats the use of those variables? I don't see why we should have those everywhere. They will be compiled and put into the final executable where they serve no purpose. I don't think that someone will suddenly feel the urge to upen the binary file in a Hexeditor and to look around for the Authors name ;-)
Grunt
Route Supervisor
Route Supervisor
Posts: 449
Joined: 03 Oct 2003 20:22
Location: Edmonton, Alberta
Contact:

Post by Grunt »

I recall uzurpator insisting on these ages ago, though I have no idea why. If I can dig out the rationale in the threads I will do so.

EDIT: it seems this was brought up in the coding standard thread. I brought up this point; it was never addressed. uzurpator appears to have added these into the coding standard and I guess refused to remove them, so I'm not sure why we have them or why they're still there.
Grunt
(aka Stephan Grunt, CEO of Grunt Transport Inc. since 1994.)
Hellfire
Transport Empire Developer
Transport Empire Developer
Posts: 699
Joined: 03 Feb 2003 09:30
Location: Back at the office

Post by Hellfire »

Yeah, I started coding with Uzurpator's coding standard in mind. I don't see why we should keep those static variables. On the other hand, they don't cause much extra load on the CPU or memory, so I kept it the way it was.

The "Count" variable can be very useful, though. Imagine an assertion before each "Count--":

Code: Select all

assert(1 <= Count);
Count--;
This should bork whenever a double free() is done.
iLess wrote:I like the PacketFactory approach but i think it could be written more flexible. As it is now, for each new Packet you define, the factory code has to be changed too. I will change it a little so this is not necessary anymore. Look at this: http://www.gamedev.net/reference/articl ... cle841.asp. Its a really elegant solution.)
I just skimmed through that article. I haven't seen the details, but the idea is clear to me: the factories are registered at program startup (thanks to the static variable) and each factory can specify which packet type they can handle. It could be faster than the switch() approach too. (Although I think switch statements are logarithmic in current compilers). This approach is great! It'll take a little time to convert the current implementation, but It'll make future extensions a lot easier.
Feel free to contact me over Email! My current timezone: Europe/Amsterdam (GMT+1 or GMT+2)

Code: Select all

+------------Oo.------+
| Transport Empire -> |
+---------------------+
[ General TE Discussion ] [ TE Development ] [ TE Coding ]
Under construction...
User avatar
iLess
Engineer
Engineer
Posts: 38
Joined: 23 Apr 2006 01:21

Post by iLess »

Yes the Count can be of use, but not for classes like Server or Client. More for the ones we instantiate very often. BTW. you didn't answer to the Factory part of my msg. I sat down today and coded a little bit around.
Here is what i got: http://tempire.selfip.org/index.php/All ... le_Factory. Haven't found out yet how i can upload files to the wiki, so i put just the essential stuff there. If you want to use it you need the Boost.Preprocessor Library.
Hellfire
Transport Empire Developer
Transport Empire Developer
Posts: 699
Joined: 03 Feb 2003 09:30
Location: Back at the office

Post by Hellfire »

iLess wrote:Yes the Count can be of use, but not for classes like Server or Client. More for the ones we instantiate very often. BTW. you didn't answer to the Factory part of my msg.
I thought I did:
Hellfire wrote:I just skimmed through that article. I haven't seen the details, but the idea is clear to me: the factories are registered at program startup (thanks to the static variable) and each factory can specify which packet type they can handle. It could be faster than the switch() approach too. (Although I think switch statements are logarithmic in current compilers). This approach is great! It'll take a little time to convert the current implementation, but It'll make future extensions a lot easier.
iLess wrote:I sat down today and coded a little bit around.
Here is what i got: http://tempire.selfip.org/index.php/All ... le_Factory. Haven't found out yet how i can upload files to the wiki, so i put just the essential stuff there. If you want to use it you need the Boost.Preprocessor Library.
What do these boost things do?
Feel free to contact me over Email! My current timezone: Europe/Amsterdam (GMT+1 or GMT+2)

Code: Select all

+------------Oo.------+
| Transport Empire -> |
+---------------------+
[ General TE Discussion ] [ TE Development ] [ TE Coding ]
Under construction...
User avatar
iLess
Engineer
Engineer
Posts: 38
Joined: 23 Apr 2006 01:21

Post by iLess »

What boost things you mean? The Preprocessor Macros?
They generate 8 versions of the same function starting with 1 argument (only the key for the map) and going up to 8 additional template and method parameters. If you run the compiler just in preprocessing mode you will basically get this (but each method will be on a single line, so i had to format it a little):

Code: Select all

T* GenerateObject(K key ) const 
{ 
  T* retval = 0; typename std::map<K,G>::const_iterator it = m_generators.find(key); 
  if (it != m_generators.end()) 
    retval = it->second(); 
  return retval; 
}


template < class A1 > 
  T* GenerateObject(K key , A1 arg1) const 
  { 
    T* retval = 0; 
    typename std::map<K,G>::const_iterator it = m_generators.find(key); 
    if (it != m_generators.end()) 
      retval = it->second( arg1); 
    return retval; 
  }


template < class A1 , class A2 > 
  T* GenerateObject(K key , A1 arg1 , A2 arg2) const 
  { 
    T* retval = 0; 
    typename std::map<K,G>::const_iterator it = m_generators.find(key); 
    if (it != m_generators.end()) 
      retval = it->second( arg1 , arg2); 
    return retval; 
  }


template < class A1 , class A2 , class A3 > 
  T* GenerateObject(K key , A1 arg1 , A2 arg2 , A3 arg3) const 
  { 
    T* retval = 0; 
    typename std::map<K,G>::const_iterator it = m_generators.find(key); 
    if (it != m_generators.end()) 
      retval = it->second( arg1 , arg2 , arg3); 
    return retval; 
  }


template < class A1 , class A2 , class A3 , class A4 > 
  T* GenerateObject(K key , A1 arg1 , A2 arg2 , A3 arg3 , A4 arg4) const  
  { 
    T* retval = 0; 
    typename std::map<K,G>::const_iterator it = m_generators.find(key); 
    if (it != m_generators.end()) 
      retval = it->second( arg1 , arg2 , arg3 , arg4); 
    return retval; }

//and so on until GENERATE_MAX_PARAMS is reached

If you really want to understand how it works look at the Boost Preprocessor library. This stuff is called Preprocessor Metaprogramming because it generates source-code using the Preprocessor. So these Macros are "Meta-Functions". It is also possible to do metaprogramming with templates. This is really powerfull stuff, but at first sight maybe a little hard to understand. I had to read a book about it to fully understand how it works. But it is REALLY worth it! (here's the page of the book: http://boost-consulting.com/mplbook/. Basically you can use the Compilers Prerprocessor or its Template-Facility to do calculations on Types. You can run the Compiler like a Touring-Machine (although a not very fast one). I actually wrote a little program once that made the compiler simulate a one-dimensional mechanical system, just using templates! As the compiler was finished with compiling, the simulation results could be read out from an array inside the executable ;-). So the only thing the App did at runtime, was just read out the result-Array. This worked on gcc3.5 but unfortunately they changed something in gcc4 and now it does not work anymore :-(. Maybe it is just because my gcc4 was altered by Apple. It would be cool if someone could check, whether it works with his compiler, or tell me the errors he gets. The source can be obtained here: http://tempire.selfip.org/index.php/COTOS
User avatar
iLess
Engineer
Engineer
Posts: 38
Joined: 23 Apr 2006 01:21

Post by iLess »

Hellfire wrote:This approach is great! It'll take a little time to convert the current implementation, but It'll make future extensions a lot easier.
I did that already. But as I couldn't find out how to upload my source to the Wiki, i didn't post all of it there. It always says:

".zip" is not a recommended image file format.

Does anyone know where i can make it a recommended format?
Post Reply

Return to “Transport Empire Coding”

Who is online

Users browsing this forum: No registered users and 5 guests