• 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.

[System] Malloc

Extension tools for OOP
JASS:
/*
*   Creates an extendable struct
*/
//! textmacro EXTEND_NOTHING takes PROP_COUNT
    static constant integer PROP_COUNT = $PROP_COUNT$
    static method allocate takes nothing returns thistype
        return IntegerPointer.allocate($PROP_COUNT$)
    endmethod
//! endtextmacro
/*
*   Extends from another struct
*
*       STRUCT
*           -   the name of the struct to extend
*       PROP_COUNT
*           -   the number of properties that the new extending struct will have
*
*       Auto Generated
*           -   static constant integer PROP_COUNT = $PROP_COUNT$
*           -   static method allocate takes nothing returns thistype
*/
//! textmacro EXTEND takes STRUCT, PROP_COUNT
    static constant integer PROP_COUNT = $STRUCT$.PROP_COUNT + $PROP_COUNT$
    static method allocate takes nothing returns thistype
        return IntegerPointer.allocate(PROP_COUNT)
    endmethod
//! endtextmacro
/*
*   Creates new property for struct
*
*       PROPERTY_NAME
*           -   the name of the property
*       PROPERTY_ID
*           -   the pointer that the property is bound to
*       RETURN_TYPE
*           -   the return type of the operator (must be integer or struct)
*
*       Extending:
*           -   CREATE_PROPERTY("name0", "PARENT_STRUCT.PROP_COUNT + 0", "type")
*           -   CREATE_PROPERTY("name2", "PARENT_STRUCT.PROP_COUNT + 1", "type")
*           -   CREATE_PROPERTY("name3", "PARENT_STRUCT.PROP_COUNT + 2", "type")
*
*       Automatically Generated:
*           static constant integer PROPERTY_$PROPERTY_NAME$        //the id the property is bound to
*           thistype $PROPERTY_NAME$                                //setters/getters for the property
*/
//! textmacro CREATE_PROPERTY takes PROPERTY_NAME, PROPERTY_ID, RETURN_TYPE
    static constant integer PROPERTY_$PROPERTY_NAME$ = $PROPERTY_ID$
    method operator $PROPERTY_NAME$ takes nothing returns $RETURN_TYPE$
        return IntegerPointer(this)[$PROPERTY_ID$]
    endmethod
    method operator $PROPERTY_NAME$= takes IntegerPointer pointer returns nothing
        set IntegerPointer(this)[$PROPERTY_ID$] = pointer
    endmethod
//! endtextmacro

/*
struct tester extends array
    //! runtextmacro CREATE_PROPERTY_EX("u", "0", "unit", "UnitPointer")
endstruct
*/
//! textmacro CREATE_PROPERTY_EX takes PROPERTY_NAME, PROPERTY_ID, RETURN_TYPE, TYPECAST_TYPE
    static constant integer PROPERTY_$PROPERTY_NAME$ = $PROPERTY_ID$
    method operator $PROPERTY_NAME$ takes nothing returns $RETURN_TYPE$
        return $TYPECAST_TYPE$(this + $PROPERTY_ID$).typecast()
    endmethod
    method operator $PROPERTY_NAME$= takes $RETURN_TYPE$ value returns nothing
        call $TYPECAST_TYPE$(this + $PROPERTY_ID$).put(value)
    endmethod
//! endtextmacro

