Any tricks to releasing memory used by ent_clone?

Posted By: EvilSOB

Any tricks to releasing memory used by ent_clone? - 10/13/12 17:04

Hiya all.

Is there any 'trick' or workaround that will allow me to
'undo' or 'reverse' an ent_clone?

AFAIK the only way to release the memory consumed by an ent_clone
is to ent_remove the whole entity. I would like to avoid this.

I wish to be able to be able to perform ent_clone on the same
entity multiple times, but only use one ent_clone worth of memory.

EG:
ent_create; ent_clone; wait(?); while{ ENT_UNCLONE; ent_morph; ent_clone; wait(?); }

Any ideas anyone? Thanks all.

For further details, see THIS thread...
Posted By: ratchet

Re: Any tricks to releasing memory used by ent_clone? - 10/13/12 17:32

Change your 3D engine !
just kidding laugh
Posted By: Spirit

Re: Any tricks to releasing memory used by ent_clone? - 10/14/12 12:12

For releasing the mesh and textures call ent_purge, for removing the entity from the cache use the level_mark and level_free.
Posted By: jcl

Re: Any tricks to releasing memory used by ent_clone? - 10/15/12 16:48

Not necessary. Cloned entities do not occupy the cache, so the memory is released with ent_remove - and I can not see any problem with that. No trick required.
Posted By: EvilSOB

Re: Any tricks to releasing memory used by ent_clone? - 10/15/12 20:41

OK... no one seems to be able to understand my question... So I will try again.

Code:
#include <acknex.h>
#include <default2.c>
//
void main()
{
	wait(1);		level_load(NULL);		wait(1);		camera.x = -150;		random_seed=100;
	//--------------------------------------------------------------------------------------
	//
	ENTITY* ents[100];		int i,v;		CONTACT* c;		VECTOR tmpV;
	//--------------------------------------------------------------------------------------
	for(i=0; i<100; i++)	
	{
		ents[i]=ent_create(SPHERE_MDL, vector(0,random(100)-50,random(100)-50), NULL);
		ent_clone(ents[i]);
		//
		v = integer(random(ent_status(ents[i],0)));
		c = ent_getvertex(ents[i], NULL, v);
		tmpV.x = c.v.x;	tmpV.y = c.v.z;	tmpV.z = c.v.y;
		vec_scale(tmpV, 1.5);
		c.v.x  = tmpV.x;	c.v.z  = tmpV.y;	c.v.y  = tmpV.z;
   	ent_setvertex(ents[i], c, v);
	}
	//--------------------------------------------------------------------------------------
	while(1)
	{
		for(i=0; i<100; i++)	
		{
			switch(integer(random(4)))
			{
				case 1:
					ent_morph(ents[i], CUBE_MDL);
					ent_clone(ents[i]);
					break;
				case 2:
					ent_morph(ents[i], SPHERE_MDL);
					ent_clone(ents[i]);
					break;
				default:
					// just do vertex displacement
			}
			//
			v = integer(random(ent_status(ents[i],0)));
			c = ent_getvertex(ents[i], NULL, v);
			tmpV.x = c.v.x;	tmpV.y = c.v.z;	tmpV.z = c.v.y;
			vec_scale(tmpV, 1.1);
			c.v.x  = tmpV.x;	c.v.z  = tmpV.y;	c.v.y  = tmpV.z;
			ent_setvertex(ents[i], c, v);
		}
		//
		wait(1);
	}
	//--------------------------------------------------------------------------------------
	sys_exit(0);
}


HOW can I fix the memory leak in this code? CAN I fix the memory leak in this code?

ALL instances of ent_clone and ent_morph are REQUIRED! Ent_remove is NOT ALLOWED!!

Hopefully someone can just ANSWER my questions without trying to re-write my code...
This is just SAMPLE code, I cant post 100Mb of project here...
This SAMPLE is just to convey my problem, and the limitations the answers
are constrained by...


PS:: I have tried playing with ent_purge and ent_reload, with no sucess,
but that doesnt mean Im not using them wrong...
Posted By: Superku

Re: Any tricks to releasing memory used by ent_clone? - 10/15/12 21:55

Originally Posted By: jcl
Not necessary. Cloned entities do not occupy the cache, so the memory is released with ent_remove - and I can not see any problem with that. No trick required.


Just use ptr_remove, why wouldn't it be allowed? If you need to keep any parameters, save them temporarily. Example:

Change

ent_morph(ents[i], CUBE_MDL);
ent_clone(ents[i]);

to

vec_set(tmpV,ents[i].x);
ptr_remove(ents[i]);
ents[i]=ent_create(CUBE_MDL, tmpV, NULL);
ent_clone(ents[i]);
Posted By: jcl

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 07:14

Correct. Only for entities use ent_remove, not ptr_remove. Both do the same, just for clarity reasons.
Posted By: EvilSOB

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 08:39

I CANT USE ENT_REMOVE! Can I make it any more clear!

I have other functions and code that store the entities by entity pointer,
not by their position within the 'ents' array.

