get/set Properties for Object, without known the Methods.

Get answers to all your basic programming questions. No Ogre questions, please!
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

get/set Properties for Object, without known the Methods.

Post by FrameFever »

For an editor it's neccessary to get/set properties of an Object.

but the GUI don't know how much properties an object contains, nor with which function I can set/get the properties. So Have anybody an idea, how I can solve this problem?


this is a basic Idea of me:

Code: Select all

class Property
        {
       
        public:
                Property();

                virtual ~Property();

                setProperty( const std::string &p_Name, SimVariant & Value) = 0;

                SimVariant getProperty( const std::string &p_Name) = 0;
        };


class Object : public Property
{
        setRotation(int Value);
        setScale(int Value);

        setProperty( const std::string &p_Name, SimVariant & Value)
        {
                if(p_Name.compare("roation") == 0)
                        setRotation(Value.toInt());
                if(p_Name.compare("scale") == 0)
                        setScale(Value.toInt());
        }
}

class Camera : public Object
{
        setDOF(int Value);
       
       
        setProperty( const std::string &p_Name, SimVariant & Value)
        {
               Object::setProperty( p_Name, Value);
                if(p_Name.compare("DOF") == 0)
                        setDOF(Value.toInt());
        }
}
good bad?
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

That general pattern is the way I have seen it done. I too would be interested if anyone has better ideas.
User avatar
betajaen
OGRE Moderator
OGRE Moderator
Posts: 3447
Joined: Mon Jul 18, 2005 4:15 pm
Location: Wales, UK
x 58
Contact:

Post by betajaen »

I spent almost a better half of a week to get it something like that working.

It was going to be a function pointer class that could change or get any registered variable for any type directly accessing the method, or through the class get/set functions, through a mixture of templates and pointers. It was going to rival anything that boost made, it was going to be awesome. It was going to be part of a Ogre User Interface (BetaUI) system that the GUI part was only 1/4 of the code.

This was possible:

Code: Select all

class test {

	public:

		test() {
			foo=1;
			bar="Hello";
		}


		void setFoo(int newFoo) {foo = newFoo;}
		int  getFoo() {return foo;}
		
		void setBar(std::string newBar) {bar = newBar;}
		std::string getBar() {return bar;}
	protected:

		int foo;
		std::string bar;
};

void main() {

	test* t = new test();

	Attributes attributes;
	attributes.add<test, int>("foo", t, &test::setFoo, &test::getFoo);
	std::cout << t->getFoo() << std::endl;
	attributes.attributes["foo"]->set(10);
	std::cout << t->getFoo() << std::endl;

	attributes.add<test, std::string>("bar", t, &test::setBar, &test::getBar);
	std::cout << t->getBar() << std::endl;
	attributes.attributes["bar"]->set("World");
	std::cout << t->getBar() << std::endl;
}
As you can tell by the past tense, I reformatted yesterday, and I did zip the code, but as it seems now it never got copied. I may have another copy in some shape or form on another harddisk, but that involves swapping out harddrives.

If the need is great. I'll try and find it, I lost BetaGUI 2.5 as well. :(
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Post by CABAListic »

A shame you lost it. I would also say that this is an excellent opportunity for templates to shine, i. e. make a templatised get/set encapsulation that can convert a generic input into a generic output (using something like boost::lexical_cast or the like). Then, on top of this, you would use a std::map to map property names to their encapsulation, saving that tedious if-blocks.
But I have no code ready for that.
User avatar
betajaen
OGRE Moderator
OGRE Moderator
Posts: 3447
Joined: Mon Jul 18, 2005 4:15 pm
Location: Wales, UK
x 58
Contact:

Post by betajaen »

I found it, three running harddisks are quite noisey, and I risked another Windows activation for you guys.

Here is the BetaUI Attribute class, and here is how to operate it.

I really don't know what the status or if it works or not. It's been a few months. But briefly looking at the code it only supports "member" attributes at the moment, and not functional ones. I think I hit a brick wall due to limitations of C++.

Code is public domain, please improve on it.
Rackle
Gnome
Posts: 375
Joined: Sat Jul 16, 2005 1:42 am
Location: Montreal