JASS:
library Malloc  /* v1.0.1.0
*                   ~Nes
*************************************************************************************
*
*   Heap memory allocation running off of a hashtable to store memory
*
*   Uses: 
*           -   Learning about pointers
*
*           -   Preparing for a language like c++
*
*           -   Data structures that can be passed into *ANY* system and can hold *ANY* type
*               with *ANY* structure (custom, list, queue, heap, etc).
*
*************************************************************************************
*
*   debug function IsMallocEnabled takes nothing returns boolean
*   debug function DisableMalloc takes nothing returns nothing
*       -   For custom memory types, if that memory type encounters an error, the system can be disabled
*       -   Before doing any operations in a custom memory type, check if the system is disabled
*       -   If the system is disabled, crash the thread
*
*************************************************************************************
*
*    struct MemoryType
*       readonly static integer count
*       readonly string name
*       readonly boolean valid
*
*       method operator == takes MemoryType other returns boolean
*           -   check if the this is of type other
*           -   square == rectangle -> true
*           -   rectangle == square -> false
*
*       static method create takes string name, MemoryType extend returns MemoryType
*           -   creates new memory type of name extending other memory type
*
*************************************************************************************
*
*   struct Pointer
*       readonly static MemoryType memoryType
*
*       readonly MemoryType type
*       readonly integer size
*
*       static method allocate takes integer arraySize, MemoryType memoryType returns Pointer
*       method deallocate takes nothing returns nothing
*
*************************************************************************************
*
*   struct AgentPointer extends Pointer
*       readonly static MemoryType memoryType
*
*       readonly MemoryType type
*       readonly integer size
*
*       method operator []= takes integer offset, agent value returns nothing
*
*       static method allocate takes integer arraySize returns thistype
*       method deallocate takes nothing returns nothing
*
*************************************************************************************
*
*   struct BoooleanPointer extends Pointer
*   struct String extends Pointer
*   struct Integer extends Pointer
*   struct FogState extends Pointer
*   struct TextTag extends Pointer
*   struct Lightning extends Pointer
*   struct Image extends Pointer
*   struct Ubersplat extends Pointer
*   struct Region extends Pointer
*   struct Timer extends Pointer
*   struct TriggerAction extends Pointer
*   struct UnitPool extends Pointer
*   struct ItemPool extends Pointer
*   struct Real extends integer
*   struct Player extends agent
*   struct Widget extends agent
*   struct Ability extends agent
*   struct Trigger extends agent
*   struct TriggerCondition extends agent
*   struct TriggerEvent extends agent
*   struct Force extends agent
*   struct Group extends agent
*   struct Location extends agent
*   struct Rect extends agent
*   struct BooleanExpr extends agent
*   struct Sound extends agent
*   struct Effect extends agent
*   struct Quest extends agent
*   struct QuestItem extends agent
*   struct DefeatCondition extends agent
*   struct TimerDialog extends agent
*   struct Leaderboard extends agent
*   struct Multiboard extends agent
*   struct MultiboardItem extends agent
*   struct Trackable extends agent
*   struct Dialog extends agent
*   struct Button extends agent
*   struct FogModifier extends agent
*   struct Hashtable extends agent
*   struct Destructable extends widget
*   struct ItemHandle extends widget
*   struct UnitHandle extends wiget
*
*       readonly static MemoryType memoryType
*
*       readonly MemoryType type
*       readonly integer size
*
*       method operator [] takes integer offset returns $TYPE$
*       method operator []= takes integer offset, $TYPE$ value returns nothing
*       method put takes $TYPE$ val returns nothing
*       method typecast takes nothing returns $TYPE$
*           -   $TYPE$ refers to the value type: integer, boolean, item, widget, etc
*           -   Can do pointer arithmetic with this
*
*       static method allocate takes integer arraySize returns thistype
*       method deallocate takes nothing returns nothing
*
*************************************************************************************/
    private keyword Heap
    private keyword Memory
    
    globals
        private hashtable memory = InitHashtable()
        
        private constant integer HEAP_POSITION = 0
        private constant integer HEAP_POINTER = 1
        private constant integer MEMORY = 2
        private constant integer MEMORY_TYPE = 3
        private constant integer MEMORY_SIZE = 4
        private constant integer ARRAY_SIZE = 5
        private constant integer LIMIT = 6
    endglobals
    
    /*
    *   static integer count
    *   string name
    */
    struct MemoryType extends array
        readonly static integer count = 0
        readonly string name
        private MemoryType base
        
        static method create takes string name, MemoryType extend returns MemoryType
            local thistype this = count + 1
            
            debug if (not Memory.enabled) then
                debug set this = 1/0
            debug endif
            
            debug if (0 == extend and (name != "pointer" or this != 1)) then
                debug set Memory.enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"INVALID EXTENDED MEMORY TYPE: " + name + "extends (" + I2S(extend) + ")")
                debug set this = 1/0
            debug endif
            
            set count = this
            
            set this.name = name
            set this.base = extend
            
            return this
        endmethod
        
        //check if the this is of type other
        //square == rectangle -> true
        //rectangle == square -> false
        method operator == takes MemoryType other returns boolean
            loop
                exitwhen 0 == integer(this) or integer(this) == integer(other)
                set this = base
            endloop
            
            return integer(this) == integer(other)
        endmethod
        
        method operator valid takes nothing returns boolean
            return 0 < this and this <= count
        endmethod
    endstruct
    
    /*
    *   Heap position
    *   MemoryType memoryType
    *   integer memorySize
    *   integer arraySize
    *   boolean limit
    */
    private struct Pointer_p extends array
        method operator position takes nothing returns Heap
            return LoadInteger(memory, HEAP_POSITION, this)
        endmethod
        method operator position= takes Heap position returns nothing
            call SaveInteger(memory, HEAP_POSITION, this, position)
        endmethod
        method operator memoryType takes nothing returns MemoryType
            return LoadInteger(memory, MEMORY_TYPE, this)
        endmethod
        method operator memoryType= takes MemoryType t returns nothing
            call SaveInteger(memory, MEMORY_TYPE, this, t)
        endmethod
        method operator memorySize takes nothing returns integer
            return LoadInteger(memory, MEMORY_SIZE, this)
        endmethod
        method operator memorySize= takes integer size returns nothing
            call SaveInteger(memory, MEMORY_SIZE, this, size)
        endmethod
        method operator arraySize takes nothing returns integer
            return LoadInteger(memory, ARRAY_SIZE, this)
        endmethod
        method operator arraySize= takes integer size returns nothing
            call SaveInteger(memory, ARRAY_SIZE, this, size)
        endmethod
        method operator limit takes nothing returns boolean
            return LoadBoolean(memory, LIMIT, this)
        endmethod
        method operator limit= takes boolean flag returns nothing
            call SaveBoolean(memory, LIMIT, this, flag)
        endmethod
    endstruct

    /*
    *   Pointer_p pointer
    *
    *   readonly Heap parent
    *   readonly Heap left
    *   readonly Heap right
    *
    *   static method link takes Pointer_p pointer, Heap position returns nothing
    *   static method bubbleUp takes Pointer_p pointer returns nothing
    *   static method bubbleDown takes Pointer_p pointer returns nothing
    *   static method insert takes Pointer_p pointer returns nothing
    *   static method remove takes Pointer_p pointer returns nothing
    */
    private struct Heap extends array
        static Heap size = 0
    
        method operator pointer takes nothing returns Pointer_p
            return LoadInteger(memory, HEAP_POINTER, this)
        endmethod
        method operator pointer= takes Pointer_p pointer returns nothing
            call SaveInteger(memory, HEAP_POINTER, this, pointer)
        endmethod
        
        method operator parent takes nothing returns Heap
            return this/2
        endmethod
        method operator left takes nothing returns Heap
            return this*2
        endmethod
        method operator right takes nothing returns Heap
            return this*2 + 1
        endmethod
        
        static method link takes Pointer_p pointer, Heap position returns nothing
            set pointer.position = position
            set position.pointer = pointer
        endmethod
        
        static method bubbleUp takes Pointer_p pointer returns nothing
            local integer pointerMemorySize = pointer.memorySize
            local Heap pointerPosition = pointer.position
            
            local Heap parentPosition = pointerPosition.parent
            local Pointer_p parentPointer = parentPosition.pointer
            
            loop
                exitwhen 0 == parentPosition or parentPointer.memorySize <= pointerMemorySize
                call link(parentPointer, pointerPosition)
                
                set pointerPosition = parentPosition
                set parentPosition = pointerPosition.parent
                set parentPointer = parentPosition.pointer
            endloop
            
            call link(pointer, pointerPosition)
        endmethod
        
        static method bubbleDown takes Pointer_p pointer returns nothing
            local integer pointerMemorySize = pointer.memorySize
            local Heap pointerPosition = pointer.position
            
            local Heap leftPosition = pointerPosition.left
            local Pointer_p leftPointer = leftPosition.pointer
            local integer leftMemorySize = leftPointer.memorySize
            
            local Heap rightPosition = pointerPosition.right
            local Pointer_p rightPointer = rightPosition.pointer
            local integer rightMemorySize = rightPointer.memorySize
            
            loop
                exitwhen (0 == leftPointer or leftMemorySize <= pointerMemorySize) and (0 == rightPointer or rightMemorySize <= pointerMemorySize)
                if (0 == rightPointer or (0 != leftPointer and leftMemorySize > rightMemorySize)) then
                    call link(leftPointer, pointerPosition)
                    set pointerPosition = leftPosition
                else
                    call link(rightPointer, pointerPosition)
                    set pointerPosition = rightPosition
                endif
                
                set leftPosition = pointerPosition.left
                set leftPointer = leftPosition.pointer
                set leftMemorySize = leftPointer.memorySize
                
                set rightPosition = pointerPosition.right
                set rightPointer = rightPosition.pointer
                set rightMemorySize = rightPointer.memorySize
            endloop
            
            call link(pointer, pointerPosition)
        endmethod
        
        static method insert takes Pointer_p pointer returns nothing
            set size = size + 1
            call link(pointer, size)
            call bubbleUp(pointer)
        endmethod
        
        static method remove takes Pointer_p pointerToRecycle returns nothing
            local Heap pointerPosition = pointerToRecycle.position
            local Pointer_p pointer = size.pointer
            
            set size.pointer = 0
            set size = size - 1
            
            call link(pointer, pointerPosition)
            
            if (pointerPosition != 1) then
                call bubbleUp(pointer)
            endif
            call bubbleDown(pointer)
        endmethod
        
        private static method clear takes Pointer_p pointer returns nothing
            set pointer.limit = false
            set pointer.memorySize = 0
        endmethod
        
        private static method clearExtraPointers takes Pointer_p lastIndex, Pointer_p pointer returns nothing
            call clear(lastIndex)
            call clear(pointer)
            call remove(pointer)
        endmethod
        
        static method defragment takes Pointer_p pointer returns nothing
            local integer   pointerMemorySize   = pointer.memorySize
            local Pointer_p pointerLastIndex    = pointer + pointerMemorySize - 1
            local Heap      pointerPosition     = pointer.position
            
            local Pointer_p pointerMerge
            
            set pointerMerge = pointer - 1
            if (pointerMerge.limit) then
                /*
                *   pointerMerge -> pointerMergeLastIndex -> pointer1 -> pointerLastIndex
                */
                call clearExtraPointers (pointerMerge + pointerMerge.memorySize - 1 , pointer)
                set pointer             = pointerMerge
                set pointerMemorySize   = pointerLastIndex - pointer + 1
            endif
            
            set pointerMerge = pointer + pointerMemorySize
            if (pointerMerge.limit) then
                /*
                *   pointer -> pointerLastIndex -> pointerMerge -> pointerMergeLastIndex
                */
                set pointerMemorySize   = pointerMerge.memorySize               //temporary as pointerMerge is cleared out
                                                                                //and it is needed to get pointerMergeLastIndex
                call clearExtraPointers (pointerLastIndex, pointerMerge)        //clear pointers in middle
                set pointerLastIndex    = pointerMerge + pointerMemorySize - 1  //get new last index (pointerMergeLastIndex)
                set pointerMemorySize   = pointerLastIndex - pointer + 1        //get new size
            endif
            
            set pointer.memorySize = pointerMemorySize
            set pointerLastIndex.memorySize = pointerMemorySize
            
            call link(pointer, pointerPosition)
            
            call bubbleUp(pointer)
        endmethod
    endstruct
    
    private struct Memory extends array
        private static integer allocatedMemory = 1
        debug static boolean enabled = true
    
        static method allocate takes integer arraySize returns thistype
            local Pointer_p pointer = Heap(1).pointer
            local integer pointerMemorySize = pointer.memorySize
            
            debug if (not enabled) then
                debug set pointer = 1/0
            debug endif
            
            debug if (arraySize < 1) then
                debug set enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPTED TO ALLOCATE POINTER OF INVALID SIZE: (" + I2S(arraySize) + ")")
                debug set pointer = 1/0
            debug endif
            
            if (0 == Heap.size or pointerMemorySize < arraySize) then
                set pointer = allocatedMemory
                set allocatedMemory = pointer + arraySize
            else
                set pointer.memorySize                                      = 0
                set pointer.limit                                           = false
                set Pointer_p(pointer + arraySize).memorySize               = pointerMemorySize - arraySize
                set Pointer_p(pointer + pointerMemorySize - 1).memorySize   = pointerMemorySize - arraySize
                
                if (0 == pointerMemorySize - arraySize) then
                    call Heap.remove(pointer)
                    set Pointer_p(pointer + pointerMemorySize - 1).limit = false
                else
                    call Heap.link(pointer + arraySize, 1)
                    set Pointer_p(pointer + arraySize).limit = true
                    call Heap.bubbleDown(pointer + arraySize)
                endif
            endif
            
            set pointer.arraySize = arraySize
            
            return pointer
        endmethod
        
        static method deallocate takes Pointer_p pointer returns nothing
            local integer pointerMemorySize = pointer.arraySize
            
            debug if (not enabled) then
                debug set pointer = 1/0
            debug endif
            
            debug if (not pointer.memoryType.valid) then
                debug set enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPTED TO DEALLOCATE NULL POINTER: (" + I2S(pointer) + ")")
                debug set pointer = 1/0
            debug endif
            
            set pointer.memoryType = 0
            set pointer.arraySize = 0
            
            set pointer.memorySize = pointerMemorySize
            set Pointer_p(pointer + pointerMemorySize - 1).memorySize = pointerMemorySize
            set pointer.limit = true
            set Pointer_p(pointer + pointerMemorySize - 1).limit = true
            
            call Heap.insert(pointer)
            call Heap.defragment(pointer)
        endmethod
    endstruct
    
    private module PointerInit
        private static method onInit takes nothing returns nothing
            set memoryType = MemoryType.create("pointer", 0)
        endmethod
    endmodule
    struct Pointer extends array
        readonly static MemoryType memoryType
    
        method operator type takes nothing returns MemoryType
            return Pointer_p(this).memoryType
        endmethod
        method operator size takes nothing returns integer
            return Pointer_p(this).arraySize
        endmethod
        static method allocate takes integer arraySize, MemoryType memoryType returns Pointer
            local Pointer_p this
            
            debug if (not Memory.enabled) then
                debug set this = 1/0
            debug endif
            debug if (not memoryType.valid) then
                debug set Memory.enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPTED TO ALLOCATE POINTER OF INVALID MEMORY TYPE: (" + I2S(memoryType) + ")")
                debug set this = 1/0
            debug endif
            
            set this = Memory.allocate(arraySize)
            set this.memoryType = memoryType
            
            return this
        endmethod
        method deallocate takes nothing returns nothing
            call Memory.deallocate(this)
        endmethod
        
        implement PointerInit
    endstruct
    
    //! textmacro PTR_STRUCT takes TYPE, FUNC_TYPE, LOAD_TYPE, PARENT
        private module $FUNC_TYPE$Init
            private static method onInit takes nothing returns nothing
                set memoryType = MemoryType.create("$TYPE$", $PARENT$)
            endmethod
        endmodule
        struct $FUNC_TYPE$Pointer extends array
            readonly static MemoryType memoryType
        
            method operator type takes nothing returns MemoryType
                return Pointer(this).type
            endmethod
            method operator size takes nothing returns integer
                return Pointer(this).size
            endmethod
            method operator [] takes integer offset returns $TYPE$
                debug if (not Memory.enabled) then
                    debug set offset = 1/0
                debug endif
                debug if not (this + offset < Pointer_p(this).arraySize) then
                    debug set Memory.enabled = false
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"READ ARRAY OUT OF BOUNDS: (" + I2S(this) + "[" + I2S(offset) +"]) -> " + memoryType.name)
                    debug set this = 1/0
                debug endif
                debug if not (Pointer_p(this).memoryType == memoryType) then
                    debug set Memory.enabled = false
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPT TO PERFORM INVALID TYPECAST ON MEMORY FROM (" + Pointer_p(this).memoryType.name + ") to (" + memoryType.name)
                    debug set this = 1/0
                debug endif
                return Load$LOAD_TYPE$(memory, MEMORY, this + offset)
            endmethod
            method typecast takes nothing returns $TYPE$
                debug if (not Memory.enabled) then
                    debug set this = 1/0
                debug endif
                return Load$LOAD_TYPE$(memory, MEMORY, this)
            endmethod
            method put takes $TYPE$ val returns nothing
                debug if (not Memory.enabled) then
                    debug set this = 1/0
                debug endif
                call Save$LOAD_TYPE$(memory, MEMORY, this, val)
            endmethod
            method operator []= takes integer offset, $TYPE$ value returns nothing
                debug if (not Memory.enabled) then
                    debug set offset = 1/0
                debug endif
                debug if not (this + offset < Pointer_p(this).arraySize) then
                    debug set Memory.enabled = false
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"WRITE ARRAY OUT OF BOUNDS: (" + I2S(this) + "[" + I2S(offset) +"]) -> " + memoryType.name)
                    debug set this = 1/0
                debug endif
                debug if not (Pointer_p(this).memoryType == memoryType) then
                    debug set Memory.enabled = false
                    debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPT TO PERFORM INVALID TYPECAST ON MEMORY FROM (" + Pointer_p(this).memoryType.name + ") to (" + memoryType.name)
                    debug set this = 1/0
                debug endif
                call Save$LOAD_TYPE$(memory, MEMORY, this + offset, value)
            endmethod
            static method allocate takes integer arraySize returns thistype
                local Pointer_p this = Memory.allocate(arraySize)
                
                set this.memoryType = memoryType
                
                return this
            endmethod
            method deallocate takes nothing returns nothing
                call Pointer(this).deallocate()
            endmethod
            
            implement $FUNC_TYPE$Init
        endstruct
    //! endtextmacro
    
    private module AgentInit
        private static method onInit takes nothing returns nothing
            set memoryType = MemoryType.create("agent", Pointer.memoryType)
        endmethod
    endmodule
    struct AgentPointer extends array
        readonly static MemoryType memoryType
    
        method operator type takes nothing returns MemoryType
            return Pointer(this).type
        endmethod
        method operator size takes nothing returns integer
            return Pointer(this).size
        endmethod
        method operator []= takes integer offset, agent value returns nothing
            debug if (not Memory.enabled) then
                debug set offset = 1/0
            debug endif
            debug if not (this + offset < Pointer_p(this).arraySize) then
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,10,I2S(this + offset) + ">=" + I2S(Pointer_p(this).arraySize))
                debug set Memory.enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"READ ARRAY OUT OF BOUNDS: (" + I2S(this) + "[" + I2S(offset) +"]) -> " + memoryType.name)
                debug set this = 1/0
            debug endif
            debug if not (Pointer_p(this).memoryType == memoryType) then
                debug set Memory.enabled = false
                debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"ATTEMPT TO PERFORM INVALID TYPECAST ON MEMORY FROM (" + Pointer_p(this).memoryType.name + ") to (" + memoryType.name)
                debug set this = 1/0
            debug endif
            call SaveAgentHandle(memory, MEMORY, this + offset, value)
        endmethod
        static method allocate takes integer arraySize returns thistype
            local Pointer_p this = Memory.allocate(arraySize)
            
            set this.memoryType = memoryType
            
            return this
        endmethod
        method deallocate takes nothing returns nothing
            call Pointer(this).deallocate()
        endmethod
        
        implement AgentInit
    endstruct
    
    //! runtextmacro PTR_STRUCT("boolean", "Boolean", "Boolean",                                    "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("string", "String", "Str",                                          "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("integer", "Integer", "Integer",                                    "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("fogstate", "FogState", "FogStateHandle",                           "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("texttag", "TextTag", "TextTagHandle",                              "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("lightning", "Lightning", "LightningHandle",                        "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("image", "Image", "ImageHandle",                                    "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("ubersplat", "Ubersplat", "UbersplatHandle",                        "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("region", "Region", "RegionHandle",                                 "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("timer", "Timer", "TimerHandle",                                    "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("triggeraction", "TriggerAction", "TriggerActionHandle",            "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("unitpool", "UnitPool", "UnitPoolHandle",                           "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("itempool", "ItemPool", "ItemPoolHandle",                           "Pointer.memoryType")
    //! runtextmacro PTR_STRUCT("real", "Real", "Real",                                             "IntegerPointer.memoryType")
    //! runtextmacro PTR_STRUCT("player", "Player", "PlayerHandle",                                 "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("widget", "Widget", "WidgetHandle",                                 "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("ability", "Ability", "AbilityHandle",                              "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("trigger", "Trigger", "TriggerHandle",                              "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("triggercondition", "TriggerCondition", "TriggerConditionHandle",   "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("event", "TriggerEvent", "TriggerEventHandle",                      "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("force", "Force", "ForceHandle",                                    "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("group", "Group", "GroupHandle",                                    "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("location", "Location", "LocationHandle",                           "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("rect", "Rect", "RectHandle",                                       "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("boolexpr", "BooleanExpr", "BooleanExprHandle",                     "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("sound", "Sound", "SoundHandle",                                    "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("effect", "Effect", "EffectHandle",                                 "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("quest", "Quest", "QuestHandle",                                    "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("questitem", "QuestItem", "QuestItemHandle",                        "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("defeatcondition", "DefeatCondition", "DefeatConditionHandle",      "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("timerdialog", "TimerDialog", "TimerDialogHandle",                  "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("leaderboard", "Leaderboard", "LeaderboardHandle",                  "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("multiboard", "Multiboard", "MultiboardHandle",                     "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("multiboarditem", "MultiboardItem", "MultiboardItemHandle",         "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("trackable", "Trackable", "TrackableHandle",                        "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("dialog", "Dialog", "DialogHandle",                                 "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("button", "Button", "ButtonHandle",                                 "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("fogmodifier", "FogModifier", "FogModifierHandle",                  "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("hashtable", "Hashtable", "HashtableHandle",                        "AgentPointer.memoryType")
    //! runtextmacro PTR_STRUCT("destructable", "Destructable", "DestructableHandle",               "WidgetPointer.memoryType")
    //! runtextmacro PTR_STRUCT("item", "Item", "ItemHandle",                                       "WidgetPointer.memoryType")
    //! runtextmacro PTR_STRUCT("unit", "Unit", "UnitHandle",                                       "WidgetPointer.memoryType")
    
    debug function IsMallocEnabled takes nothing returns boolean
        debug return Memory.enabled
    debug endfunction
    
    debug function DisableMalloc takes nothing returns nothing
        debug set Memory.enabled = false
    debug endfunction
