1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  7. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  8. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[vJASS] [WIP] Check my system

Discussion in 'Triggers & Scripts' started by Krogoth, Oct 7, 2012.

  1. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    My System. :p

    Import:
    WorldBounds

    Native Extension:
    Code (vJASS):
    //=======================
    //=== NativeExtension ===
    //======= v0.1000 =======
    // Makes some code shorter.

    library NativeExtension
        globals
            constant integer MAX_PLAYER_INDEX = 15
        endglobals

        function GroupEnumUnits takes group whichGroup, boolexpr filter returns nothing
            local integer i = 0
            local player p
            loop
                set p = Player(i)
                call GroupEnumUnitsOfPlayer(whichGroup, p, filter)
                exitwhen i == MAX_PLAYER_INDEX
                set i = i + 1
            endloop
        endfunction
    endlibrary

    In-struct Arrays:
    Code (vJASS):
    //======================
    //=== InstructArrays ===
    //======= v0.900 =======
    // Provides declaring arrays inside structs to exploit dot syntax.
    // There is a max size declaration for arrays of this sort.

    library InstructArrays
        globals
            private constant integer MAX_INDEX = 1023
        endglobals

        //! textmacro CREATE_INSTRUCTARRAY_TYPE takes TYPE
        type $TYPE$Array extends $TYPE$ array[MAX_INDEX]
        //! endtextmacro

        //=== Create all needed in-struct array types ===
        //Sample:
        // runtextmacro CREATE_INSTRUCTARRAY_TYPE("<TYPE>")
        //Execution:
        //!runtextmacro CREATE_INSTRUCTARRAY_TYPE("boolean")
        //!runtextmacro CREATE_INSTRUCTARRAY_TYPE("integer")
        //!runtextmacro CREATE_INSTRUCTARRAY_TYPE("real")
        //!runtextmacro CREATE_INSTRUCTARRAY_TYPE("unit")

        //Use "<TYPE>Array" to declare in-struct array of <TYPE>.
    endlibrary

    Error Stater:
    Code (vJASS):
    //===================
    //=== ErrorStater ===
    //===== v0.1001 =====
    // Checks errors and informs about them.

    library ErrorStater

    //=== Settings ===
    globals
        private constant INFORM = true
    endglobals
    //================

        globals
            private constant string ARRAY_OUTINDEX_ERROR = "Array out index error."
            private constant string ARRAY_RAWINDEX_ERROR = "Array raw index error."
        endglobals

        function CheckArrayIndexError takes integer index, integer max_index, integer current_size returns boolean
            if index > max_index or index < 0 then
                if INFORM then
                    call BJDebugMsg(ARRAY_OUTINDEX_ERROR)
                endif
                return true
            endif
            if index >= current_size then
                if INFORM then
                    call BJDebugMsg(ARRAY_RAWINDEX_ERROR)
                endif
                return true
            endif
            return false
        endfunction
        //Operator [] uses it usually to not address with impossible index or index with no value.

        function CheckArrayOutIndexError takes integer index, integer max_index returns boolean
            if index > max_index or index < 0 then
                if INFORM then
                    call BJDebugMsg(ARRAY_OUTINDEX_ERROR)
                endif
                return true
            endif
            return false
        endfunction
        //Operator []= uses it usually to not address with impossible index.
    endlibrary

    Indexed Data:
    Code (vJASS):
    //===================
    //=== IndexedData ===
    //===== v0.9003 =====
    // Provides incapsulated data arrays of any allowed type.
    // This type of data called indexed data type.
    // Indexed data type can be specified to indexed object type with registrar
    // to perform a list of objects and tools for manipulation them.
    // Marker can be included to indexed object type for quick conversions
    // object <-> index. Marker functions (<SETMARK_FUNC>, <GETMARK_FUNC>)
    // cannot be changed dynamic, they all are determined upon compilation.

    //Interface:
    //| method operator[] takes integer index returns <TYPE>
    //| method operator[]= takes integer index returns nothing
    //| readonly integer size
    //+ registrar:
    //| method register takes <TYPE> object returns nothing
    //| method free takes integer index returns nothing
    //| method unregister takes <TYPE> object returns nothing
    //+ marker:
    //  static constant boolean setMark
    //  static constant boolean getMark

    library IndexedData uses InstructArrays, optional ErrorStater
        globals
            private constant INSTANCES_LIMIT = 10000
            private constant NULL_INDEX = -1
        endglobals

        //! textmacro CREATE_INDEXEDDATA_TYPE takes NAME, TYPE, NULL_VALUE, OBJECTS, SETMARK_FUNC, GETMARK_FUNC
        struct $NAME$[INSTANCES_LIMIT]
            private $TYPE$Array data
            //In-struct array format is used above
            readonly integer size = 0

            //=== Get data by index ===
            method operator[] takes integer index returns $TYPE$
                //Check an error
                static if LIBRARY_ErrorStater then
                    if CheckArrayIndexError(index, ARRAY_MAX_INDEX, size) then
                        return $NULL_VALUE$
                    endif
                endif
                return data[index]
            endmethod

            //=== Set data by index ===
            method operator[]= takes integer index, $TYPE$ data returns nothing
                //Check an error
                static if LIBRARY_ErrorStater then
                    if CheckArrayOutIndexError(index, ARRAY_MAX_INDEX) then
                        return
                    endif
                endif
                //Set data
                set this.data[index] = data
                //Apply new size
                if index >= size then
                    set size = index + 1
                endif
            endmethod
     
        static if $OBJECTS$ then
            static constant boolean setMark = $SETMARK_FUNC$ != "null"
            static constant boolean getMark = $GETMARK_FUNC$ != "null"
            private integerArray freeIndex
            private integer freeIndex_count = 0
            //Check below is used at register
            readonly boolean check = false
            method checkOn takes nothing returns nothing
                set check = true
            endmethod
            method checkOff takes nothing returns nothing
                set check = false
            endmethod
           
            //=== Get index of object by handle ===
            //Object is supposed as unique in register.
            method getIndexOf takes $TYPE$ object returns integer
                local integer index
                static if getMark then
                    //Get index by mark
                    set index = $GETMARK_FUNC$(object)
                    if this[index] == object then
                        return index
                    endif
                else
                    //Seek through array for identity
                    set index = 0
                    loop
                        exitwhen index == size
                        if data[index] == object then
                            return index
                        set index = index + 1
                    endloop
                endif
                return NULL_INDEX
            endmethod

            //=== Register object by handle ===
            method register takes $TYPE$ object returns nothing
                local integer index
                //Check if there is no this object already in register
                if check then
                    static if getMark then
                        //Get index supposed to accord with object by mark
                        set index = $GETMARK_FUNC$(object)
                        if this[index] == object then
                            return
                        endif
                    else
                        //Seek through array for identity
                        set index = 0
                        loop
                            exitwhen index == size
                            if data[index] == object then
                                return
                            set index = index + 1
                        endloop
                endif
                //Prepare index
                if freeIndex_count > 0 then
                    set index = freeIndex[freeIndex_count - 1]
                    set freeIndex_count = freeIndex_count - 1
                    //Bind object to index ...
                    set data[index] = object
                else
                    set index = size
                    //Bind object to index ... *
                    set this[index] = object
                endif
                //... and mark it if set mark function is set
                if setMark then
                    call $SETMARK_FUNC$(object, index)
                endif
            endmethod
               
            //=== Unregister object by index ===
            method free takes integer index returns nothing
                //Check an error
                static if LIBRARY_ErrorStater then
                    if CheckArrayIndexError(index, ARRAY_MAX_INDEX, size) then
                        return
                    endif
                endif
                //Free index
                if this[index] != $NULL_VALUE$ then
                    set data[index] = $NULL_VALUE$
                    set freeIndex[freeIndex_count] = index
                    set freeIndex_count = freeIndex_count + 1
                endif
            endmethod
               
            //=== Unregister object by handle ===
            method unregister takes $TYPE$ object returns nothing
                call free(getIndexOf(object))
            endmethod

            //~ Destructor
            method destroy takes nothing returns nothing
                call data.destroy()
                call freeIndex.destroy(
            endmethod
        else
            //~ Destructor
            method destroy takes nothing returns nothing
                call data.destroy()
            endmethod
        endif

        endstruct
        //! endtextmacro
           
        //=== Create all needed indexedData types ===
        //Sample:
        //  runtextmacro CREATE_INDEXEDDATA_TYPE("<NAME>", "<TYPE>", "<NULL_VALUE>", "<OBJECTS>", "<SETMARK_FUNC>", "<GETMARK_FUNC>")
        //Execution:
        //! runtextmacro CREATE_INDEXEDDATA_TYPE("indexedUnit", "unit", "null", "true", "SetUnitUserData", "GetUnitUserData")
        //! runtextmacro CREATE_INDEXEDDATA_TYPE("indexedBoolean", "boolean", "false", "false", "null", "null")
        //! runtextmacro CREATE_INDEXEDDATA_TYPE("indexedInteger", "integer", "0", "false", "false", "null", "null")
        //! runtextmacro CREATE_INDEXEDDATA_TYPE("indexedReal", "real", "0.", "false", "false", "null", "null")
    endlibrary

    very Simple Unit Indexer:
    Code (vJASS):
    //=============================
    //=== verySimpleUnitIndexer ===
    //========== v0.1000 ==========

    library vSUI initializer Init uses IndexedData, NativeExtension, WorldBounds

    //=== Settings ===
    globals
        private constant boolean INSTANT_INIT = true
        private constant boolean REGISTER_START_UNITS = true
    endglobals
    //================

        globals
            indexedUnit Unit
        endglobals

        struct vSUI
            private static boolean enabled = false
            private static trigger t

            //=== Register filtered unit ===
            private static method registerFilter takes nothing returns boolean
                call Unit.register(GetFilterUnit())
                return false
            endmethod

            //=== Register all units present at this moment ===
            static method registerPresent takes nothing returns nothing
                local group g = CreateGroup()
                call GroupEnumUnits(g, Condition(function registerFilter))
                call DestroyGroup(g)
                set g = null
            endmethod

            static method turnOn takes nothing returns nothing
                if not enabled then
                    call EnableTrigger(t)
                    set enabled = true
                endif
            endmethod

            static method turnOff takes nothing returns nothing
                if enabled then
                    set enabled = false
                    call DisableTrigger(t)
                endif
            endmethod

            //=== Register start units and turn on dynamic register ===
            static method start takes nothing returns nothing
                static if not INSTANT_INIT then
                    set Unit = Unit.create()
                    set vSUI.t = CreateTrigger()
                endif
                static if REGISTER_START_UNITS then
                    call registerPresent()
                endif
                call TriggerRegisterEnterRegion(t, WorldBounds.worldRegion, Condition(function registerFilter))
                set enabled = true
            endmethod
        endstruct

        function Init takes nothing returns nothing
            //Create all needed dynamic variables if vSUI init is set instant
            static if INSTANT_INIT then
                set Unit = Unit.create()
                set vSUI.t = CreateTrigger()
            endif
        endfunction
    endlibrary

    Game:
    Code (vJASS):
    //============
    //=== Game ===
    //============

    library Game initializer Init uses vSUI
        globals
        endglobals

        function GameOn takes nothing returns nothing
            call DestroyTimer(GetExpiredTimer())
            call vSUI.start()
        endfunction

        function Init takes nothing returns nothing
            call TimerStart(CreateTimer(), 0, false, function GameOn)
        endfunction
    endlibrary
     
    Last edited: Oct 17, 2012
  2. Arhowk

    Arhowk

    Joined:
    Aug 8, 2007
    Messages:
    2,753
    Resources:
    0
    Resources:
    0
    First of all, whats it supposed to do? :\
     
  3. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    IncData -> Object Indexer (units, trees, lightnings, spells,...) -> Unit Auto Indexer -> Damage Controller.
     
  4. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    from the looks of it you are indexing the so called objects manually and the purpose is to put it inside an array variable?, hmmm, UnitIndexer already has that...
     
  5. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    Cannot update code now, but... I'll try to explain. (Some terms changed)
    There are (some of in theory yet (just have no PC, that's a problem)):
    - indexed data. It can be associated with indexed data with registrar to perform a data table like hashtable. Has readonly parameter size for separated loop. (Sometimes we don't need go through all units' indexes. For example, in Dota first units (buildings) are very special)
    - indexed data with registrar. There is a bool in textmacro to include registrar. Adds register, unregister, free (same unregister but takes index) functions doing the same UnitIndexer does and 2 marker function variables: to set mark (SetUnitUserData as we got used) and to get mark (GetUnitUserData as we got used); just call setMarkerSetMarkFunction. Can work without any marker function (ofc not effective then). So, it's versatile enough.
    - [WIP] unit auto indexer. It has 2 function variables for register and unregister to bind it to indexed unit data. So, indexed unit data and unit auto indexer are 2 stand-alone objects as it should be.

    edit
    Code (vJASS):
    library GameOn initializer Init uses ObjectIndexer, UnitAutoIndexer
        globals
            indexedUnit Unit
            indexedUnit Dummy
            unitAutoIndexer UnitAutoIndexer
        endglobals

        function Init takes nothing returns nothing
            set Unit = indexedUnit.create()
            call Unit.setMarkerSetMarkFunc(function SetUnitUserData)
            call Unit.setMarkerGetMarkFunc(function GetUnitUserData)
            set Dummy = indexedUnit.create()
            call Dummy.setMarkerSetMarkFunc(function SetUnitUserData)
            call Dummy.setMarkerGetMarkFunc(function GetUnitUserData)
            set UnitAutoIndexer = unitAutoIndexer.create()
            call UnitAutoIndexer.setRegisterFunc(function Unit.register)
            call UnitAutoIndexer.setUnregisterFunc(function Unit.unregister)
            call UnitAutoIndexer.registerPresent()
            call UnitAutoIndexer.turnOn()
        endfunction
    endlibrary
    Should it work?
     
    Last edited: Oct 9, 2012
  6. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    code type is so bad and useless.........
    I had to eat my plan. :/
    Updated.

    edit
    Code (vJASS):
            method onDestroy takes nothing returns nothing
                //Destroy array upon death
                call data.destroy()
            endmethod
    Is it needed?
     
  7. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    So is this manual indexing? Meaning, do you register the indexing yourself by calling a function to index a unit/tree/whatever?

    Or is this auto indexing? Meaning, does the system automatically index objects?

    I understand the system a bit, but some of the stuff seems a bit unnecessary. If I know whether this is meant to be manual or auto indexing, I'll be able to help you improve the system. :)
     
  8. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    Indexing a unit is pretty much useful, but Idk whats the use of indexing others things such as boolean, reals, integers doesnt ring a bell to me...

    btw you should remove the onDestroy and call destroy instead...
     
  9. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    o_O
    Where?

    Actually question is does struct destroy its arrays upon its destroying or I should do it manually at its onDestroy?

    edit
    I have divided it to:
    1) not needed to read,
    2) read,
    3) not needed to read again.
     
  10. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    AFAIK, onDestroy is slow coz:
    onDestroy >>> destroy >>> deallocate

    while:
    destroy >>> deallocate

    so remove the onDestroy and just
    call.destroy()
    when you want to deallocate instance...
     
  11. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    Ok, thanks !
    What about array? Should I destroy it manually?
     
  12. Krogoth

    Krogoth

    Joined:
    Apr 5, 2011
    Messages:
    247
    Resources:
    0
    Resources:
    0
    Updated.
    Not much coz I still have no PC but I have questions already. In vSUI I have a trigger that registers entered units. Will it work absolutely correct if I use RegisterLeaveRegion to unregister units? No leaks then?