Page 1 of 1

Initializing classes more than once

Posted: 06 Dec 2005, 19:32
by krogothe
Say i have a class that creates an array. I want to use that array and its methods in two or more other classes...
Do i have to create 2 instances of that class? will that take up more memory?
also is it possible to stick a whole array in the register for faster loading/saving?

Posted: 06 Dec 2005, 20:23
by AF
I would add a function in that class that returns a pointer to the desired array, that way other classes only need create a pointer and point it to that functions return value.

Posted: 06 Dec 2005, 21:31
by krogothe
but how can you pass arguments into a pointer? just like the IAICallback pointers?

and while were at it:
are vectors any slower than arrays?
how do you check if a folder exists?
how do you create a new folder?
how do i find out how wide/tall a building's footprint is?
why do you set your forum status as hidden?

Posted: 07 Dec 2005, 01:58
by jcnossen
are vectors any slower than arrays?
Only when you make it reallocate all the time:

Fastest (data.clear() doesn't reallocate!! just sets the size to zero)

Code: Select all

vector<int> data;

void test() { 
  while (need_to_do_stuff) {
    data.clear();
    fill data vector
    use data vector
  }
}
Slightly worse (data is allocated and freed everytime test is called)

Code: Select all


void test() { 
  vector<int> data;
  while (need_to_do_stuff) {
    data.clear();
    fill data vector
    use data vector
  }
}
Worst: (data is allocated and destroyed everytime it goes through the loop)

Code: Select all


void test() { 
  while (need_to_do_stuff) {
    vector<int> data;
    data.clear();
    fill data vector
    use data vector
  }
}
Accessing and looping through the data is just as fast probably, not a real difference.
how do you check if a folder exists?
Can be done in multiple ways, Win32 crap, going through the file tree with findfirst style (of which several forms exist as well), using boost::filesystem,......
how do you create a new folder?
mkdir() might work
how do i find out how wide/tall a building's footprint is?
UnitDef::xsize, UnitDef::ysize
why do you set your forum status as hidden?
I'm admin and I don't even know :|

Posted: 07 Dec 2005, 11:52
by Triaxx2
Because he doesn't want people to know when he's online, and suddenly start sending him ten million PM's?

Posted: 07 Dec 2005, 17:25
by krogothe
Wow awesome guys!
and how would i go about implementing a vector to work as a struct?
vector<struct> data;
data[z].x = y?

like that? and the brackets [] work just like an array right?
so the only real differences are the neat little functions like .push_back, clear etc? (im reading up on them)

All i really want to do is fill the vector array once and then remove values from it occasionally (could i remove a value right in the middle of it? how are the other values affected?)

Posted: 07 Dec 2005, 17:43
by jcnossen
All i really want to do is fill the vector array once and then remove values from it occasionally (could i remove a value right in the middle of it? how are the other values affected?)
Then you might want to use std::list... or if order doesn't matter, my ptrvec template. In general when deciding which template you should use, there are a few things to note:

- does it have fast random access like std::vector,std::deque and normal arrays:
array[element index]

- do you need to insert and remove elements from it regularly? then you want a container with constant time insertion+removal like std::list

- should it be sorted and have unique items: set/map,
the last two are very powerful but also generate a lot of code and use more memory than vector and list and I'm guessing that when used very often, they can really slow down the CPU caching..

Posted: 07 Dec 2005, 17:46
by krogothe
hmm ill have to look up on the differences between a list and vector and deques too (vecs and deqs seem similar but lists are slower for some reason)...
it wont be changed very often at all but will be accessed often so ill go for something fast!

Re: Initializing classes more than once

Posted: 08 Dec 2005, 10:34
by PauloMorfeo
krogothe wrote:Say i have a class that creates an array. I want to use that array and its methods in two or more other classes...
Do i have to create 2 instances of that class? ...
Do you want to make something like this?
note, this is C# so in C++ should look diferently (still similar).

A class:

Code: Select all

class UnitList
{
	//Create an Array
	private Array unitList= new Array();
	
	//stuff
	
	public bool IsUnitUnderFire (Unit unit)
	{
		//do your stuff to check it
	}
}
Accessing an object made out of the class «UnitList» in another method:, example 1:

Code: Select all

class krogotheProgram
{
	static void Main ()
	{
		UnitList unitList= new UnitList();
		krogotheProgram2 k= new krogotheProgram2();
		k.checkUnitsUnderFire (unitList);
	}
}

class krogotheProgram2
{
	public void checkUnitsUnderFire (UnitList unitList)
	{
		foreach (Unit u in unitList) {
			if (unitList.IsUnitUnderFire(u)) {
				//Means unit is under fire
				//You've just accessed a method in the class UnitList in
				//  a method diferent from the one that created an instance out of it
			}
		}
	}
}
Accessing an object made out of the class «UnitList» in another method:, example 2:

Code: Select all

class krogotheProgram
{
	static void Main ()
	{
		UnitList unitList= new UnitList();
		krogotheProgram2 k= new krogotheProgram2(unitList);
		k.checkUnitsUnderFire ();
	}
}

class krogotheProgram2
{
	private UnitList unitList;
	
	//The constructor of the class
	public krogotheProgram2 (UnitList u)
	{
		unitList= u;
	}
	
	public void checkUnitsUnderFire ()
	{
		foreach (Unit u in unitList) {
			if (unitList.IsUnitUnderFire(u)) {
				//Means unit is under fire
				//You've just accessed a method in the class UnitList in
				//  a method diferent from the one that created an instance out of it
			}
		}
	}
}
They work slightly diferent.

Posted: 08 Dec 2005, 13:17
by AF
not the same at all, but helpful if you\'re learning C#

Posted: 08 Dec 2005, 17:36
by krogothe
Yeah, ive thought about passing the classes as arguments to the constructor, which works but since ill be using a lot of classes it will make the code really messy, passing 10+ classes....
What ive tried doing so far is creating instances of all classes in the GlobalAI class and then passing just a pointer to GlobalAI to each class:

Code: Select all

void CGlobalAI::InitAI(IGlobalAICallback* callback, int team)
{
	cb=callback->GetAICallback();
	ut = new UnitTable(this);
	ut->Init();
	mm = new MetalMap(this);
	mm->init();
}

Code: Select all

MetalMap::MetalMap(CGlobalAI* ai)
{
	this->ai = ai;
	cb = ai->cb;
and then to use the actual methods:

Code: Select all

float3 MetalMap::GetNearestMetalSpot (int builderid)
{
	float Tempscore = 0;
	const UnitDef* extractor = ai->ut->GetResourceBuilding(1,1);
 //////////lots of irrelevant code
}
The above should work, right? I can use callback functions in all classes like that without passing the IAICalback class, by just using ai->cb->method().
Am I missing something really obvious here? (since sub seems to get his AI to do that no probs!)

Posted: 08 Dec 2005, 18:11
by jcnossen
I've used that method too for quite some time. From a design point of view, you might want to make a seperate structure with all the globals in it (In JCAI this is called CGlobals):

Code: Select all


struct Globals {
  MetalStuff *ms;
  ResourceThings *rt;
  IAICallback *cb;
  TaskManager *tm;
};

Otherwise you'll end up with both the high-level and low level stuff in your CGlobalAI class, which can make things a bit messy when your code is growing.

Posted: 08 Dec 2005, 18:21
by krogothe
Ive never thought of that! Zaph youre a genius...
lemme try it out!


EDIT:
Yup! its working! you have no idea how much this has just helped my AI! (ill post a little topic soon about what i can do with it now!)

Posted: 13 Dec 2005, 20:28
by Veylon
Clever!

I mostly use things like this in my Init function for my AI:

Code: Select all

UnitDefList = new UnitDefClass(callback);
Metaller = new MetalClass(callback, UnitDefList);
Builder = new BuildClass(callback, UnitDefList, Metaller);
Attacker = new AttackClass(this, callback, UnitDefList);
But I think yours is better.

Posted: 13 Dec 2005, 20:35
by AF
I use a similair system. GlobalAI class creates a globals object liek the above btu thent he globals object creates all the agents and deals with all the stuff, so really the Global is NTAI and not cgloablAI.