• 🏆 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!

[Lua][vJass] New Table

Level 9
Joined
Jun 21, 2012
Messages
432
When creates a Table via Table struct, NOT have access to the two-dimensional arrays: parentKey and childKey.

TableArray allows us to use this feature but with the requirement that we must assign a size to parentKey.

In hashtable: call SaveInteger(h,myUnlimitedParendkey,childKey,value)

In TableArray: set h[myLimitedParendkey].integer[childKey]=value

myLimitedParendkey is the size assigned when creating a new TableArray.

For me this is a stone in my shoe :ogre_rage:
 
Level 11
Joined
Dec 3, 2011
Messages
366
I dont know why I can't save trigger

JASS:
struct test
    private static Table Data
    
    private static method onInit takes nothing returns nothing
        set Data = Table.create()
        set Data.trigger[1] = CreateTrigger()
        call BJDebugMsg(I2S(GetHandleId(Data.trigger[1]))) // Return true handleID
        set Data[1] = GetHandleId(Data.trigger[1])
        set Data.unit[1] = CreateUnit(Player(0), 'Hpal', 0, 0, 0)
        call BJDebugMsg(I2S(GetHandleId(Data.trigger[1]))) // Return 0
    endmethod
endstruct
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
store it at another index(not 1).

Since table directly compiles into hashtable calls, it has the same limitations that the hashtable does.

You can store at index X these things without overriting: integer, real, string, boolean, handle.

Problem is you can only store 1 handle type inside, so if you store trigger(subtype for handle), if you store unit in it, it will overrite that handle(trigger in this case)
 
Level 11
Joined
Dec 3, 2011
Messages
366
store it at another index(not 1).

Since table directly compiles into hashtable calls, it has the same limitations that the hashtable does.

You can store at index X these things without overriting: integer, real, string, boolean, handle.

Problem is you can only store 1 handle type inside, so if you store trigger(subtype for handle), if you store unit in it, it will overrite that handle(trigger in this case)

Create another Table to store data and problem is fixed :ogre_kawaii:

Anyway thank you &^&
 
Level 5
Joined
Dec 1, 2008
Messages
120
I know, and I added that in my notes in the first post. You can just create a Table within a Table if you need a little more complexity. If you store tables within Tables you could end up with this syntax:

local unit u = table['hfoo']['hpea']

Can someone expand on this a little? How can I achieve this?
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
it wont work out of the box, because JassHelper will think that table['hfoo'] is integer, and you cant apply array subscript operator onto integer, but you can do:

Apparently it works even without casting into Table, funny.

Example:

JASS:
local Table t = Table.create()
set t[0] = Table.create()

set t[0][5] = 5

and this will work(I tried compiling it, because of the ])[ series in there, but JassHelper has no problem with that apparently
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
Should I add this to the Table library? It simplifies the need someone may have for indexing with large parent and child keys. I thought of this after seeing some recent posts. It is mostly a wrapper, but creates a Table as needed when indexing to guarantee the same utility as you'd find in a regular hashtable (though it lacks the FlushParent function - that would prove too much to replicate). The user must flush all child tables prior to destroying the HashTable.

JASS:
struct HashTable extends array

    method operator [] takes integer index returns Table
        local Table t = Table(this)[index]
        if t == 0 then
            set t = Table.create()
        endif
        return t
    endmethod

    method remove takes integer index returns nothing
        local Table t = Table(this)[index]
        if t != 0 then
            call t.destroy()
            call Table(this).remove(index)
        endif
    endmethod
    
    method destroy takes nothing returns nothing
        call Table(this).destroy()
    endmethod
    
    static method create takes nothing returns thistype
        return Table.create()
    endmethod

endstruct

example:

JASS:
local HashTable hash = HashTable.create()
set hash['hfoo'][StringHash("poop")] = 66
call hash.remove('hfoo')
call hash.destroy()
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
OK everybody who has implemented version 4.0, please update to version 4.1. I made an error due to how rusty I am. The version fixes the HashTable's method operator [] as previously it was creating a new Table every time.

I have also added a "method has takes integer index returns boolean" due to a PM I've received from one of our users who needed it if he were to use HashTable for his resource, so this is technically more than just a hotfix.
 
Level 11
Joined
Dec 3, 2011
Messages
366
OK everybody who has implemented version 4.0, please update to version 4.1. I made an error due to how rusty I am. The version fixes the HashTable's method operator [] as previously it was creating a new Table every time.

I have also added a "method has takes integer index returns boolean" due to a PM I've received from one of our users who needed it if he were to use HashTable for his resource, so this is technically more than just a hotfix.

Yep :)) You've just save my systems :ogre_icwydt:
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
What what! Have I just updated the TableBC library to restore Vexorian's static methods [] and flush2D? Yes I have!! Now converting those old resources only requires changing .flush(integer) to .remove(integer) and that's that!

