Class IDs - ResourceManager

closed account (N36fSL3A)
Hello everyone, this is Fredbill30,

Well I was wondering if there was a way to give every individual class an ID for my ResourceManager class. Well basicly this is what I want to do:

Say I assign class Medkit ResourceManager ID Like:

This is Medkit.h:
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef  _MEDKIT_H_
#define _MEDKIT_H_
class Medkit
{
	public:
		ResourceID get_ResourceID() {Medkit ID = 1; return 1;}
		//...
	private:
		//...
};

#endif//_MEDKIT_H_ 


This is ResourceManager.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef _RESOURCEMANAGER_H_
#define _RESOURCEMANAGER_H_

typedef unsigned int ResourceID;

//"typedef const int ResourceID;" tells the compiler what I mean when I enter the type "ResourceID" in front of a variable
//This array will hold the ID values in the future, gotta figure out how to impliment this...
ResourceID RESOURCE_ID[1];


class ResourceMananger
{
	private:
	//Some code...	

	public:
	//With something like this to get the code
	ResourceID get_ID(ResourceID ID) {/*Do some stuff*/ return ID;}
	//Some code...

};

#endif//_RESOURCEMANAGER_H_ 


Basicly I want the manager to get into class Medkit and get the ID of the get_ResourceID(); function. I was looking up some resource managers (I wanted to get ideas to mix em' together to make a custom one for my games, applications. I basicly wanted it to be cross program) And I got this idea when I thought of how RPG Maker VX handled items. And when I was coding it I had a little trouble. Some Resource Managers used virtual functions, but I have no idea how they are used and what they are used for (I don't want to put something in my program I have no idea how to use)
Last edited on by Fredbill30
The tutorial on polymorphism explains virtual function.
You could also probably use a static class variable.

Assuming you want the same ResourceID for all classes...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Mother_foo {
  private:
  // ...
  public:
  // Declaring it as virtual means that we could change it in future classes
  virtual ResourceID get_ID() { return 0; };
};

class Child_foo {
  private:
  //...
  public:
  // Yaaay, method redeclarations!
  ResourceID get_ID() { return 1; };
};
Last edited on
closed account (N36fSL3A)
So It basicly overloads the function? I see its usefulness becuase instead of having to redeclare it everytime, you can declare it once...

How would I make it take the class name to figure out the ID? kinda like


1
2
3
4
5
6
7
//Some class code above...
virtual ResourceID get_ID(char* class_name)
{
	//Takes the class name and finds the id
	return ID;
}
//Some class code below...  



I was thinking that this isn't possible, so I was thinking I could create a function that finds a function or a variable inside my Medkit class, maybe even a use a macro.


Also, I was thinking it could find the value in that array declared above... I'm working on that concept.
Last edited on by Fredbill30
I'm a little confused. Why would a resource ID be part of the class? A resource would be an instance of a class, right?

An image is a resource... so if you have an image class that returns '1' as its ID, then that means that all images are going to have the same ID. Is that what you want? That doesn't really make sense to me.


If you're just looking for a way to identify which type of class you have, you can do this using the RTTI system (<typeinfo>). All you have to do is make your resource classes polymorphic (give them at least 1 virtual function -- a virtual dtor will work just fine), or a parent that is polymorphic.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <typeinfo>

class Resource
{
public:
  virtual ~Resource() { }  // a virtual dtor to make the class (and all its children) polymorphic
};


//  some child classes to handle different kinds of resources

class Image : public Resource  {};
class Audio : public Resource {};
class Model : public Resource {};
//...


int main()
{
  Image i;
  Audio a;
  Model m;
  
  if( typeid(i) == typeid(Image) )  std::cout << "i is an image" << std::endl;
  if( typeid(a) == typeid(Audio) )  std::cout << "a is an audio" << std::endl;
  if( typeid(m) == typeid(Model) )  std::cout << "m is a model" << std::endl;

  // you can also do this polymorphically (if you don't know the exact type):
  Resource* p = &a;  // 'p' is a pointer to some resource
  
  if( typeid(*p) == typeid(Image) )  std::cout << "p points to an Image" << std::endl;
  if( typeid(*p) == typeid(Audio) )  std::cout << "p points to an Audio" << std::endl;
  if( typeid(*p) == typeid(Model) )  std::cout << "p points to a Model" << std::endl;
}




But I'm not sure that's what you're asking for....
Disch brings up a good question, are you looking for a globally unique identifier? This is one where each object type has a unique ID. Or are you looking for a individually unique identifier? This is where each instance of the object has it's own unique ID. Or are you looking for both? We can do both, where part of the objects UID identifies it's type and the other part identifies the particular instance of that type (I highly recommend this approach).
closed account (N36fSL3A)
I wanted the manager to store classes that I choose to be able to be referenced by a number such as 1, 2, or 3 for my game. So when I want to change an item in my game, I could just enter it into a function like.

 
load_itemPosition(1, 50, 10); //This would load my Medkit class at 50 x, and 10, y 


Also, I would be able to easily edit this for 3D games like...
 