Post by Rackle »

The "A Property Class for Generic C++ Member Access" article by Charles Cafrelli from Game Programming Gems 2 allows the following:

Code: Select all

#include <string>
#include "Properties/Property.h"

class GameObject : public PropertySet
{
	int m_speed;
	std::string m_name;
public:
	GameObject()
	{
		Register("name",&m_name);
		Register("speed",&m_speed);
	}
};

int main(int argc, char* argv[])
{
	GameObject starship;

	// set starship's name and speed...
	starship.Set("name","Enterprise");
	starship.Set("speed",4);

	// if you're unsure of the property's type, use the generic SetValue which will
	// attempt to do the conversion for you...
	starship.SetValue("speed","6");

	Property* speed_property = starship.Lookup("speed");
	int ispeed = speed_property->GetInt();
	ispeed += 2;
	speed_property->Set(ispeed);

	// this is a convenience function so that you don't have to go through the hoops
	// of doing the conversion to display the contents yourself.
	std::string speed = speed_property->GetValue();
	
	return 0;
}
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

@Rackle

and where is the "Properties/Property.h" ? thats what we need.

@betajaen
you code looks damn freaky, so hard to understand for me.

what I miss, When you get the property, you don't know which Type is it.

So the GUI have to print all properties, so for a bool property it have to make a bool widget, for a time property a time widget, color a color widget.

the type for the property is a must to know.

So I think a Variant type can solve this, but I don't have seen good custom variant types.

@gameender
whats the "general pattern"? never heard of this pattern
User avatar
syedhs
Silver Sponsor
Silver Sponsor
Posts: 2703
Joined: Mon Aug 29, 2005 3:24 pm
Location: Kuala Lumpur, Malaysia
x 51

Post by syedhs »

It depends on how much integration needed.

For me I will do the followings:-

1) Construct a base class PropertyObject & PropertyWindow.

2) All objects are supposed to derived from PropertyObject and they are connected to PropertyWindow via simple method eg PropertyObject::connect(PropertyWindow*)

3) Let say you have 10 objects so you have to have 10 classes derived from PropertyObject.

4) Initially the PropertyObjects are not active (default state), but once activated, the PropertyObjects will automatically populate the connected PropertyWindow. So it is a self contained class that you dont have to know what/how many properties are in there. They take care by themselves & the complexities are confined within the class.

5) The PropertyObject will also be able to self-validate (if the user enter value in it). So probably you will need to create another class named eg PropertyValue. You have to create classes like PropertyRGBValue, PropertyStringValue, PropertyIntValue etc.
User avatar
betajaen
OGRE Moderator
OGRE Moderator
Posts: 3447
Joined: Mon Jul 18, 2005 4:15 pm
Location: Wales, UK
x 58
Contact:

Post by betajaen »

Nash wrote:you code looks damn freaky, so hard to understand for me.
Template Code always is, it's not for the faint of heart.
Nash wrote:what I miss, When you get the property, you don't know which Type is it.

So the GUI have to print all properties, so for a bool property it have to make a bool widget, for a time property a time widget, color a color widget.
Not exactly. The template will store any type you wish, however the wrapper around it doesn't use templates and resorts to old fashioned stuff. To add a new type all, you'd need to do is copy and paste 4 lines, and just change say int to myClass.
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

I think that could be the answer
http://www.boost.org/doc/html/any/s02.html
User avatar
betajaen
OGRE Moderator
OGRE Moderator
Posts: 3447
Joined: Mon Jul 18, 2005 4:15 pm
Location: Wales, UK
x 58
Contact:

Post by betajaen »

Ogre uses boost any, funnily enough called; Ogre Any. However it doesn't provide any real get or set methods, or the ones we want. ;)
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

The system I've used also works off of string keys. I use a class called Variable, which uses stringstreams and boost::any as transport and conversion devices to store any type within it. I built a Property type around it which is then surrounded by Model. Anyway, it was a lot of work to make generic holders and such. The code is all open-source here:

http://sourceforge.net/projects/odysseyengine

It was pretty much ready for primetime, but I needed help to finish making some section cross-platform. I may go back to this some time, but currently we've moved away from it so I haven't updated it much.
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

