Mark,

Thanks for the clarification. I'm not familiar with python, so I'm not entirely sure how to take the pseudocode provided. If I read it correctly, it's some thing like this in C++:

class Skill
{
//C style: void (*func_ptr)(Skill &) = 0;
   //C++ style (not going to use because I "can't")
   void (Skill::*func_ptr)(Skill &) = 0;
}

And now a non-member function:
void cast_code(Skill &x_skill)
{
   <some crap>
}

And do this:
Skill s;
s.func_ptr = &cast_code;

And to execute:
(s.*func_ptr)(&s);


This is fine and will probably be what I will end up doing (I actually just finished making a separate library for skill code, but decided it was overkill), but I originally wanted each Skill to have its cast code as a member method. This isn't much different, but there's a small problem, only because I'm allowing skills to be made in-game. What do I mean? I'll try to show you:

class Skill
{
   public:
       string name;
       int mana;
//don't have to pass a Skill ref, now. void (Skill::*cast_ptr)(void) = 0;
   private:
      void spell1_cast_code(void);
      void spell2_cast_code(void);
      ...
      void ray_of_light_cast_code(void);
}

Spell 1's cast code is somewhere in the MUD's loading linked to spell1_cast_code, and Spell 2 the same.
e.g.
void MUD_skill_loading_function(void)
{
   vector<Skill> skills;
Skill s, t; ...
   s.cast_ptr = &spell1_cast_code;
   skills.push_back(s);
   ...
   t.cast_ptr = &spell2_cast_code;
   skills.push_back(t);
}

And that's fine, and what I want.  The problem, though, is this line:
   s.cast_ptr = &spell1_cast_code;

Since I'm loading the skills from disk, I don't know how to link a loaded skill's functions to it. To solve this originally, I have the code write itself a table to be used when the MUD was recompiled:
const struct skill_code_type skill_code_table[] =
{
   {"spell1", spell1_cast_code}
   ...
   {"ray of light", ray_of_light_cast_code}
};

And to "link" each Skill to its functions:
void MUD_skill_loading_function(void)
{
   vector<Skill> skills;
Skill s; for (int position = number of skills on disk)
   {
       s.<load_skill_from_disk>;
       s.assign_code(position);
       skills.push_back(s);
       }
}

void Skill::assign_code(const int foo)
{
   cast_code = skill_code_table[foo].cast_code;
}

I do not know how to do this cleanly using member methods. Hmm, actually, maybe instead of writing a table, I could just write out the assignments "hard code". Hackish, but it'd work:

//This file/function generated by code elsewhere
extern vector<Skill> skills;
void generated_skill_code_assignment_function(void)
{
   skills[0].cast_code = &spell1_cast_code;
   ...
   skills[20].cast_code = &ray_of_light_cast_code;
}

This actually could be accomplished with about 20 lines of code, I think.


I may still be entirely missing your point, but I think that because the function pointer in the Skill is pointed -whenever the MUD feels like it- (not the compiler, not the linker) it complicates matters a bit.

Thank you for your help so far--you've really helped. I gladly welcome any further suggestions.

-- Jeremy


Mark Roberts wrote:

Jeremy,

Actually, if you read my message VERY carefully (I did some editing and didn't 
exactly read over it before I rushed off to work), I presented two seperate 
methods for solving the problem.

The first method is with "function pointers" (or God forbid, functors...).  The 
second method was with member functions.

def cast_code(self):
 """some function to cast spells or something"""

def cast_code2(self):
 """some other function to cast spells or something"""

class Skill:
 self.name=""
 self.mana=0
 self.cast_code=cast_code
#...

s=Skill()
s.cast() # Exec's cast_code

s=Skill()
s.cast_code=cast_code2
s.cast()

Function pointer method.  If you truly need an example of the function pointer syntax (to 
member functions... believe me this is an ugly mess and is one of the best reasons NOT to 
use C++ for something like this...), I'm sure I can dig one up in my "Archive".

The second method was the function method, and isn't the method that I'd 
recommend.  As far as overhead goes, you won't be incurring any additional 
overhead unless you're programming things in a silly way (like recursion or 
with excessive usage of virtual functions.  Even then virtual functions are a 
single dereference away as far as efficiency!).

Note that the 2nd method is probably the simplest method, though there might be 
some repeated code (and hence a larger compile size).  I doubt it'd cause 
anything more than memory bload to have each and every skill have the same 
functions.   Though another solution might be to use inheritance to inherit the 
function in ... but nheritance is another matter entirely. :-)

Regards,
Mark



Reply via email to