So if I do an ent_remove/ptr_remove then those functions/actions will be
pointing to a no-longer-valid address, or even a different entity altogether.
This is not good...

Also, I am currently using ent_morph because it is MUCH faster then performing
an ent_remove & ent_create combo. I will be processing the entities in
'batches' and if I use the ent_create process I get stuttery fps
due to 20+ ent_create's in a single frame. Ent_morph doesnt cause this problem.


If the answer is "... it CANNOT be done...", then someone say so... please.
(but dont lie, I want the truth!)
Posted By: TechMuc

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 08:48

Just to rewrite your question, so jcl / others can understand it:

You have more or less this coding:
Code:
ent = ent_create(..)
ent_clone(ent);
while(1) {
  ent_morph(ent,...); //much faster and safer than ent_remove / ent_create combo
  ent_clone(ent);
  wait(1);
}



Additionally you have several external references to "ent", and therefore do not want to invalidate the pointer (besides it's pretty nonsense to "recreate" an entity - with all known sideeffects, e.g. restarted action, stopped functions, and slow processing).

Your question is, if:
1) With the ent_morph action, the reserved memory for the previously cloned model is freed
2) If not: Does a second call (e.g. to subsequent calls of ent_clone) free the memory of the first call?
3) If not: If there is a possiblity to free the extra memory reserved by a clone instruction after a morph instruction, without removing and recreating the entity.

correct me if i'm wrong

FYI: After a clone instruction the complete vertex / index buffer is copied. I do not think that it is possible to go "back to standard" (so releasing the changed parts). But: After a morph instruction the complete copied vertex / index buffer should be released, and your given code should not create any memory leak at all..

FYI 2: If the memory is not freed after the morph instruction, this is just a bug for me. Actually I highly doubt that ent_remove will recognize the "old" vertex buffers after some morph / clone instructions and delete them. Ent_Morph should detect if the current model is cloned, and delete the buffers accordingly if necessary..
Posted By: jcl

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 08:51

Evilsob: If you have other functions that access the entities by pointer, then why don't you change those functions so that they access the entities by array index instead, if that is what you need? That should be a matter of five minutes.

Of course ent_remove is slower than ent_morph because ent_remove releases the clone, which is just what you asked for.

There are obvious and simple solutions to your problem. You just have to use them. Behave like a programmer and solve your problem instead of whining about it.
Posted By: TechMuc

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 08:54

@jcl:
1) "Of course ent_remove is slower than ent_morph because ent_remove releases the clone, which is just what you asked for."

leads to==>

Code:
ent = ent_create(ent);
ent_clone(ent);
ent_morph(ent,..)
ent_clone(ent);
ent_morph(ent,..);
ent_clone(ent);
ent_remove(ent);



So this will result in a memory leak (As Morph does NOT release the cloned memory and ent_remove will release most probably only the last vertex buffer)? In this case I think it should be mentioned that the morph and clone instruction should not be used on the same entity..

(or is ent_remove "smart" enough to detect all cloned previous buffers?)

2) Is it possible to do release the mesh and the corresponding vertex / index buffer (returned by ent_getmesh) for non animated entities on your own?
Posted By: jcl

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 09:00

No, ent_remove does not keep a history of previous clones. So, cloning the same entity multiple times will generate orphans, and we'll mention that in the manual. But it should be sort of obvious anyway.
Posted By: EvilSOB

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 10:54

For gods sake! Is it really that hard to answer my question!

I may be whining, but I AM behaving like a programmer.
I am looking at ALL possible avenues to solve my problem.
But obviously no-one wants to help me determine the validity of
THIS particular avenue...


JCL: I KNOW there are other ways to solve this issue. Probably BETTER ways.
But Im not askling about them. Im just asking is there a way to release the
cloned entity data WITHOUT releasing the WHOLE entity?

I understand WHY ent_clone & ent_morph are consuming memory as they are.
And I dont disagree with it, nor do I think its a bug. Its fine.
Im just looking for a POSSIBLE way of bypassing it.

Ent_remove being slower than ent_morph is obvious, as is ent_morph creating
orphans if used un-wisely. I dont feel the manual NEEDS to explain that.
It was pretty obvious to me after one test run.


There are obvious solutions to my problem... YES.
There are simple solutions to my problem... YES, to a degree.
But I prefer to examine all the POSSIBLE solutions that I can think of,
before deciding which to work with.

And so this discussion... it is all about ONE possible solution.
I was asking for help to see if it was POSSIBLE to be of use to me.

BUT ... seeing as no-one wants to answer the question, Im going to write off
this entire discussion/thread as a WASTE OF MY BLOODY TIME... and hair!

!! CASE CLOSED !!

I'll see you guys around once Ive cooled off a bit.
I apologise if Ive offended anyone... no hard feeling OK?
Posted By: jcl

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 11:46

Ok, I see now - the original question was just if the allocated memory can be released without ent_remove. The answer is no, so either ent_remove or not cloning is required.
Posted By: Superku

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 11:54