endlibrary
 
Last edited:
I know that we all write (v)Jass for the fun, but it is the first time i've seen a jass resource which has be made only for fun.
You seriously need an other hobby :ogre_hurrhurr:

I won't lie, I mainly wrote it for my video tuts on vjass.

Also, it is in fact extremely useful in SC2 due to static memory limits (I use arrays there). This is really a modified port of my SC2 Malloc.
 
I won't deny it's useful in SC2, i just don't care to check it, but it's wc3 here.
Now, i don't know, does it meet the requirements to be approved ?

Well, you can do the stuff in the regular JASS way (spamming arrays) by using table and you'll even have faster allocation/deallocation speeds and faster read/write speeds ;o.

I'm not sure if it does meet requirements to be approved as I don't know when you'd ever want to use this. However, it is educational if you want to learn more proper ways to code things before moving to c++ ^_^. If you look at the LinkedList struct, the Linked List head is a very different data structure from the nodes. I combine them both into one struct, but you'd normally have 2 structs, one for the node and one for the list. The node and list would be templates of T. In the structs I do, they are completely generic since you just pass in pointers (similar to void* in c++).
 
I really like this, as it actually taught me something, but if I am to approve it, it would be approved as a 'model' script, not a usable vJass resource.

(That is, after it's working and Bribe likes it too)

But you need to put up a disclaimer telling people not to use this in public resources because people who know C/C++ might think this is a /good/ usable resource if they're new to wc3 modding :p
 
Top