Jump to content
  • Advertisement
Sign in to follow this  
frank fayek

Unity Accessing arbitrary variables at runtime

This topic is 4397 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, This is my first post and first of all let me say thanks for all the help the gamedev community has provided regarding programming (especially OpenGL). On to my question: I have a C++ program and I would like to be able to get and set variables while my app is running. What is a good way to provide access to program variables? For the sake of context, this is an OpenGL app that has enough variables that binding keys, etc is impractical. I've written a little console (like a simple version of what you get in Quake, etc when you press tilde). I can enter commands to check and change variables in the console. However, the way I've written it I have to code a separate function for each variable I want to get/set. When I parse/interpret the command line i resolve a function pointer, pass it the params and execture it. Is there some better (more general way) to do this? I'm sure others have this type of functionality in games or other programs. What approach have you used / do you suggest? Has anyone gone so far as to create a simple debugging environment (like a lightweight gdb) or something like an interpretive language interface, where you can call your functions directly? Thanks in advance, Frank.

Share this post


Link to post
Share on other sites
Advertisement
You could do it in a general way using .Net reflection, but that obviously only works if you're using a .Net language.

You could also do it in a general way if you expose things through a scripting language and have your console execute that scripting language.

I don't have any experience exposing my code through a scripting language, though, so I don't know if there's any languages or tools that would let you automatically expose everything.

You could also store every variable you want to be able to modify in a hash table indexed by a string and have your console automatically look up the variable in the hash table.

Share this post


Link to post
Share on other sites
For your console class I could imagine something like

Console.BindInt( "PlayerX", &player->x );


And then from the console, while in the game, you could type

SET PlayerX 400

Share this post


Link to post
Share on other sites
It's pretty simple to do a basic command line in the program, you could (for example) have something like std::map<std::string, boost::function<void (const std::string&)> >, then tokenize each command line by spaces and pass to the function described by the map at the first string in the command.

Share this post


Link to post
Share on other sites
Hi,

Thanks for the help. .Net reflection looks pretty powerful. Alas, I'm not using .Net. I implemented a map for functions (get, set, etc) and a function to bind variables, as recommended. It's definitely better than a single function for each variable!

I'm now trying to template it to avoid creating BindFloat, BindString, etc..., and perhaps to avoid using switches in the my get/set/print... functions (and to learn about templates). I've created a function:

template <typename T>
Console.Bind(string & const name, T *ptr, boundVar_t type)

But it seems silly that I need the boundVar_t tag. Is there a better (implicit) way to keep track of the type so I can do the appropriate thing with the data later? Can T be saved directly somehow?

Thanks again,
Frank


Here's are some snippets from my current implementation:

// type tag
typedef enum {
intt, floatt, stringt // must specify every possible type :(
} type_t;

typedef struct {
string name;
type_t type;
void *ptr;
} boundVar_t;

//: Bind variable
void Console::Bind(string const &name, T *ptr, boundVar_t type)
{
boundVar_t newBind;
newBind.name = name;
newBind.type = type;
newBind.ptr = (void*) ptr;
variableList.push_back(newBind);
}


// ... somewhere in Console.Set

switch (variableList[hash].type) {
case intt:
*((int*)variableList[hash].ptr) = (int)valueParsedFromCommandline; break;
case floatt:
*((float*)variableList[hash].ptr) = (float)valueParsedFromCommandline; break;

// ...

Share this post


Link to post
Share on other sites
Im not sure what you were looking to do, How about you wrap the variables themselves in templates, some sort of convinance class.


template<class T>
class BindVar
{
BindVar(std::string, *T);
Get();
Set(T);

T *item
}

// Usage
int *variable_to_bind = myengine::getvar();
BindVar<int> bv = new BindVar<int>("Master", variable_to_bind);
Console::Get().AddToHash(bv)

Share this post


Link to post
Share on other sites
Hi,

When etothex originally mentioned boost, I didin't look at it very carefully. I've now read the tutorials. It looks very useful, thanks snk_kid. I'll try it your way first, Paul, then I'll try boost.

Thanks again,
Frank

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
I suggest investigating boost libraries, in particular Boost.Variant.


Oh, hell yes!

I like to think that I have a bit of experience in this as I've spent the last month and a half writing my console, and I'm just finishing it up for functions.

For variables, I'm using boost::variant, and I'm storing them in a std::map<std::string, boost::variant> object. The variant can be a pointer, and I've created the visitors, so when it is a pointer, it's de-referenced and value it points to is get or set.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!