Save every type of value in a struct

Executor

I see you
Reaction score
57
Hi,

I need help generating a struct, which is able to store every type in wc3 efficiently (no hashtable). I dislike many ifs.

The following code is my momentarily progress. Theoratically it would work, but when I now want to copy for example one "Data" I have to access the right struct of the type, but I don't know how to connect a structTYPE to an integer. Ask if you need further explanations, cannot really verbalize it.

JASS:
    //! textmacro TypeIndexer takes TYPE
    private struct $TYPE$_Indexer
        $TYPE$ value
        static method newValue takes $TYPE$ t returns integer
            local thistype this = thistype.allocate()
            set .value = t
            return this
        endmethod
    endstruct
    //! endtextmacro
    //! runtextmacro TypeIndexer("integer")
    //! runtextmacro TypeIndexer("real")
    //! runtextmacro TypeIndexer("boolean")
    //! runtextmacro TypeIndexer("string")
    //! runtextmacro TypeIndexer("player")
    //! runtextmacro TypeIndexer("widget")
    //! runtextmacro TypeIndexer("destructable")
    //! runtextmacro TypeIndexer("item")
    //! runtextmacro TypeIndexer("unit")
    //! runtextmacro TypeIndexer("ability")
    //! runtextmacro TypeIndexer("timer")
    //! runtextmacro TypeIndexer("trigger")
    //! runtextmacro TypeIndexer("triggercondition")
    //! runtextmacro TypeIndexer("triggeraction")
    //! runtextmacro TypeIndexer("event")
    //! runtextmacro TypeIndexer("force")
    //! runtextmacro TypeIndexer("group")
    //! runtextmacro TypeIndexer("location")
    //! runtextmacro TypeIndexer("rect")
    //! runtextmacro TypeIndexer("boolexpr")
    //! runtextmacro TypeIndexer("sound")
    //! runtextmacro TypeIndexer("effect")
    //! runtextmacro TypeIndexer("unitpool")
    //! runtextmacro TypeIndexer("itempool")
    //! runtextmacro TypeIndexer("quest")
    //! runtextmacro TypeIndexer("questitem")
    //! runtextmacro TypeIndexer("defeatcondition")
    //! runtextmacro TypeIndexer("timerdialog")
    //! runtextmacro TypeIndexer("leaderboard")
    //! runtextmacro TypeIndexer("multiboard")
    //! runtextmacro TypeIndexer("multiboarditem")
    //! runtextmacro TypeIndexer("trackable")
    //! runtextmacro TypeIndexer("dialog")
    //! runtextmacro TypeIndexer("button")
    //! runtextmacro TypeIndexer("texttag")
    //! runtextmacro TypeIndexer("lightning")
    //! runtextmacro TypeIndexer("image")
    //! runtextmacro TypeIndexer("ubersplat")
    //! runtextmacro TypeIndexer("region")
    //! runtextmacro TypeIndexer("fogstate")
    //! runtextmacro TypeIndexer("fogmodifier")
    //! runtextmacro TypeIndexer("hashtable")
   
    private struct Data
        integer TYPE    
        integer index
        method assignStringValue takes string value returns thistype
            if IsInt(value) then
                set .TYPE = TYPE_INTEGER
                set .index = integer_Indexer.newValue(S2I(value))
            elseif IsReal(value) then
                set .TYPE = TYPE_REAL
                set .index = real_Indexer.newValue(S2R(value))
            elseif (value=="TRUE") or (value=="FALSE") then
                set .TYPE = TYPE_BOOLEAN
                set .index = boolean_Indexer.newValue(S2B(value))
            elseif IsRawcode(value) then
                set .TYPE = TYPE_INTEGER
                set .index = integer_Indexer.newValue(String2Rawcode(SubString(value,1,StringLength(value)-1)))
            else
                set .TYPE = TYPE_STRING
                set .index = string_Indexer.newValue(value)
            endif
            return this
        endmethod
        static method create takes nothing returns thistype
            local thistype this = thistype.allocate()
            return this
        endmethod
    endstruct
 

Azlier

Old World Ghost
Reaction score
461
I don't think it can be done with the current features of vJass, but I think Vex is cooking up something that'll make it possible.
 

Executor

I see you
Reaction score
57
Hm, hopefully, otherwise I'd have to use hashtables and this would just be.. slower :)
Wouldn't ingame coding for debugging purposes be wonderful?:shades:
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I don't know how to connect a structTYPE to an integer
Give them a static key.

Replace your mass "ifs" with StringHash/hashtable use, to attach a method to a string with function interfaces and .evaluate(). :thup:
For each struct, if you like, in onInit, you can store methods in a hashtable using this:
[LJASS]function interface Method takes integer this returns nothing[/LJASS]
See SpellStruct.

Edit: The actual way I did this in SpellStruct was use a function interface to store the create method of each struct, and then an interface which all structs extend, combining modules and struct extention allows this power you seek (but you won't need a module, I expect). ;)
 

quraji

zap
Reaction score
144
This?

http://www.wc3c.net/vexorian/jasshelpermanual.html#interfs

JassHelper Manual said:
It is possible to acquire the type id of an instance of an struct that extends an interface, this type id is an integer number that is unique per struct type that extends that interface.

JASS:
interface A
    integer x
endinterface

struct B extends A
    integer y
endstruct

struct C extends A
    integer y
    integer z
endstruct

function test takes A inst returns nothing
   if (inst.getType()==C.typeid) then
     // We know for sure inst is actually an instance of type C
       set C(inst).z=5 //notice the typecast operator
   endif
   if (inst.getType()==B.typeid) then
       call BJDebugMsg("It was of type B with value "+I2S( B(inst).y  ) )
   endif
endfunction

In short, .getType() is a method that you use on instances of an object whose type extends an interface. And .typeid is an static constant set for struct types that extend an interface.
 

Executor

I see you
Reaction score
57
>I don't know how to connect a structTYPE to an integer
Give them a static key.

Replace your mass "ifs" with StringHash/hashtable use, to attach a method to a string with function interfaces and .evaluate(). :thup:
For each struct, if you like, in onInit, you can store methods in a hashtable using this:
[LJASS]function interface Method takes integer this returns nothing[/LJASS]
See SpellStruct.

Edit: The actual way I did this in SpellStruct was use a function interface to store the create method of each struct, and then an interface which all structs extend, combining modules and struct extention allows this power you seek (but you won't need a module, I expect). ;)

The clue is, I want to get away from hashtable usage :D
My lib already works with hashtables but I hope for a better way with handle array or sth.


@quraji
I know that you can typecast structs, thats the basic of my question. I need somekind of "typecast array", BECAUSE your code will lead to really many ifs when implementing all types. You see my prob?
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Just use static (else)ifs inside the textmacro.
Done.(Or i miss something)
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Nevermind, i hadn't read your method assignStringValue.
I don't see the usefulness of a such thing though.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top