lep / jassdoc

Document the WarCraft 3 API
52 stars 20 forks source link

BlzGroupUnitAt: remove comment about removed units being returned as … #148

Open WaterKnight opened 3 months ago

WaterKnight commented 3 months ago

…null

WaterKnight commented 3 months ago

@Luashine please confirm

Luashine commented 3 months ago

That's still correct (returns nil) in Lua 1.36.1.21015. I didn't start my copy-paste script so here's a screenshot from manual code testing.

EDIT: the -1 note is good, keep it please.

nilgroup

WaterKnight commented 3 months ago

That's still correct (returns nil) in Lua 1.36.1.21015. I didn't start my copy-paste script so here's a screenshot from manual code testing.

EDIT: the -1 note is good, keep it please.

nilgroup

In contrast to Lua, in Jass, it appears that RemoveUnit has a delay. Immediately after removing a unit, you can still read its name with GetUnitName and it still appears in the group. After a short delay, it will be properly removed and leave a null gap in the group. In Lua, there is no delay.

function B2S takes boolean b returns string
    if b then
        return "true"
    endif
    return "false"
endfunction

function test takes nothing returns nothing
    local group g = CreateGroup()
    local unit u
    call GroupAddUnit( g, u )
    call RemoveUnit(u)
    //call TriggerSleepAction(0)
    set u = BlzGroupUnitAt(g, 0)
    call BJDebugMsg(B2S(u == null) + ";" + GetUnitName(u))
endfunction

edit: Did a mistake in Lua. In Lua, I have the delay as well. Maybe it is specific unit properties then that make it not immediately be removed. Conducting further tests...

edit2: Or looking at your timestamps, do you have a delay as well between the instructions?

Luashine commented 3 months ago

1.32.10 maps Unit Removal Test.zip

Good test. I extended it to avoid manual mistakes for Jass and transpiled to Lua (and fixed string concat).

Jass and Lua behave the same. The unit is not immediately considered removed from the game, but after sleep the handle really returns null.

Untested cases:

This means that FirstOfGroup iterators work fine in almost all cases except Removal+Sleep which should be really odd cases. That note must be updated.

// Jass result, 1.32.10: // Unit original handle: false,Footman,alive=true;deadBJ=false;pos=-30.000;30.000 // Unit groupAt handle: true;;alive=false;deadBJ=true;pos=0.000;0.000

function B2S takes boolean b returns string
    if b then
        return "true"
    endif
    return "false"
endfunction

native UnitAlive            takes unit id                               returns boolean

// Jass result, 1.32.10:
// Unit original handle: false,Footman,alive=true;deadBJ=false;pos=-30.000;30.000
// Unit groupAt handle: true;;alive=false;deadBJ=true;pos=0.000;0.000

// Lua result, 1.32.10:
// same as Jass above
function TestUnitRemoval takes nothing returns nothing
    local unit u_getgroup
    local string msg1
    local string msg2
    local group g = CreateGroup()
    local unit u_created = CreateUnit(Player(0), 'hfoo', -30, 30, 42)

    call GroupAddUnit( g, u_created )
    call RemoveUnit(u_created)

    set msg1 = "Unit original handle: " + B2S(u_created == null) + ";" + GetUnitName(u_created)
    set msg1 = msg1 + ";alive=" + B2S(UnitAlive(u_created)) + ";deadBJ=" + B2S(IsUnitDeadBJ(u_created))
    set msg1 = msg1 + ";pos=" + R2S(GetUnitX(u_created)) + ";" + R2S(GetUnitY(u_created))
    call TriggerSleepAction(0)
    set u_getgroup = BlzGroupUnitAt(g, 0)

    set msg2 = "Unit groupAt handle: " + B2S(u_getgroup == null) + ";" + GetUnitName(u_getgroup)
    set msg2 = msg2 + ";alive=" + B2S(UnitAlive(u_getgroup)) + ";deadBJ=" + B2S(IsUnitDeadBJ(u_getgroup))
    set msg2 = msg2 + ";pos=" + R2S(GetUnitX(u_getgroup)) + ";" + R2S(GetUnitY(u_getgroup))

    // Messages are intentionally not displayed immediately out of fear of delaying anything
    call BJDebugMsg(msg1)
    call BJDebugMsg(msg2)

    call DestroyGroup(g)

    set g = null
    set u_created = null
    set u_getgroup = null
endfunction
---@param b boolean
---@return string
function B2S(b)
    if b then
        return "true"
    end
    return "false"
end

getmetatable("").__add = function(obj, obj2) return obj .. obj2 end
--native UnitAlive            takes unit id                               returns boolean

-- Jass result, 1.32.10:
-- Unit original handle: false,Footman,alive=true;deadBJ=false
-- Unit groupAt handle: true;;alive=false;deadBJ=true

-- Lua result, 1.32.10:
-- same as Jass above
function TestUnitRemoval()
    local u_getgroup ---@type unit 
    local msg1 ---@type string 
    local msg2 ---@type string 
    local g       = CreateGroup() ---@type group 
    local u_created      = CreateUnit(Player(0), FourCC('hfoo'), -30, 30, 42) ---@type unit 

    GroupAddUnit( g, u_created )
    RemoveUnit(u_created)

    msg1 = "Unit original handle: " + B2S(u_created == nil) + ";" + GetUnitName(u_created)
    msg1 = msg1 + ";alive=" + B2S(UnitAlive(u_created)) + ";deadBJ=" + B2S(IsUnitDeadBJ(u_created))
    msg1 = msg1 + ";pos=" + R2S(GetUnitX(u_created)) + ";" + R2S(GetUnitY(u_created))
    TriggerSleepAction(0)
    u_getgroup = BlzGroupUnitAt(g, 0)

    msg2 = "Unit groupAt handle: " + B2S(u_getgroup == nil) + ";" + GetUnitName(u_getgroup)
    msg2 = msg2 + ";alive=" + B2S(UnitAlive(u_getgroup)) + ";deadBJ=" + B2S(IsUnitDeadBJ(u_getgroup))
    msg2 = msg2 + ";pos=" + R2S(GetUnitX(u_getgroup)) + ";" + R2S(GetUnitY(u_getgroup))

    -- Messages are intentionally not displayed immediately out of fear of delaying anything
    BJDebugMsg(msg1)
    BJDebugMsg(msg2)

    DestroyGroup(g)

    g = nil
    u_created = nil
    u_getgroup = nil
end

--Conversion by vJass2Lua v0.A.2.3