- Joined
- Sep 6, 2013
- Messages
- 6,742
Added a topic about data types. If I wrote wrong information or missed something, please give your input.
Last edited:
primitive: [
integer,
real,
boolean,
string,
code,
handle,
],
intresting: [
string, // any string when displayed can be colored using a code: |cffFF0000<this-text-will-be-displayed-in-red>|r
unit, item, ability, buff,
destructable,
trigger, event,
timer, timerdialog,
rect,
sound,
camerasetup,
effect,
weathereffect,
terraindeformation,
fogmodifier,
dialog, button,
multiboard, multiboarditem, leaderboard,
trackable,
gamecache,
texttag,
lightning,
image,
<text-to-player>, // DisplayTimedTextToPlayer
<cine-filter>, <cinematic-cine>,
],
unintresting: [
player, // glorified integer
agent,
widget,
force,
group,
triggercondition, triggeraction,
quest, questitem, defeatcondition,
location,
region,
boolexpr, conditionfunc, filterfunc,
unitpool, itempool,
ubersplat,
hashtable,
],
not-savable-in-hashtable: [
// code, // can't have code arrays (modulo bug) either so...
camerasetup,
weathereffect,
terraindeformation,
gamecache,
],
enums: [
race,
alliancetype,
racepreference,
gamestate, igamestate, fgamestate,
playerstate,
playerscore,
playergameresult,
unitstate,
aidifficulty,
eventid,
gameevent,
playerevent,
playerunitevent,
unitevent,
limitop,
widgetevent,
dialogevent,
unittype,
gamespeed,
gamedifficulty,
gametype,
mapflag,
mapvisibility,
mapsetting,
mapdensity,
mapcontrol,
fogstate,
playerslotstate,
volumegroup,
camerafield,
playercolor,
placement,
startlocprio,
raritycontrol,
blendmode,
texmapflags,
effecttype,
version,
itemtype,
attacktype,
damagetype,
weapontype,
soundtype,
pathingtype,
],
@TODO: which of the handle extending types (non-enum) use handle-ids >= 0x00_10_00_00 and which use their own specific handle-id pool (e.g: texttag(s))
Like I said, the list is biased, but lets see:@Aniki how you exactly detinguish between intresting and uninteresting?
uninteresting: [
// I don't see the point of this type not being an integer or implicitly convertable to one.
// Its just annothing having to call GetPlayerId (player -> integer) and Player (integer -> player)
// manually all the time. I think in SC2 this type is indeed an integer.
player,
// I don't know why this type was introduced when Blizzard made the hashtable natives.
// It seems pretty pointless.
agent,
// Units, items and destructables are widgets... so we have inheritance there... I just don't like
// inheritance (I do like tagged/discriminated unions =), instead), but at least its only 1 level
// of inheritance (I guess Blizzard learned their lesson from SC1 :P).
// So okay, maybe not that uninteresting.
widget,
// A non-random-access collection of player(s) with callback iteration...
force,
// A non-random-access collection of unit(s) with optional callback iteration,
// slightly better than force, thanks to FirstOfGroup, but FirstOfGroup has
// issues of its own (GroupRefresh), so yeah... not really interesting.
group,
// Removing an event listener (trigger)'s handler functions...
triggercondition, triggeraction,
// These are here because they are cumbersome to read when one wants to put
// a lot of text in the quests menu.
quest, questitem, defeatcondition,
// I wish location was a primitive type (like integer/real), i.e not having to bother
// calling RemoveLocation and nulling them, but they are not, which makes them annoying to use,
// unfortunately.
location,
// Just because of the confusion it creates with using the event "unit enters rect".
region,
// Code pointing to a function with a boolean return value?
boolexpr, conditionfunc, filterfunc,
// I don't think Blizzard used these in WE's jass generation, I guess they are kind of
// intersting from algorithmic point of view.
unitpool, itempool,
// Image, ubersplat, what's the difference?
ubersplat,
// I think we have to thank dota's ubiquitous use of gamecache (and not structs, I don't think "dota knows" what a struct is)
// and the return bug for this overused type. It's occasionally useful, but not as interesting as gamecahe.
hashtable,
],
function [URL='http://wiki.thehelper.net/wc3/jass/Blizzard.j/ForGroupBJ']ForGroupBJ[/URL] takes [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL] whichGroup, [URL='http://wiki.thehelper.net/wc3/jass/common.j/code']code[/URL] callback returns [URL='http://wiki.thehelper.net/wc3/jass/common.j/nothing']nothing[/URL]
// If the user wants the group destroyed, remember that fact and clear
// the flag, in case it is used again in the callback.
local [URL='http://wiki.thehelper.net/wc3/jass/common.j/boolean']boolean[/URL] wantDestroy = [URL='http://wiki.thehelper.net/wc3/bj_wantDestroyGroup']bj_wantDestroyGroup[/URL]
set [URL='http://wiki.thehelper.net/wc3/bj_wantDestroyGroup']bj_wantDestroyGroup[/URL] = false
call [URL='http://wiki.thehelper.net/wc3/jass/common.j/ForGroup']ForGroup[/URL](whichGroup, callback)
// If the user wants the group destroyed, do so now.
if (wantDestroy) then
call [URL='http://wiki.thehelper.net/wc3/jass/common.j/DestroyGroup']DestroyGroup[/URL](whichGroup)
endif
endfunction
function [URL='http://wiki.thehelper.net/wc3/jass/Blizzard.j/GetUnitsInRangeOfLocMatching']GetUnitsInRangeOfLocMatching[/URL] takes [URL='http://wiki.thehelper.net/wc3/jass/common.j/real']real[/URL] radius, [URL='http://wiki.thehelper.net/wc3/jass/common.j/location']location[/URL] whichLocation, [URL='http://wiki.thehelper.net/wc3/jass/common.j/boolexpr']boolexpr[/URL] filter returns [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL]
local [URL='http://wiki.thehelper.net/wc3/jass/common.j/group']group[/URL] g = [URL='http://wiki.thehelper.net/wc3/jass/common.j/CreateGroup']CreateGroup[/URL]()
call [URL='http://wiki.thehelper.net/wc3/jass/common.j/GroupEnumUnitsInRangeOfLoc']GroupEnumUnitsInRangeOfLoc[/URL](g, whichLocation, radius, filter)
call [URL='http://wiki.thehelper.net/wc3/jass/common.j/DestroyBoolExpr']DestroyBoolExpr[/URL](filter)
return g
endfunction
Ah yes XD My badIsnt this the GUI ForGroup:
type location extends agent
call RemoveLocation(<loc>)
What about sound?
Sounds can leak. Though, JASS is needed to really create new sounds, which happens automatically in background only once, when used in GUI. So one is safe in GUI.@IcemanBo What about sound?
There's no leak like this. There's nothing like a destructible group for storage, but only the mere enumeration of destructibles.By the way up to this day I'm still curious if Destructible Groups can leak.
function GetUnitsOfTypeIdAll takes integer unitid returns group
local group result = CreateGroup()
local group g = CreateGroup()
local integer index
set index = 0
loop
set bj_groupEnumTypeId = unitid
call GroupClear(g)
call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
call GroupAddGroup(g, result)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call DestroyGroup(g)
return result
endfunction
is this similar to picking all units in the map and adding condition to only get Footman units?
function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
local group g = CreateGroup()
call GroupEnumUnitsInRect(g, r, filter)
call DestroyBoolExpr(filter)
return g
endfunction
As there are so many GUI functions with reference leaks included I decided not to give some a special platform, even 2 of ref leaks are included, and just mentioned:but this wasn't mentioned/missing at the main post,
Very much BJs (Blizzard JASS functions) which are mostly used in GUI have reference leaks.
You might always look them up to see how a BJ is defined at blizzard.j
For now it looks like you maybe meant only to have one random location, So eaither point_x, or point_y, should be enough.How many variables do I need to define (and then remove) here?
Yes you need to destroy the group, that will be used in condition. Ste the group to a variable, before you use the condition to count units. And destroy after:I suppose that you need to create a temporary variable for UnitGroup (it wouldn't be freed automatically) and "destroying" int_i does not accomplish anything (if it is even possible)?
That's a pure integer comparisons, which don't leak. And getting the level of ability does not create an internal leak, too. It's leak-safe!Another question: what's about leaks in conditions? I have a trigger with the following condition:
(Level of Some_Ability for (Reviving Hero)) Greater than or equal to 1![]()
do I need to change something here?
Let's assume that I need two different random points and a region for some esoteric reason (to make more nested brackets here; I agree that this is not the best way to accomplish this).For now it looks like you maybe meant only to have one random location, So eaither point_x, or point_y, should be enough.
Is a new region required per se, or you only need it for the centered creation?
local location p
set p = GetUnitLoc(GetTriggerUnit())
//do thing with p
call RemoveLocation (p)
set p = null//is this line necessary
(
Yeshi im a few years late but in case anyone is still reading the thread i just want to ask about reference leaks:
do i need to set p to null after removelocation like the example you gave for destroygroup?
JASS:local location p set p = GetUnitLoc(GetTriggerUnit()) //do thing with p call RemoveLocation (p) set p = null//is this line necessary (
It refers to trigger-summoned effects.Effect leak looks really nasty. Does it only refers to trigger-summoned effect? Or cinematic doodads (like fires) and using abilities like charm also cause leaks?
Yes, I'm doing my best to actively get rid of units and unnecessary stuff if the player has no longer access to that portion of the map. However, I have numerous fire animations and a blood-fountain in the intro that's made up of 75 cinematic doodads. However, doodads can't be cleared to simply, so I'm not sure how to get rid of these things. Should I use destructibles or units with cinematic models?It refers to trigger-summoned effects.
For your second question (around fires and such), it depends on whether you want that effect still there."Memory leaks" are a bit of a strange term because we typically think of them as something that is actively causing harm over time--like a faucet that is leaking a bunch of water. But in software, it is a little different. A memory leak just refers to something being held in memory even though it isn't needed anymore. So then the question of whether something is considered a leak is often a question of, "do I need this anymore?"
For example, let's say you have a fire effect that you put on some village building in your map. Is it a leak? It depends. If I want that fire to show to players throughout the entire map, then no--I wouldn't consider that a memory leak. You need it to stay in memory so it can always be shown when a player looks at that building. But what if I only wanted to show that fire during a cinematic? Then yes, I'd consider it a leak if I didn't remove it after the cinematic was over.
All in all--a few leaks here and there likely won't be too much of a problem. It is easy for them to slip through the cracks! I recommend doing your best to remove anything you don't need anymore--and if you are scouring for leaks, I'd put the most attention to any of your periodic triggers. One leak here or there for a cinematic will be pretty inconsequential, but some triggered spells can create dozens or even hundreds of effects/locations per cast, so it is definitely critical to make sure those are all cleaned up!
I'd recommend just leaving them there. Doodads are quite lightweight in terms of memory compared to widgets (units, items, destructibles) as they don't have life and are not walkable, and 75 (or even a couple of thousand) isn't much to worry about. As long as that number isn't growing over time you're fine.Yes, I'm doing my best to actively get rid of units and unnecessary stuff if the player has no longer access to that portion of the map. However, I have numerous fire animations and a blood-fountain in the intro that's made up of 75 cinematic doodads. However, doodads can't be cleared to simply, so I'm not sure how to get rid of these things. Should I use destructibles or units with cinematic models?
I see. The reason I asked is because units and destructibles can be removed and I was not sure whether the miniscule remaining memory leak with these is smaller than leaving in doodads.I'd recommend just leaving them there. Doodads are quite lightweight in terms of memory compared to widgets (units, items, destructibles) as they don't have life and are not walkable, and 75 (or even a couple of thousand) isn't much to worry about. As long as that number isn't growing over time you're fine.
So in terms of memory/memory leaks, I wouldn't worry about it.
The other aspect you might consider though is performance (i.e. FPS)--generally it won't be a concern as most objects are typically not even rendered when the camera is away (through occlusion culling). But if you do want to hide your doodads when you're done, you can create a region for your doodads and then run a trigger like this to hide them:
Animation - Play the hide animation for all doodads of type Fire Blue within (Playable map area).