|
Call Function By Name
Submitted by |
This code illustrates how one can call a function using a string literal, or a char *
this makes it very useful for in-game command consoles, or scripting languages, or whatever you want.
All you have to do to call the function is
CallFunctionByName("MyFunction", args);
or
strcpy(funcCaller, "MyFunction");
CallFunctionByName(funcCaller, args);
(For the reference: This code uses a modified version of John W. Ratcliff's StringTable class - Thanks John!)
Happy Coding
|
Currently browsing [CallFunc.zip] (32,369 bytes) - [test.cpp] - (2,484 bytes)
/* File: test.cpp
* Author(s): Michael Deardeuff <mr__goodbytes@hotmail.com
* Description:
* Tests the CallFunctionByName Routine
* Notes:
* Copyright (C) 2000 Michael Deardeuff
* You may use this code in anything you want as long as you keep the copyright notices intact
*/
#ifdef _MSC_VER // >= 1200 // For MSVC++ Only (6.0+ in comments)
#pragma warning(disable :4786) // Disable all those pesky warnings you get
#endif // _MSC_VER // from using the STL
#include <map>
#include "mgTable.h"
#include "function.h"
/*
extern "C"
{
StringTable functionTable;
std::map<char *, FunctionPointer> mFunction;
}
*/
void FunctionTableInit();
int main()
{
FunctionTableInit();
bool done=false;
char buf[32];
do
{
printf("Enter name of function in function table\n");
printf("Or enter 'bye', 'quit', or 'end' to exit:\n");
printf("Currently only HoserChild and MrGoodbytes\n");
printf("are valid function names\n\nFunction: ");
// Get Function name
if( fgets( buf, sizeof( buf ), stdin ) == NULL )
{
done = true;
break;
}
// remove the trailing '\n' from string
strchr(buf, 10)[0] = '\0'; // isn't that ugly :C
String command = buf;
// see if user wants to quit
if ( command == "bye" || command == "end" || command == "quit" )
{
done = true;
break;
}
else
{
// enter "arguments"
printf("\nEnter a string to pass as an argument\nArgs: ");
command = buf;
if( fgets( buf, sizeof( buf ), stdin ) == NULL )
{
done = true;
break;
}
printf("\n\n-------------------------------------------\n\n");
if (!CallFunctionByName((char *)command.c_str(), buf))
printf("\n%s is not in the Callable Function Table\n\n", command.c_str());
}
} while ( !done );
printf("\n\n---------------------------------\n\n");
// Can also be called with a string literal:
CallFunctionByName( "MrGoodbytes", (void *)"Goodbye");
return 0;
}
// Add the functions to the list
void FunctionTableInit()
{
AddFunction("HoserChild", HoserChild);
AddFunction("MrGoodbytes", MrGoodbytes);
AddFunction("NullFunc", NULL);
};
/**** The User Callable Functions ********************************************/
void HoserChild(void *args)
{
printf("HoserChild says:\n%s\n", (char *)args);
}
void MrGoodbytes(void *args)
{
printf("Mr Goodbytes' own personal function:\n%s\n", (char *)args);
} |
|
Currently browsing [CallFunc.zip] (32,369 bytes) - [CallFunc.cpp] - (2,967 bytes)
/* File: CallFunc.cpp
* Author(s): Michael Deardeuff <mr__goodbytes@hotmail.com>
* Description:
* Implements CallFunctionByName() and AddFunction() methods
* Notes:
* Copyright (C) 2000 Michael Deardeuff
* You may use the code in whatever you want as long as the copyright notice stays intact.
* Usage:
* To use these to functions(methods if you prefer), you first add the function to the
* "Callable Function List" by calling AddFunction() with the name you wish to give the
* function, and the function itself. Then to call the function in your code, you invoke
* CallFunctionByName() with the name you gave the function, and any arguments you may wish.
* to pass to the function.
* Example:
*
* void CallMeFunc(void *args)
* {
* // Do Something...
* }
*
* int main()
* {
* char funcCaller = "MyFunction"; // for later
*
* // Add the Function to the "Callable Function List"
* AddFunction("MyFunction", CallMeFunc);
*
* // Call the function in a variaty of ways
* CallFunctionByName("MyFunction", NULL);
* CallFunctionByName(funcCaller, NULL);
*
* // ...
* return 0;
* }
*
* I find this useful when using a scripting language, or a console debugger in your game.
* Happy Coding!
* -Michael Deardeuff
*/
#ifdef _MSC_VER // >= 1200 // For MSVC++ Only (6.0+ in comments)
#pragma warning(disable :4786) // Disable all those pesky warnings you get
#endif // _MSC_VER // from using the STL
#include <map>
#include "mgTable.h"
#include "function.h"
// For use by our "map"
class FunctionPointer
{
public:
void (*pFunc)(void *args);
};
StringTable functionTable;
std::map<char *, FunctionPointer> mFunction;
/* CallFunctionByName():
* Calls a function associated with to a string name
* Functions must be added to callable list via AddFunctions()
*/
bool CallFunctionByName (char * pName, void * args)
{
char * result;
// If the name is in the list, call it;
if (functionTable.IsIn(pName))
{
result = (char*)functionTable.Get(pName);
mFunction[ result ].pFunc( args ); // this is a good thing about maps
return true; //Ok
}
return false; // Didn't happen
}
/* AddFunction():
* Adds functions and their associated strings to the list
* callable by CallFunctionName
* returns true if successful
*/
bool AddFunction(char * pName, void (*pFunc)(void *args))
{
FunctionPointer fp;
char * result;
// Test to see whether pFunc is valid, and whether
// pName is already listed in the set
if ((pFunc != NULL) && (functionTable.IsIn(pName)))
return false; // Already something with that name in list
// Puts name in the function table
result = (char *) functionTable.Get(pName);
// Assign the function pointer to the map
// with the above result as the key
fp.pFunc = pFunc;
mFunction[result] = fp;
return true; // Ok
} |
|
Currently browsing [CallFunc.zip] (32,369 bytes) - [function.h] - (520 bytes)
#ifndef FUNCTION_H
#define FUNCTION_H
#ifdef _MSC_VER // >= 1200 // For MSVC++ Only (6.0+ in comments)
#pragma warning(disable :4786) // Disable all those pesky warnings you get
#endif // _MSC_VER // from using the STL
// Defines (or includes) all callable functions for use of Call...ByName()
bool CallFunctionByName (char * pName, void* args);
bool AddFunction(char *pName, void (*pFunc)(void *args));
void HoserChild(void *args);
void MrGoodbytes(void *args);
#endif // FUNCTION_H |
|
Currently browsing [CallFunc.zip] (32,369 bytes) - [mgTable.cpp] - (2,172 bytes)
/* File: mgTable.cpp
* Author(s): John W. Ratcliff <jratcliff@verant.com>
* Michael Deardeuff <mr__goodbytes@hotmail.com>
* Descripton:
* Implements the StringTable class. For a better description, consult "sTable.h"
* Notes:
* John W. Ratcliff made about 99% of this. All thanks go to him
* Michael Deardeuff just added IsIn() for use of CallFunctionByName
*/
#ifdef _MSC_VER // >= 1200 // For MSVC++ Only (6.0+ in comments)
#pragma warning(disable :4786) // Disable all those pesky warnings you get
#endif // _MSC_VER // from using the STL
#include <string.h>
#include <string>
#include <set>
#include "mgTable.h"
// Compares two strings, returns true if first is less than second (used by std::set)
bool CharPtrLess::operator()(const char *v1,const char *v2) const
{
int v = strcmp(v1,v2);
if ( v < 0 )
return true;
return false;
}
// Clean up.
StringTable::~StringTable(void)
{
CharPtrSet::iterator i;
for (i=mStrings.begin(); i!=mStrings.end(); i++)
{
char *str = (char *)(*i);
delete str;
}
}
/* Get():
* Searches the set, seeing if "str" is already in set.
* If so, returns a pointer to the string, If not,
* creates a new string, and returns a pointer to
* the newly allocated string;
*/
const char * StringTable::Get(const char *str)
{
CharPtrSet::iterator found;
// Search the set for str
found = mStrings.find( str );
// if found return pointer to the original string
if ( found != mStrings.end() )
return (*found);
// create a new string identical to "str"
int lngth = strlen(str);
char *mem = new char[lngth+1];
strcpy(mem,str);
// insert new string into the set, and return a pointer
mStrings.insert( mem );
return mem;
}
/* IsIn():
* Searches the set for occurance of "str". Returns True
* if found, false if not
*/
bool StringTable::IsIn(const char *str)
{
CharPtrSet::iterator found;
found = mStrings.find( str );
if (found != mStrings.end())
return true;
return false;
}
const char * StringTable::Get(const String &str)
{
return Get( str.c_str() );
}
|
|
Currently browsing [CallFunc.zip] (32,369 bytes) - [mgTable.h] - (4,189 bytes)
#ifndef MR_GOODBYTES_TABLE_H
#define MR_GOODBYTES_TABLE_H
#ifdef _MSC_VER // >= 1200 // For MSVC++ Only (6.0+ in comments)
#pragma warning(disable :4786) // Disable all those pesky warnings you get
#endif // _MSC_VER // from using the STL
#include <string.h>
#include <string>
#include <set>
// This class implements a 'stringtable'. It is being released into
// the public domain on September 27, 2000 by John W. Ratcliff
// jratcliff@verant.com for FlipCode.com as part of the 'code of they day'
// project.
//
// What the heck does a 'StringTable' class do for me? What a StringTable
// is used for is to manage a collection of shared strings across a package.
// It is primarily used for tokens, keywords, asset names, etc. You do
// *NOT* want to use the StringTable for any cases which could produce
// an infinite number of strings. This is only for managing a finite list
// of keywords.
//
// The reason you use a string table is so that you can keep track of items
// by ASCII name instead of some non-intutitive and arbritrary id number.
// Normally it is not practical to make a container class who's key is
// an STL string. First of all there is a memory overhead, and additionally
// there is a serious peformance penalty. However, with the StringTable
// class, instead you can keep track of a list of items where the key is
// a pointer to the string, instead of the string itself. Now you can
// compare if 'two strings are equal' simply by comparing if their address
// is the same. Remember that any container class which uses this pointer as
// a key is *NOT* in alphabetical order!! It's ordered based on the address
// in memory of the string itself. But that doesn't matter, because the
// purpose of the container is not to maintain an alphabetical list of
// items but rather to simply locate items *BY NAME* extremely quickly.
//
// Using a stringtable makes it trivial to keep ASCII names and descriptions
// as member variables in all of your classes. This makes debugging and
// debug output vastly simpler.
//
// Example: Say you contruct a new intance of a Vehicle class. In it's
// constructor you might have something like:
//
// mObjectName = gStringTable.Get("vehicle");
//
// Where mObjectName is a member variable of type 'const char *' and
// gStringTable is some global instance of a shared string table across
// your application. Now, you can compare whether or not an object is of
// type 'vehicle' simply by comparing it's name to anybody else's name
// with the two pointers allocated with the same string table.
//
// This is extremely convenient for debugging, logging, etc.
//
// To create an STL map where you access every item *by name* all you
// have to do is:
//
// typedef std::map< const char * , Texture *> TextureMap;
//
// This would create an STL map that would allow you to quickly look
// up any texture by name. A fairly useful data structure.
//
// Example of how to locate a texture by name:
//
// **NOTE* texname must have been created by the same StringTable
//
// Texture * FindTexture(const char *texname)
// {
// TextureMap::iterator found; // STL map iterator to find item.
// found = mTextures.find( texname ); // search red/black tree
// if ( found != mTextures.end() ) return (*found).second;
// return 0; // no texture of this name found.
// }
//
// The string table implementation uses STL to maintain the collection
// of strings. If you change the comparator function in CharPtrLess
// from strcmp to stricmp then all of your strings will be created without
// case sensitivity, which is often the behavior you want for tokens and
// keywords.
typedef std::string String;
class CharPtrLess
{
public:
bool operator()(const char *v1,const char *v2) const;
};
typedef std::set< const char *, CharPtrLess > CharPtrSet;
class StringTable
{
public:
StringTable(void){}
~StringTable(void);
const char * Get(const char *str);
const char * Get(const String &str);
bool IsIn(const char *str);
private:
CharPtrSet mStrings;
};
#endif //MR_GOODBYTES_TABLE_H |
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|