No change to Table required - just re-copy the TableBC lib and you're set!
 
Level 11
Joined
Dec 3, 2011
Messages
366
What what! Have I just updated the TableBC library to restore Vexorian's static methods [] and flush2D? Yes I have!! Now converting those old resources only requires changing .flush(integer) to .remove(integer) and that's that!

No change to Table required - just re-copy the TableBC lib and you're set!

Hmmm :( I hope you test my map which I sent you. I can't find the problem :ogre_icwydt:
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
What what! Have I just updated the TableBC library to restore Vexorian's static methods [] and flush2D? Yes I have!! Now converting those old resources only requires changing .flush(integer) to .remove(integer) and that's that!

No change to Table required - just re-copy the TableBC lib and you're set!

I think this needs more attention! I don't even bother flushing anyway, so it's basically just "fixed".
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Hello, mr Bribe. I wonder how to remove saved real (or any other types) from a Table? As far as I see it only allows me to remove integer.
JASS:
    //call tb.remove(294080)
    method remove takes integer key returns nothing
        call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
    endmethod

I tried this (following your documentation):
JASS:
call Ht.real.remove
It compiles fine but does that work to remove saved real in the Table?
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Execute the following: call table.$TYPE$.remove(key).

You can check out my Vector<T> and List<T> for various Table manipulation in order to extend it's functionality.

From Table's source:
JASS:
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
// (...)
    method remove takes integer key returns nothing
        call RemoveSaved$SUPER$(ht, this, key)
    endmethod
// (...)
//! endtextmacro

//! textmacro NEW_ARRAY takes FUNC, TYPE
// (...)
    method remove takes integer key returns nothing
        call RemoveSavedHandle(ht, this, key)
    endmethod
// (...)
//! endtextmacro
As you can see, everything is there.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
This doesn't suffer any collisions. HashTables are just as powerful as normal hashtables, but avoid the 256 limit and run twice as slowly unless you cache the parent key's Table for repeated uses.

You didn't really answer to my question, when should i use an Hashtable, a Table and a TableArray ?

Not sure if the link you sent me was correct as I didn't see any mention of Tables.

It is correct, check the second library. (requires Wait, which requires Table)
However i had forgotten the requires.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Sorry but i'm still confused, it seems i can use the 3 for the same thing, just with a different syntax, at least for my example.
Ofc i could check your code, but it's a total mess (no offense) with all these textmacros and sugar vJass syntax.

So would you be kind enough to check my code and say what's the best option please ?
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
Sorry but i'm still confused, it seems i can use the 3 for the same thing, just with a different syntax, at least for my example.
Ofc i could check your code, but it's a total mess (no offense) with all these textmacros and sugar vJass syntax.

So would you be kind enough to check my code and say what's the best option please ?

Table is just the child key, TableArray is an allocated arrays of Tables, tho the parent key is limited. Meanwhile, HashTable exceeds the limit of TableArray (Based on what Bribe explained)
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Because Table has this operator that returns Table.
JASS:
method operator [] takes integer key returns Table
Not just 2d, you can even do any dimension with that operator. But that is really not the purpose of the operator.
Until now, I think that operator is just the sort term of saving integer, instead of Table.integer[index] = 0, you can do Table[index] = 0 instead. But why it returns Table? That's still a mystery : P

HashTable, as Bribe said, is the same as TableArray just with bigger parent key size. So it's normal if you can do 2d with that thing.
 
Level 4
Joined
Jun 19, 2010
Messages
49
Already searched a lot to find an example of how to store tables into tables. here are 2 links where Bribe himself says, that it is supported, but as always (till yet), I found no example:
"... you can manually store nested Tables and get syntax like table[value1][value2][value3][value4][value5]"
post #20: http://beta.roflmania.com/threads/multidimension.276330/
"Something like set pt[this][10]['A']['G'].unit[1] = GetTriggerUnit() is now supported (obviously the example is an exaggeration)."
post #11: http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/

to be more specific, given following example, how would I apply it?
JASS:
// i need a 4D-array like this:
	// [ELEMENT][TIER][TOWER][LEVEL]=ABILITY RAWCODE
	// [    1-8][ 1-6][  1-4][  0-8]
	
	// MAX STORAGE SIZE OF Bribe's Table = 2 ^ 31 - 1
	// HOW IT WORKS:
	// all stored data from created & used table is shared among 1 hashtable from library table, hence the size 2 ^ 31 - 1
	// "You can have up to 2 ^ 31 - 1 Table instances."
	// [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
	// "As for the length, I think it just follows the normal limit.
	//  Wc3 integers are 32-bit signed integers with a limit of 2147483647 (2^31 - 1)."
	// [url]http://www.wc3c.net/showthread.php?t=110243[/url]
	
// init global variables:
globals
	private Table gTab_element
	private Table gTab_tier
	private Table gTab_tower
	private Table gTab_level
endglobals
	
// create tables later in a function:
	set gTab_element = Table.create()
	set gTab_tier = Table.create()
	set gTab_tower = Table.create()
	set gTab_level = Table.create()
	
// and now what?
	set gTab_element[1]=gTab_tier[1]=gTab_tower[1]=gTab_level[0] = 'SAA0'
???

edit:
wait, or is it simple like that?
JASS:
library tableMultiD initializer Init requires Table

// init global variable:
globals
	private Table gTab_multiD
endglobals

private function Init takes nothing returns nothing
// create table:
	set gTab_multiD = Table.create()

// store data:
	set gTab_multiD[1][1][1][0]='SAA0'
	set gTab_multiD[1][1][1][1]='SAA1'
	set gTab_multiD[1][1][1][2]='SAA2'
	//...
endfunction

endlibrary

edit 2:
after some more reading in 'Jasshelper' & trying to understand Bribe's script & hiveworkshop-chat with 'Almia' & 'Wietlol', I guess this isn't achievable as easy as I thought. my current imagination of how it could work, is to write 4 structs with operator overloading nested to every previous struct. but that seems quite too challenging for me...
 
Last edited:

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
I know about the operator, what i mean is that it seems redundant.
It's funny how my question is simple and straight to the point but not are the answers.

You were not straight to the point. Your questions (and your discussions) made me think that you don't understand why you can do TableArray syntax with Table. If you were going straight to the point, you better say that operator is a redundant from the first place, which I agree.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Well, read again my first questions then.
Ok i give up until i have a clear answer.

Your question, in short, was about difference of Table, TableArray, and HashTable. How is it supposed to be related to what you have just stated about redundant operator? Maybe I'm too stupid to understand.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, i don't want to begin a fight or anything like that.
For me it was clear, but maybe it wasn't for you, ok.
This one at least : http://www.hiveworkshop.com/forums/2823264-post288.html

Now, i will wait for Bribe or anyone else that can explain when and why you will use HashTable, Table or TableArray.
Anyway i'm quite sure i'm not the only one which is wondering that.
The Bribe's example of usage in the very first post of this thread doesn't make it clear imho.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Maybe I can help. You can use Table if you only need one dimension variable. But judging from your code, you are using 2 dimension. So you should use TableArray instead because using Table will not work (it compiles but should not work correctly). I still don't understand as well in what case I should use HashTable, neither ever used it.

I use Table quite a lot so I know some things. But if you still want to hear the answer directly from the creator, it's fine then : P
 
Top