• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] Need some help on allocation

Status
Not open for further replies.
Level 14
Joined
Apr 20, 2009
Messages
1,543
Okay so I made this script with the intention of using it for something:

JASS:
struct myStruct extends array
    private integer id

    implement Alloc
    
    static method operator [] takes integer index returns thistype
        local thistype this = thistype(index).allocate()
        .id = index
        return this
    endmethod

    private static method doSomething takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local integer uId = GetHandleId(u) - 0x100000
        local thistype myNewInstance = thistype[uId]
        call BJDebugMsg(I2S(thistype(uId).id)) //prints 0 because of stack allocation from Alloc I suppose?
    endmethod
    
    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_DESELECTED, null)
            set i = i + 1
            exitwhen i == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddCondition(t, Condition(function thistype.doSomething))
        set t = null
    endmethod
endstruct

The problem is: how can I do this correctly?

EDIT: I think I need to use a heap allocator, but I'm not sure...
Should I implement Binary Heap instead? http://www.hiveworkshop.com/forums/jass-resources-412/snippet-binary-heap-199353/ (tried this but it gives me an error, check my last post)

I'm currently using it like this:

JASS:
implement BinaryHeap

static method operator [] takes integer index returns thistype
    local thistype this = thistype.allocate(index)
    .id = index
    return this
endmethod
 
Last edited:
Level 16
Joined
Aug 7, 2009
Messages
1,403
If you're trying to attach struct instances to a unit, you could simply use a unit indexer, and use GetUnitUserData. You don't even need to allocate your instances, you can just use these:
JASS:
call thistype(GetUnitUserData(GetTriggerData()).myNonStaticMethod()
...
local thistype this=GetUnitUserData(GetTriggerUnit())

Quick, simple, easy-to-use solution.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Isn't it possible to use that same solution for converted handle ID's?
Imagine I want to attach it to any handle, would this work in the same fasshioned way?

If so, then this is probably an easier way of accomplishing what I want, thank you Luorax!
What does it mean not to allocate and deallocate? Isn't this a bad practice?
Shouldn't I destroy my instances? If so, how will this be done if the instance isn't allocated? Set this = 0?

EDIT: Could you give a code example? For some reason it doesn't seem to work the way I intend it to be.
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
JASS:
struct MyStruct extends array

    real x
    real y

    static method operator [] takes unit u returns thistype
        return thistype(GetUnitUserData(u))
    endmethod
    private method myNonStaticMethod takes nothing returns nothing
        set this.x=GetSpellTargetX()
        set this.y=GetSpellTargetY()
    endmethod
    static method myCallbackMethod takes nothing returns boolean
        call thistype(GetUnitUserData(GetTriggerUnit())).myNonStaticMethod()
        return false
    endmethod
endstruct

It's not that allocating/deallocating those instances is bad, or anything, but it's pointless. You need to understand how structs are implemented in WC3 to understand it.

Also no, it wouldn't work for other handles (except for items). A unit indexer attaches a number from 0-8190 to a unit, that's why you can use it like that. For handles, you can just use Table instances.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
JASS:
struct MyStruct extends array

    real x
    real y

    static method operator [] takes unit u returns thistype
        return thistype(GetUnitUserData(u))
    endmethod
    private method myNonStaticMethod takes nothing returns nothing
        set this.x=GetSpellTargetX()
        set this.y=GetSpellTargetY()
    endmethod
    static method myCallbackMethod takes nothing returns boolean
        call thistype(GetUnitUserData(GetTriggerUnit())).myNonStaticMethod()
        return false
    endmethod
endstruct

It's not that allocating/deallocating those instances is bad, or anything, but it's pointless. You need to understand how structs are implemented in WC3 to understand it.

I shall take a look at struct implementation a bit more then. I've watched nestharus's vJass 10 and 11 several times but I still can't really grasp the entire subject. I'll keep learning untill I do.

A unit indexer attaches a number from 0-8190 to a unit
And a converted handle Id can not?
Hmm well I do see a point with the amount of handles since it could go over 8190, but still that wouldn't be a problem as long as you don't have more then 8190 handles in your game right?
I don't usually hit that limit... So why shouldn't it work?
 
Level 16
Joined
Aug 7, 2009
Messages
1,403
And a converted handle Id can not?
Hmm well I do see a point with the amount of handles since it could go over 8190, but still that wouldn't be a problem as long as you don't have more then 8190 handles in your game right?
I don't usually hit that limit... So why shouldn't it work?

Print the handle id of a random handle, and you shall figure it out :)

It's also faster/simpler to just use the index, and more reliable.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Print the handle id of a random handle, and you shall figure it out :)

I just did:

JASS:
call BJDebugMsg(I2S(GetHandleId(u)-0x100000))
This prints out 13 for me. Why is that a problem? Doesn't that work just fine as the index for an array?
As long as I don't have more then 8190 instances, I don't see how it could go wrong?

It's also faster/simpler to just use the index, and more reliable.
How is it faster?
More reliable I can imagine. I find using handleId's with offsets just as simple?

What version of Alloc has allocate() as a method?

http://www.hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/

EDIT: I'm trying to implement the Binary heap allocator. I'm not that famillair with interfaces. Does anyone know what the following compile error means?
Expected: create

I suppose it has something to do with not having a create method, but I added it to both my struct and my interface and nothing happened. :/
My struct does extend the interface and I implemented the Binary Heap module.

I still have a lot to learn about vJass it seems. This is what I did:
JASS:
interface myHeap
    private static method compare takes thistype value1, thistype value2 returns boolean
    static readonly thistype root
    readonly thistype node
    readonly thistype heap
    static readonly integer size
    readonly integer value
    method modify takes integer sortValue returns nothing
    static method insert takes integer sortValue returns thistype
    method delete takes nothing returns nothing
    static method clear takes nothing returns nothing
endinterface

it shows this compile error at: private static method compare.
 
allocate is a static method, not a regular method. (that was what mag was pointing out) So if you are passing an instance with thistype(index).allocate() (where thistype(index) serves as an instance), eh it just doesn't make much sense.

I would just use custom allocation. If you want to be able to read it as thistype(index) then just do:
JASS:
//   
    static method operator [] takes integer index returns thistype
        local thistype this = thistype(index)
        .id = index
        return this
    endmethod
You don't need allocation in that case. But in reality all you are doing at the moment is using an array. That sort of direct allocation is just like doing x[index].
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
allocate is a static method, not a regular method. (that was what mag was pointing out) So if you are passing an instance with thistype(index).allocate() (where thistype(index) serves as an instance), eh it just doesn't make much sense.

I would just use custom allocation. If you want to be able to read it as thistype(index) then just do:
JASS:
//   
    static method operator [] takes integer index returns thistype
        local thistype this = thistype(index)
        .id = index
        return this
    endmethod
You don't need allocation in that case. But in reality all you are doing at the moment is using an array. That sort of direct allocation is just like doing x[index].

Ahh, thank you for the elaborate explanation.
This was exactly what I was looking for.
I understand exactly what you mean.

It's similar to the answer Luorax gave me and I understand why now.
 
Status
Not open for further replies.
Top