• 🏆 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] Class

A simple module that provides an allocator (newClass), deallocator (endClass), initializer (initClass), an onDestroy (onEndClass) and a Table that is only created if needed and gets garbage collected on-destroy (getClassTable).

Requires Table version 6

Required API:

implement Class
Can be implemented in any struct - whether it extends array or not (though it only makes sense to use this in the context of an array struct). Similar to AGD's GlobalAlloc, it doesn't add any globals to the struct when the module is run, but this has the following key differences:
  • Uses the typeid directly as a Table rather than as a faux 2D array.
  • Bad values are handled during runtime rather than only in DEBUG_MODE.
  • Debug messages will work when TEST mode is true, since Blizzard has permanently disabled DEBUG_MODE.
  • Does not clash with the namespace for established systems like vJass structs nor Sevion's Alloc.
  • Includes the initClass and onEndClass methods, as well as getClassTable.
thistype.newClass()
Behaves the same as allocate in vJass/Alloc.
NOTE: Calls to this method should be placed BELOW the implement Class statement to prevent vJass from silently generating duplicate code+triggers.

this.endClass()
Behaves the same as deallocate in vJass/Alloc, but returns a boolean to assess whether the class instance was successfully destroyed (true) or had already been destroyed (false). It will also call the onEndClass method, which is analoguous to onDestroy in vJass.
NOTE: Calls to this method should be placed BELOW the implement Class statement to prevent vJass from silently generating duplicate code+triggers.

Optional API:

this.onEndClass()
Called during the event a class instance is destroyed.
NOTE: It must be placed ABOVE the implement Class statement, otherwise it will have no effect.

thistype.initClass()
Static method that is called only once (during the map's loading sequence). It is like onInit, but it is called during the module sequence. Therefore, if you were already injecting a module initializer into your struct, this module can cover that behavior for you.
NOTE: It must be placed ABOVE the implement Class statement, otherwise it will have no effect.

this.getClassTable()
Call to access a table for your class instance. It will be destroyed automatically when endClass() is called.
NOTE: Calls to this method should be placed BELOW the implement Class statement to prevent vJass from silently generating duplicate code+triggers.

JASS:
// Class version 1.0 by Bribe.
// Hosted at https://www.hiveworkshop.com/threads/class.351587/
// Requires Table version 6 https//www.hiveworkshop.com/threads/188084/
library Class requires Table

    globals
        private constant boolean TEST = true
    endglobals

    public function New takes Table table returns integer
        local integer current = table[0]
        if current == 0 then
            set current = R2I(table.real[0]) + 1
            if current >= JASS_MAX_ARRAY_SIZE then
                static if TEST then
                    call BJDebugMsg("Class.new Error: Too many active instances running simultaneously; class " + I2S(table))
                endif
                return 0
            else
                set table.real[0] = current
            endif
        else
            set table[0] = table[-current]
        endif
        set table.boolean[-current] = true
        return current
    endfunction

    public function End takes Table table, integer current returns boolean
        if table.boolean[-current] then
            call table.boolean.remove(-current)
            set table[-current] = table[0]
            set table[0] = current
            if table.has(current) then
                // clears the data created by any calls to getClassTable()
                call table.remove(current)
            endif
            return true
        endif
        static if TEST then
            call BJDebugMsg("Class.end Error: Tried to destroy invalid instance; class " + I2S(table) + " -> " + I2S(current))
        endif
        return false
    endfunction

    module Class
        method getClassTable takes nothing returns Table
            return Table(thistype.typeid).link(this)
        endmethod

        static method newClass takes nothing returns thistype
            return New(thistype.typeid)
        endmethod

        method endClass takes nothing returns boolean
            static if thistype.onEndClass.exists then
                if End(thistype.typeid, this) then
                    call this.onEndClass()
                    return true
                endif
                return false
            else
                return End(thistype.typeid, this)
            endif
        endmethod

        static if thistype.initClass.exists then
            private static method onInit takes nothing returns nothing
                call thistype.initClass()
            endmethod
        endif
    endmodule
endlibrary
 
Last edited:
Top