• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

ForForce strange bug

Status
Not open for further replies.
Level 5
Joined
Dec 12, 2011
Messages
116
Hello guys, I have a function that is not working well every time.

JASS:
function TempPlayersGroupEnum takes nothing returns nothing
    call BJDebugMsg("Inside ForForce: " + I2S(GetPlayerId(GetEnumPlayer())))
    call ForceAddPlayer(udg_tempPlayerGroup, GetEnumPlayer())
endfunction

function TempPlayersGroup takes nothing returns nothing
    call ForceClear(udg_tempPlayerGroup)
    call ForForce(udg_myPlayerGroup, function TempPlayersGroupEnum)
    call BJDebugMsg("Aftercount: " + I2S(CountPlayersInForceBJ(udg_tempPlayerGroup)))
endfunction

Sometimes, when I call TempPlayersGroup() I get the debug messages as following:

Inside ForForce: 0
Inside ForForce: 1
Inside ForForce: 2
Inside ForForce: 3
Aftercount: 0

(The udg_myPlayerGroup really has got the players from 0 to 3)
Also, my udg_tempPlayerGroup is correctly initialized at Map Initialization as CreateForce()

Any ideas why this could happen?

PS: This does not fail everytime, only sometimes. And more, I didn't post the whole triggers where I call the function because I firstly want to receive some random ideas about why this could fail. I can post the triggers.

Thanks in advice,
hamsterpellet
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
PS: This does not fail everytime, only sometimes. And more, I didn't post the whole triggers where I call the function because I firstly want to receive some random ideas about why this could fail. I can post the triggers.
So what, you mean it can fail and the next time work as intented ?

Make sure that udg_tempPlayerGroup is always a valid group, add a debug, use the function :

native SaveLocationHandle takes hashtable table, integer parentKey, integer childKey, location whichLocation returns boolean

If it returns false then your force is invalid, (null or ghost one).
 
Level 5
Joined
Dec 12, 2011
Messages
116
Thanks already for all of you, but as always I didn't get everything you say at the first time =s

@arhowk:

what's a ForcePickRandomPlayer loop? I will try to guess, anyway:

JASS:
loop
     set p = ForcePickRandomPlayer( myForce )
     exitwhen p == null
     // Do Stuff
     call ForceRemovePlayer(p)
endloop

@Troll-Brain:

Do you mean that the SaveLocationHandle will bug inside a ForForce of an invalid force? I mean, a Hashtable Location function? Did I take it correctly, is it that strange?

Also, what's a ghost force? I will try to guess that it is a force which was destroyed through DestroyForce() but not nulled; also guess that that word is also used with groups.


Slightly offtopic: By the way, when I null a local variable, am I completely killing it? I mean, will it be possible to un-null the variable, to use it again (i'm pretty sure this is valid to globals)

Thanks in advice,

hamsterpellet

PS: +rep given accordingly.
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Thanks already for all of you, but as always I didn't get everything you say at the first time =s

@arhowk:

what's a ForcePickRandomPlayer loop? I will try to guess, anyway:

JASS:
loop
     set p = ForcePickRandomPlayer( myForce )
     exitwhen p == null
     // Do Stuff
     call ForceRemovePlayer(p)
endloop

@Troll-Brain:

Do you mean that the SaveLocationHandle will bug inside a ForForce of an invalid force? I mean, a Hashtable Location function? Did I take it correctly, is it that strange?

Also, what's a ghost force? I will try to guess that it is a force which was destroyed through DestroyForce() but not nulled; also guess that that word is also used with groups.


Slightly offtopic: By the way, when I null a local variable, am I completely killing it? I mean, will it be possible to un-null the variable, to use it again (i'm pretty sure this is valid to globals)

Thanks in advice,

hamsterpellet

PS: +rep given accordingly.

Im not 100% (hell, even 1%) sure what DSG meant with the SaveLocationHandle statement but yes your ForcePickRandomPlayer loops is correct (im not sure if that BJ leaks but i didnt see any in the function but i might be wrong)

Did you test the FPRP loop?

also, nulling a variable does not destroy it. Groups have to be destroyed if theyre not used afterwards
 
Level 5
Joined
Dec 12, 2011
Messages
116
Well, I didn't have time to test anything yet, will test soon.
But look, if I use the FPRP loop, the "source group" will end empty, which is a problem... Do you have an idea of how to avoid that? Notice that the idea of those functions are to simply get a copy of the udg_myPlayerGroup at te udg_tempPlayerGroup.
Thanks already;

@DoctorSuperGood: maybe it's the op limit (but I guess not), I'll take a look at my big scripts...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Do you mean that the SaveLocationHandle will bug inside a ForForce of an invalid force? I mean, a Hashtable Location function? Did I take it correctly, is it that strange?

Also, what's a ghost force? I will try to guess that it is a force which was destroyed through DestroyForce() but not nulled; also guess that that word is also used with groups.

Slightly offtopic: By the way, when I null a local variable, am I completely killing it? I mean, will it be possible to un-null the variable, to use it again (i'm pretty sure this is valid to globals)
Meh, i want mean SaveForceHandle ...
I suggest it because there is no way that you can store an invalid handle in an hashtable.
So if it returns false, then your handle is invalid, the check "!= null" is not enough for ghost handles.

Your guess about what i call a "ghost force" is correct.

When you null a variable, its handle id can be free only if there is no more handles on it.
For most handles there is an handle reference counter, if one or more variables still point on it, the handle id is not recycled when the handle is destroyed.
And there is a bug with local variables, even when the variable should be "killed" (end of the thread) it's not automatically nulled, excepted for function arguments (function ... takes handle arg1, handle arg2 ...)

That's why you need to null local variable handle, since when the handle will be destroyed, the handle reference counter will not be empty.
It also means that if you're 100 % sure that the handle will never be destroyed you don't need to null the local variable.

As long you will use the global variable later, you don't null it, since the handle reference counter will be refreshed soon or late.
Well, in fact there is a really minor memory leak (but not an handle id one, just a memory one) if you don't null a global variable in the same thread where you destroy the handle, but really you don't have to care about it.

Now, there are exceptions such as texttag and image, there is no handle reference counter, which mean you don't need to null them.
The handle id is recycled immediatly when the handle is destroyed, and you can even use this fact to do some silly things, such as get an unit's shadow (well it's also because an other bug, but jass is full of them and sometimes we need them to bypass its limitations :p)

Also, some people say they had memory leaks on their map, until they null every handle, especially player's ones.
That sounds silly since you can hardly create or destroy a player, but who knows, it's jass after all ...

Now, don't take me wrong, i'm just accurate there, but it's a good practice to null every handle (function argument or not) when it's possible.

The suggestion of DSG is possible but that's really unlikely though.
That would mean you've reached the limit op before
call ForceAddPlayer(udg_tempPlayerGroup, GetEnumPlayer())

So that's impossible with the actual code, unless you real code is heavy in this function.
 
Status
Not open for further replies.
Top