Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


About Passing Objects to my Object Adder


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 01:47 PM

So heres my World Class in .CPP Form


#include "World.h"

std::vector<Object*> Scene_Objects;
std::vector<Object*>::iterator Iter;


void World::AddObjectToWorld()
{
	Scene_Objects.push_back(new Object);
}

void World::RemoveObjectFromWorld()
{
	for (Iter = Scene_Objects.begin(); Iter!=Scene_Objects.end();)
{
    if ((*Iter)->MarkedForDeletion)
    {
        delete *Iter;
        Iter = Scene_Objects.erase(Iter);
    }
    else
    {
        ++Iter;
    }
}

};

void World::RemoveAllObjectsFromWorld()
{
	for ( size_t i = 0; i < Scene_Objects.size( ); ++i )
	{ 
		delete Scene_Objects[i];
		Scene_Objects.clear();
	}
};

Just a couple functions to manage my Scene_Objects vector, (which will ultimately be sent to the render for final rendering)

Here is my Object Class, its quite simple, but It needs something else, I'm quite sure of it...


#include "MS3D.h"

#ifndef OBJECT_H
#define OBJECT_H

class Object
{
public:

	bool MarkedForDeletion;

	struct Location
	{
		float locx;
		float locy;
		float locz;
	};

};
#endif
And here is the final object (inherits the object class)


#ifndef C_CROSS_H
#define C_CROSS_H


#include "Object.h"

class Cross : public Object
{
public:

	MS3DModel *Model1;

};

#endif
Now, back up there in the um, World class, I have an AddObjectToScene function, that creates a new object, is there any way I can set Cross = to Object, or do I have to switch a few parameters to make this work?

Sponsor:

#2 Alan Kemp   Members   -  Reputation: 772

Like
0Likes
Like

Posted 14 December 2005 - 02:09 PM

Just make AddObjectToWorld take an object pointer. That way you can also pass any subclass of Object (I suspect you already understand this).


void World::AddObjectToWorld(Object * obj)
{
Scene_Objects.push_back(obj);
}







void World::RemoveAllObjectsFromWorld()
{
for ( size_t i = 0; i < Scene_Objects.size( ); ++i )
{
delete Scene_Objects[i];
Scene_Objects.clear();
}
};





This doesn't do what you think it does. Scene_Objects.clear(); clears the entire vector, the first time through it deletes element[0] then clears the list (so Scene_Objects.size() is 0 the second time through and the loop ends immediatly.) Move it to after the for loop. That is, loop through deleting each element one at a time and then finally clear the whole vector in one go.

Alan

#3 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 02:14 PM

Thanks for another great response Alan. Rating++.

#4 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 02:16 PM

Question though - Do I have to hard code each instance of every object I want to pass this way?

If not, this isn't what I want, I want to dynamically allocate another object of a certain type on command from the user...


EDIT: oops for double post

#5 Alan Kemp   Members   -  Reputation: 772

Like
0Likes
Like

Posted 14 December 2005 - 02:21 PM

If I understand you correctly, you want the user to chose a type of object to add to the scene? I would implement that something like this:


enum OBJECTS
{
OBJ_CROSS,
OBJ_CAR,
OBJ_BADGER,
// etc
};

void addObject(int type)
{
Object * obj = NULL;

switch (type)
{
case OBJ_CROSS:
obj = new Cross();
break;
case OBJ_CAR:
obj = new Car();
break;
case OBJ_BADGER:
obj = new Badger();
break;
}

if (obj != NULL)
{
world.AddObjectToWorld(obj);
}
}



Alan

#6 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 02:28 PM

Alan you never cease to amaze me, consise and straight to the answer.

Is this the object oriented way to go? If so, it is perfect.

But it seems to make it so adding new models and objects to my game engine a bit clunky...

I have to add it to the ENUM, I have to add a switch for it, am I just being a little girly coder and complaining? Or is this the way it is? :D

#7 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 03:04 PM

I did find one problem that I can't quite figure out


int World::AddObjectToWorld(int type)
{
Object * Obj = NULL;

switch (type)
{
case OBJ_CROSS:
Obj = new Cross();
break;
}

if (Obj != NULL)
{
World::AddObjectToWorld(Obj);
}
}




When AddObjectToWorld is referenced in my header file, it says it takes an int, and that is fine, up until this part.

World::AddObjectToWorld(Obj);


We get an error like this


--------------------Configuration: NeHeGL - Win32 Debug--------------------
Compiling...
World.cpp
c:\documents and settings\jonathan\desktop\renderengine\world.cpp(20) : error C2664: 'AddObjectToWorld' : cannot convert parameter 1 from 'class Object *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Generating Code...
Compiling...
NeHeGL.cpp
Generating Code...
Skipping... (no relevant changes detected)
Renderer.cpp
Error executing cl.exe.
Creating browse info file...