load_itemPosition(1, 50, 10, 13); //This would load my Medkit class at 50 x, 10 y, and 13 z. 

Edit - Woah, i basically answered my question, I think. Couldn't I do this loading thing with Vectors, And the rest is dependent with my map, but how would I do the globally unique ID@Computergeek01 I was looking for globally unique, I can figure out how to do both with Dish's teachings
Last edited on by Fredbill30
This is a terrible way to do this, you would need a container to manage the custom class just to implement this and it would still be a mess to use. Why not just set the position of the object in the constructor? If you want you can even have a member function to move the object after it has been created.
closed account (N36fSL3A)
Okay you're saying to make the constructor create the object at a position like 0,0 The make a function move that object to the desired place. I got the Idea of creating the object from GTA 3 modding, the way the function was set up is the same way it was written in Squirrel, which is a scripting language very close to C/C++...
I'm still very confused as to what it is you're actually trying to do. I think I'm thrown off by the word "resource" because your posts aren't talking about resources, yet you say you're using a resource manager... so I'm quite baffled.

Can you start over explain for me what it is you're trying to do? If I can understand I might be able to help with the design.
@ Disch: I think "Resource" should be find+replaced with "Object Type". That or the OP is using the term "resource" like in the context of an '.rc' file. Either way the underlying question seems to be how to manage instances of a class in an array of base pointers.
@ Computergeek, that's what I originally thought, hence my post about typeinfo... but I'm not confident that's really the problem here.
closed account (N36fSL3A)
I'm talking about files, and their code, witch I put into classes to handle so I can easily access them. I was writing a resource manager to handle these classes.
So more of a 'class manager' than a 'resource manager' then.

But why would you need such a thing? What is there to manage?

Sorry, I'm just trying to understand. I'm still confused.

It sounds to me like you are using classes as if they were objects or something. I don't know, something here just kind of stinks of misuse.

EDIT: what would help me understand was if you gave an overall picture of what the program is doing and how the classes are used.
Last edited on
closed account (N36fSL3A)
The program is a GAME. The reason I need this is because in that game, the items, will be stored in a class. The class will contain the functions the items need to preform their tasks. I was thinking if the had IDs they would be easier to manage.
Okay this is making more sense to me now. Thanks.

I would approach this one of two ways.

1) Polymorphism

Since each type of item will have different logic for their tasks, you can differentiate that logic by putting it in a virtual function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Item
{
public:
  virtual ~Item() { }
  virtual void Use() = 0;  // pure virtual 'Use' function - each Item will provide its own implementation

protected:
  int price_or_value;
  int weight;
  int more_properties_common_to_all_items;
};

// different types of items:  a book and a potion
class Book : public Item
{
public:
  virtual void Use() { /* Use/Read the book here*/ }

protected:
  int property_specific_to_books;
};

class Potion : public Item
{
public:
  virtual void Use() { /* Use/Drink the potion here*/ }

protected:
  int property_specific_to_potions;
};

//.....

void AFunctionThatDoesSomethingWithAnItem( Item* theitem )
{
  // we want to use the given item:
  theitem->Use();  // <- polymorphism automatically figures out which item we have
    // and calls the appropriate Use function.  Doesn't matter if it's a Book/Scroll/Potion/whatever.
}


Advantages:
- Keeps all item logic in the item class
- Adding new items does not require code changes to be made anywhere but in the new item class
- Allows all Items to be treated as similar types ('Item's), rather than their specific type ('Potion', etc). Makes it easier to throw all of them in a unified container like a vector or list.

Disadvantages:
- Requires a common 'Use' interface for all items. If some items are used differently than others, you'll either have to adjust the Use() function in all classes so that they can all be called the same way.


2) Clump all items into a single class/struct, and give them an ID as to their type

Here we move the logic outside of the Item class, which probably means it's more suitable to be a struct with possibly a union contained within:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
enum ItemId
{
  Book,
  Potion
};

struct Item
{
  std::string name;
  ItemId id;

  int price_or_value;
  int weight;
  int more_properties_common_to_all_items;

  union
  {
    struct
    {
      int property_specific_to_books;
    } book;
    struct
    {
      int property_specific_to_potions;
    } potion;
  };
};

//...........

void AFunctionThatDoesSomethingWithAnItem( Item* theitem )
{
  // we want to use the given item.  Figure out what kind of item it is:
  switch( theitem->id )
  {
    case Book: /* Read/Use book here */ break;
    case Potion: /* Drink/Use potion here */ break;
  }
}


Advantages:
- No need to have a common 'Use' interface for all items. Each item can be

Disadvantages:
- Harder to maintain/make additions to because logic is scattered throughout the entire program rather than neatly contained in each Item's class.



...........

It almost sounds to me like you are doing a hybrid of these two styles, which I strongly recommend against doing. Mixing them gives you the weaknesses of each and the benefits of neither.
closed account (N36fSL3A)
Ah, thank you Dish! You're the best, I guess I'll just use Polymorphism. You completely solved my problem!
Topic archived. No new replies allowed.