Archived

This topic is now archived and is closed to further replies.

mrhodes

Is this possible???

Recommended Posts

Hello, I working on making a simple scripting / text parsing system, and I was wanting to be able to load a text file with commands, and data to be stored. Then I got a bright idea! instead of having a massize switch statement to have all command options, why not make one text file, called settings.txt or whatever, and this file will store all the commands, and the functions name that is to be called in place of that command. Here is an example
// Sample settings file


print CDisplay::Print(char *data)
map CMap::LoadMap(char *mapname)
That would be something like what I want, and then for the script file itself, I would have:
// Script File

map "Level2.map"
print "Map loaded..."
Anyway, that''s what I first thought of... then I realized that maybe that''s not possible, becasue once my engine is compiled, the names (CDisplay::LoadMap, etc) really don''t mean a whole lot anymore. So, my question is this, is there a way this can be done?? I would like to do this, but I''m not sure how. Thanks for any help, Mike

Share this post


Link to post
Share on other sites
Oh, it''s doable - and without the switch statement.

Think for a moment. How do you set which functions are available from the text file, and which ones aren''t? You don''t want the user to be able to access everything...

Also, for some of the more commonly used functions, you might not want to use the same names in the text file as you do in code.

There''s also the problem of parameters - different functions will take different numbers and types of parameters.

This method - a ''function table'' approach - works if

  • all your functions have the same return type and the same arguments

  • you''re not dealing with functions which are members of classes (static functions are OK)

  • you''re prepared to add code to ''register'' all those functions with their name



That may seem a little restrictive, especially that first one. You can get round it - have all your functions take strings, and then write simple parsing routines to break the arguments that the function actually wants out of the string. Given that those arguments would be read from a text file to begin with, it''s pretty easy.

What you want is a map (probably std::map) of function names to function pointers. When executing a command in the script file, the processor can look up a function name in the map, get out the pointer, and call that pointer (passing the arguments from the file in a string).

That''s pretty simple. The other thing you need is the ability to ''register'' functions - add them to the map.

Superpig
- saving pigs from untimely fates, and when he''s not doing that, runs The Binary Refinery.

Share this post


Link to post
Share on other sites
The problem is, this kind of settings.txt file would work the same way as a switch anyway : looking through the file until you find the command, and print it.

Something else I would do is to "compile" the script file using a switch, turning each command into a structure with :
- A byte (the command)
- A void * (the parameters)

So effectively, the script becomes a struct array.

Then, I''d create an array of classes which all have a "virtual void Command( void * Params )" virtual function. Each index contains one particular class. For instance, if "Print" was turned into 0 then the class at index 0 would turn the params into a (char*) and print it, when "Command" is called. It is then quite simple to tie new classes to indexes (in the code), and then tie commands to indexes (in a side-file).

Besides, a DLL contains various things (objects, functions) that can be accessed by name (although these names are quite obfuscated, such as "?End@exText@@UAEXXZ". A program could read these library entry points from a file, then open them in the target library, and execute them (although how this could be done, I do not know).

ToohrVyk

Share this post


Link to post
Share on other sites
(I just pulled up the source to read his code - the [ source ] tags don't work in my browser).

Do away with the first file altogether. With my method, you don't need it - you just call Register("map",LoadMap); or Register("print",PrintToConsole); at app startup, and then can read the script file directly.

Only downside is that the function set is then fixed at compile-time (you can't add more functions to the vocabulary) without rebuilding). However, you can do some pretty clever things - like:

Register("print",(bIsDebugging)?PrintToDebugger : PrintToConsole);


You can even change which functions are associated with which keywords as you go along.

Superpig
- saving pigs from untimely fates, and when he's not doing that, runs The Binary Refinery.

[edited by - Superpig on July 2, 2003 11:57:13 AM]

Share this post


Link to post
Share on other sites