On the face of that, it looks like you have a very impressive Meta-Framework there. With a very nice (MIT) license as well. Now if only I can wrap my head around it fast enough to convince myself to use it. Do you have any design documents? (Besides the Odyssey Manual). I am looking for a quicker way to understand your the whole property system you have developed.
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

There is a design doc in the downloads section on sourcforge. It is fairly high-level and talks about the main components in the framework. You don't have to use the whole thing. If you just wanted to pull out the data handling parts of it you can, but there isn't a document specifically about that part. If you look at the manual in the sections about the Model and Property you can see the kinds of things you can do with it.
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

My idea is if you need to start using approaches like this you should rethink your design.
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

you can also explain your "idea" a little bit more
do you have a better design?
User avatar
pjcast
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2543
Joined: Fri Oct 24, 2003 2:53 am
Location: San Diego, Ca
x 2
Contact:

Post by pjcast »

This is kind of problem is nicely solved by reflection. Specifically, .Net has a real good reflection and property editing system in place (PropertyGrids).

However, doesn't really solve your issue in C++. Though, maybe you should take a look at YAKE, I know they created some sort of reflection system for C++, maybe that could be a good starting point to get some ideas from.
Have a question about Input? Video? WGE? Come on over... http://www.wreckedgames.com/forum/
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

The problem I have with a lot of reflection systems in C++ is that there is a lot of registration overhead usually. I couldn't even avoid it. But I did try to minimize it. I'd much rather use a system that transparently handles generic data types that one which reports the expected ones back to me, but which requires me to register all of the information somehow. The only option I see which can really be good is to use something like gccxml to automatically "bind" reflection systems in C++, and then to transparently handle a generic calling mechanism.
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

pjcast wrote:This is kind of problem is nicely solved by reflection. Specifically, .Net has a real good reflection and property editing system in place (PropertyGrids).

However, doesn't really solve your issue in C++. Though, maybe you should take a look at YAKE, I know they created some sort of reflection system for C++, maybe that could be a good starting point to get some ideas from.
reflection that was the right keyword!!!
I know that was a common problem in C++, how to get properties of your object.
with this Keyword info I found following:

http://seal-reflex.web.cern.ch/seal-reflex/index.html
also LGPL,
why to reinvent the whell, when there are good solutions on the market
I think thats what I need!!

but there also other good projects...maybe finde better ones?
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

The genreflex command is used to generate the C++ code from header files that will be used to populate the C++ Reflection information when it will be loaded into an application. It is based on the GCC_XML open-source C++ parser, a C++ front-end to GCC, which is currently able to deal with the language in its entirety.
Well look at that! [SHAMELESSSELFPROMOTION]I believe a wise man once said this would be way to do it...[/SHAMELESSSELFPROMOTION]
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

Well its hard to say without knowing any details.

If you really want to create somekind of reflection system as in java or .net then yes u'll have to do something like this.

The question is, do you really need it?
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

I think yes.

Because I want not only manipulat all my properties with in the editor.

I think it also helps to make an exact copy of an object, so I can set all the values for the object. right?!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

You can use a copy constructor or somekind of clone() function for that. Every situation is different, some ppl swear by design patterns(which reflection basicly is) but be careful with that.
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Post by Praetor »

You do want to be careful. An elegant design and general solution is great, but it can take up a lot of time doing it. At this point only you can know if it is really necessary, but you could just provide support in the editor for editing a subset of types (like int, string, bool, Vector3, etc.), instead of a full reflection system. Just as one example.
User avatar
FrameFever
Platinum Sponsor
Platinum Sponsor
Posts: 414
Joined: Fri Apr 27, 2007 10:05 am

Post by FrameFever »

thats not the biggest problem, boost:any ist the solution, they also use it in the reflex syste,, the problem is, how many properties contains the current object?

Like I said what I when I pick a Light Object, or an Camera Object, there will be other properties of course. So I think a reflection system will be the most elegant solution, for such a problem.

and of course I don't write my own reflection system, there is a nice solution, so why don't use it? what will be happen? they use it in the CERN. it must be good :P
Post Reply