@Lumpkin
I'm 32 years old. I've been playing games longer than you have been alive and I know how to optimize settings to make the most out of shitty hardware. The laptop is an off the shelf intel product (which back in 2006 wasn't that good). Can't test my desktop as it hasn't been hooked up for a while now.
There's no need for drama, some people honestly don't know that optifine even adds settings and options in the first place. Lumpkin just isn't downcasting from a Person instance to a BHXSpecter instance, which is good practice in programming but not in real life.
Yeah but you should still avoid it when you can. Sometimes you can't avoid it at all (or you can, but it would be even uglier to do so) but you can minimise the "damage" by hiding global variables in namespaces or classes or by making them file-static.
@chrisname
Don't forget another way to minimize the damage is if you can, use constant globals. I do this for my games in regard to if I know tile size for my maps or for my screen resolution that I want to set.
@BHXSpecter
Definitely; globals are one bad thing but non-const ones are much worse. By "damage", though, I meant the chance of naming conflicts, breaking encapsulation, and increasing coupling between different modules. It also makes all your code that relies on globals non-reentrant.
Just on the topic of macros, as this(http://www.parashift.com/c++-faq/array-memfnptrs.html) points out, sometimes you may want to use them (I have actually used this exact sort of thing before), otherwise your code risks getting both complex and unreadable.
Just wanted to point that out, in case anyone reading this thread didn't know about this sort of thing.
That still doesn't call for use of macros as you can just use std::function with std::bind to avoid marcos and still produce even cleaner syntax than CALL_MEMBER_FN(obj, fn_ptr)(params...).
@xerzi
That is actually nice, but now I will have to look into std::function and std::bind as I've never used them. I have to admit, I haven't used much of the library, but that is something I will have to keep in mind if I need to do that in future projects.
typedef std::function<void()> action;
//...
void stuff( action actiontoperform )
{
// do prep stuff
actiontoperform(); // do the action
// do cleanup stuff
}
int main()
{
//...
MyClass obj;
obj.DoSomethingWithAFile( "myfile.txt" ); // how to call the function normally
// but if we want to pass it as an 'action':
action act = std::bind( &MyClass::DoSomethingWithAFile, &obj, "myfile.txt" );
stuff( act ); // <- send it to our 'stuff' function
}
Notice how I did not have to pass the 'obj' or the filename to the "stuff" function. All that information is stored within the std::function object. All I have to do is call it as if it were a normal void() function.