I feel like your ignorance wasted OUR/ my time, not yours. To me it has been pretty clear since the beginning of the thread that you need ptr_/ent_remove to release the memory, and all this talk that the provided solutions are "NOT ALLOWED" is nonsense. The memory problem should occur on the day that you've written this code which means that the rest cannot be a full game yet, only a rather simple prototype. Using ents[i] as a pointer and not a "direct" reference is a very easy solution, you're just being stubborn here.
Posted By: EvilSOB

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 13:14

Thanks JCL, a lot. Thats all I was looking for.

I guess my original question got lost in my over-simplification,
and later by my ranting... Sorry.


Superku:
My ignorance is obvious, otherwise why would I have asked the question?
The best way to resolve my ignorance would have been to supply a simple answer.
Just because it was clear to you doesnt mean its clear to me.

But no one did answer the question. There were plenty of good suggestions,
but none dealing with the ACTUAL question.

As for my "not allowed" nonsence... havent you ever has a task to do that had
some form of limitation on it? Thats what 'not allowed' means.
I was trying to limit the number of solutions people would give me so
that the answers they gave fit the scope of my needs.

Phrasing my question better may have helped, but I didnt know a better way.
So I kept trying, and still got no answer, and got frustrated. My bad.

As for this fault occuring on day-one... never going to happen.
Im not capabale of writing a fully complete project on one day,
especially one this complex. So I do it in stages.

Up till now, the entities have been static place-holder entities.
Now Im 'morphing' them to reflect underlying map data, so the ent_morph process
in only now being implemented. All the other entity handling is already done.

Its that 'other handling' that contain the 'direct' references, and there
is quite a lot of it. YES, I will be fixing them to use array references
IN THE END, but not yet. Ive got this morphing proof-of-concept to deal
with first, then I'll go back and 'tidy' older code.

So YES, I am being stubborn. Live with it or ignore me... your choice.
Normally it doesnt get in the way of my programming, normally anyway.


So, regardless of how I may have responded to individual posts, I HAVE
been listening to all the suggestions made, and am considering many of them.
Posted By: Superku

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 13:22

I'm curious, what are you using this code for in the end? Do you have a grid of entities that are used as the visible tiles in a bigger (let's say) var array?
Posted By: EvilSOB

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 15:54

Got is in one ... nearly. As I would expect of you.

Its being used on a grid of 'visible' entities that are the tiles in a
much larger array of custom-structs.

Have a look at Esper's latest post in Projects|"What are you working on?"


The grid is fully populated with null-entities after level_load.
Then the array gets fully ent_morphed with map-data defined models
by the map_load function, or a sub-function thereof.

Then as each row and/or column gets beyond a set 'distance' from the camera,
the entitys in that row/column gets physically moved to the opposite side,
and then ent_morphed into its 'base model' correlating to its new XY position
within the master map-grid. The model also gets rotated to an sppropriate PAN
value at this point. (to reduce the number of MDL files we need to design)
Then the model gets its 'edge' vertices 'stitched' to its neighbour, using the
XY positions of the neighbours matching vertex.
Now you can see why I WANTED ent_morph and ent_clone to work together.

Thats was the plan IF my question had been answered with YES...

This attempt was following my previous one which was using ent_remove & ent_create,
when a slight lag was noticed when scrolling a row AND a column. AND I havent
even implemented the 'stitching' process yet.
I cant afford ANY noticable lag at this early stage because this projects
'mapping system' is only at a 'framework' stage so there is so little cpu-load
at this time I should never get ANY lag. Otherwise it will just get worse later.

Thats the primary reason why I was looking to avoid the ent_remove/ent_create process.
There are other reasons, future reasons, but they can be worked-around easily.

So I think I will soon go back to the ent_remove/ent_create process, and
figure out some way to buffer the ent_remove's (and maybe ent_creates too)
in order to 'smooth out' the cpu-load-balancing so there will be no
significant lag, even later when more game-mechanisms are installed.
Posted By: Superku

Re: Any tricks to releasing memory used by ent_clone? - 10/16/12 16:52

Ok. Well as it obviously doesn't work great that way, let me make 3 suggestions:

1) Use a big var/ int array that contains the value/ type of every tile in your level, f.i. a 200x200 array. Then create only a small array of entities, maybe 20x20, which make up the visible part of the level. The entities have the appropriate model file according to their position and the var array value. If you now move the camera, f.i. to the right, you only have to morph one column (or none) because you can replace all other columns by simple pointer arithmetic (I mean create the entity field array out of column arrays and replace their indices in the field array).

2) I don't fully understand why you would need to manipulate the meshes and thus need to clone them. The tiles could easily be created this way that they perfectly fit together. If you need a little more variation you can manipulate the vertices in the vertex shader depending on their world position (using sin/ cos/ ...), that's what I oftentimes do in my game, it allows me to stitch entities together easily and animate them seamlessly.

3) As you don't need any collision detection for your game, you can try to set collision_mode to 0 (before level_load) and hope that entity creation gets faster (because no collision mesh should be calculated then).
© 2024 lite-C Forums