NeHeGL.exe - 1 error(s), 0 warning(s)





I did find this in the MSDN

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/express_76.asp

I think this is what I need to do but I'm not sure how to implement it.

I tried, but failed

int World::AddObjectToWorld(int type)
{
Object * Obj = NULL;
Obj = reinterpret_cast<Object>( type );

switch (type)
{
case OBJ_CROSS:
Obj = new Cross();
break;
}

if (Obj != NULL)
{
World::AddObjectToWorld(Obj);
}
}


Now it just tells me I can't turn Obj into an Object class, and an int into an Obj...

--------------------Configuration: NeHeGL - Win32 Debug--------------------
Compiling...
World.cpp
c:\documents and settings\jonathan\desktop\renderengine\world.cpp(10) : error C2440: 'reinterpret_cast' : cannot convert from 'int' to 'class Object'
Conversion requires a constructor or user-defined-conversion operator, which can't be used by const_cast or reinterpret_cast
c:\documents and settings\jonathan\desktop\renderengine\world.cpp(21) : error C2664: 'AddObjectToWorld' : cannot convert parameter 1 from 'class Object *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
Error executing cl.exe.
Creating browse info file...

NeHeGL.exe - 2 error(s), 0 warning(s)



[Edited by - Shamino on December 14, 2005 9:04:15 PM]

#8 oscinis   Members   -  Reputation: 209

Like
0Likes
Like

Posted 14 December 2005 - 03:30 PM

Notice Alan's example function is addObject(int type), not addObjectToWorld. The function addObject basically wraps to addObjectToWorld, supplying it with the correct object to be added, based off the int type.

#9 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 03:32 PM

Oh! Thanks... Jee, hmmm, thanks for that....

*bangs head on desk*

#10 helix   Members   -  Reputation: 301

Like
0Likes
Like

Posted 14 December 2005 - 03:36 PM


int World::AddObjectToWorld(int type)
{
Object * Obj = NULL;
Obj = reinterpret_cast<Object>( type );

switch (type)
{
case OBJ_CROSS:
Obj = new Cross();
break;
}

if (Obj != NULL)
{
World::AddObjectToWorld(Obj);
}
}



You can't cast an int into an object. Basically just eliminate that line all together What you want to do is take the int object id and create the object associated with that id. When you have different types of objects, you can easily add them. So something like the following:


int World::AddObjectToWorld(int type)
{
Object * Obj = NULL;

switch (type)
{
case OBJ_CROSS:
Obj = new Cross();
break;

case OBJ_X:
Obj = new X();
break;

case OBJ_Y:
Obj = new Y();
break;
}

if (Obj != NULL)
{
World::AddObjectToWorld(Obj);
}
}




I would encourage you to look into the class factory design pattern. Because, as you mentioned earlier, this is a little clunky of a way to do it (though by far the easiest).

#11 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 03:38 PM

Fixed it, this should be doing exactly what I want it to



#include "World.h"

std::vector<Object*> Scene_Objects;
std::vector<Object*>::iterator Iter;


void World::AddObjectToWorld(Object * Obj)
{
Scene_Objects.push_back(Obj);
}

int World::AddObject(int type)
{
Object * Obj = NULL;


switch (type)
{
case OBJ_CROSS:
Obj = new Cross();
break;
}

if (Obj != NULL)
{
World::AddObjectToWorld(Obj);
}

return 0;
}



void World::RemoveObjectFromWorld()
{
for (Iter = Scene_Objects.begin(); Iter!=Scene_Objects.end();)
{
if ((*Iter)->MarkedForDeletion)
{
delete *Iter;
Iter = Scene_Objects.erase(Iter);
}
else
{
++Iter;
}
}

};

void World::RemoveAllObjectsFromWorld()
{
for ( size_t i = 0; i < Scene_Objects.size( ); ++i )
{
delete Scene_Objects[i];
}
Scene_Objects.clear();
};



#12 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 03:51 PM

Helix, did you mean something like this?

http://www.gamedev.net/reference/articles/article1415.asp

#13 Shamino   Banned   -  Reputation: 100

Like
0Likes
Like

Posted 14 December 2005 - 05:47 PM

Goodness.......

This is a BIG topic to grasp, but to make my game engine more object oriented and encapsulated I need to implement it.

#14 helix   Members   -  Reputation: 301

Like
0Likes
Like

Posted 14 December 2005 - 07:53 PM

hmm...that is pretty involved. :) I implemented a class factory that was much simpler. But it was also far less robust and full featured.

What I used was something more like this: Factory Method Pattern

If I were you, start simple with that and then work your way up to the reflective pattern.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS