In the Quake 4 console, there is a "spawn" command, then you put the class name of what you want to spawn, eg. "spawn weapon_railgun".
>Meaning that it tried to construct the weapon_railgun class from this input.

If the class that you specify is not one that can be spawned, it says something like this: "[class_entered] does not have a spawnfunc or a spawnclass".
>Meaning that they were able to know if weapon_railgun had a spawnfunc.

What I want to know is how they could've inplemented this:

1) How would you be able to construct a class from a string of user input?
2) How would you be able to search a class to see if it has a function or data in it?(such as spawnfunc)

Thanks for your time

Edited 7 Years Ago by tomtetlaw: n/a

I think its just checking from a list of options and if it is not there it throws you the error that it does not have a spawn function.

What do you mean by checking from a list of options?

If you mean like this:

class Foo{
};

int main()
{
    Foo f;
    try{
        f.a_function()
    }
    catch(...)
    {
        cout << "funciton not found";
    }
}

then that wouldn't work, it would give a compiler error

One way of doing it would be like this:

class object{
public:
    object(){};
    virtual ~object(){ std::cout << "destroy object\n"; };
    virtual void doStuff() = 0;

};

class rail_gun : public object{
public:
    rail_gun(){ std::cout << "construct railgun\n"; };
    ~rail_gun() { std::cout << "destroy railgun\n"; };
    void doStuff() {std::cout << "doStuff railgun\n"; };
};

class bfg : public object{
public:
    bfg(){ std::cout << "construct bfg\n";};
    ~bfg() { std::cout << "destroy bfg\n"; };
    void doStuff() {std::cout << "doStuff bfg\n"; };
};

object * spawn(std::string type){
   if (type == "rail_gun") return new rail_gun();
   if (type == "bfg") return new bfg();
   return NULL;
}


int main()
{
    std::string type = "bfg";
    object * obj = spawn(type);
    if (!obj) {
        std::cout << "can't contruct " << type;
    } else {
        obj->doStuff();
        delete obj;
    }
    std::cin.get();
}

All classes inherit from 'object' so you can use an object pointer as a starting point. The 'spawn' function checks if a class may be created and creates a new class if it's allowed. The functions in object are virtual for obvious reasons.

Try to change "type" to other things and see what happens!

Hey thanks, that example is really interesting, I played around it and let the user input stuff(cin>>type) so it's interactive.

What about the second question? Mabey it would just call the base classes version of doStuff if the class you tried to construct didn't have it and inherited from object? I'll try experimenting more.

EDIT:
Yep, I was right, this is what I used to test this:

#include <iostream>
#include <string>

class object{
public:
    object(){};
    virtual ~object(){ std::cout << "destroy object\n"; };
	virtual void doStuff(){ std::cout << "it has no spawn func\n"; }

};

class rail_gun : public object{
public:
    rail_gun(){ std::cout << "construct railgun\n"; };
    ~rail_gun() { std::cout << "destroy railgun\n"; };
    void doStuff() {std::cout << "doStuff railgun\n"; };
};

class bfg : public object{
public:
    bfg(){ std::cout << "construct bfg\n";};
    ~bfg() { std::cout << "destroy bfg\n"; };
    //void doStuff() {std::cout << "doStuff bfg\n"; };
};

object * spawn(std::string type){
   if (type == "weapon_railgun") return new rail_gun();
   if (type == "weapon_bfg") return new bfg();
   return NULL;
}


int main()
{
	std::string type = "bfg";
	while(std::cin>>type)
	{
		object * obj = spawn(type);
		if (!obj) {
			std::cout << "can't contruct " << type << '\n';
		} else {
			obj->doStuff();
			delete obj;
		}
	}
	std::cin.get();
}

/*test run:
weapon_railgun
construct railgun
doStuff railgun
destroy railgun
destroy object
weapon_bfg
construct bfg
it has no spawn func
destroy bfg
destroy object*/

Thanks for helping me to understand this : )

Edited 7 Years Ago by tomtetlaw: n/a

This article has been dead for over six months. Start a new discussion instead.