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

[vJASS] linked list

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
this turned out to be a ask things as they pop up thread so the most recent problem is located down at the comments and not here anymore.

I want to use the following: http://www.wc3c.net/showthread.php?t=103604

But I have issues figuring out how it works..

JASS:
function test takes nothing returns nothing
	local List l =  List.create()
	set somelist = l
	
	call Link.create(l, 10)
	call Link.create(l, 27)
	call Link.create(l, 65)

	call BJDebugMsg(I2S(l.first))
	call BJDebugMsg(I2S(l.first.next))
	call BJDebugMsg(I2S(l.first.next.next))
endfunction

this prints 3,2,1 while I was expecting it to type 10,27,65 or 65,27,10
 
Last edited:
Level 23
Joined
Apr 16, 2012
Messages
4,041
static method create takes List l, integer data returns Link what you do is you create link, which stores the data.

first is the head, and next points to the next INSTANCE, but you attached data to it. This basically prints the instance that is linked after "first"
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
543
I want to use the following: http://www.wc3c.net/showthread.php?t=103604

But I have issues figuring out how it works..

JASS:
function test takes nothing returns nothing
	local List l =  List.create()
	set somelist = l
	
	call Link.create(l, 10)
	call Link.create(l, 27)
	call Link.create(l, 65)

	call BJDebugMsg(I2S(l.first))
	call BJDebugMsg(I2S(l.first.next))
	call BJDebugMsg(I2S(l.first.next.next))
endfunction

this prints 3,2,1 while I was expecting it to type 10,27,65 or 65,27,10

That's a problem with vJass as structs are being represented by integers and i wont issue a warning when you use them as integers.

However, the .data field is what you're looking for:
JASS:
call BJDebugMsg(I2S(l.first.data))
call BJDebugMsg(I2S(l.first.next.data))
call BJDebugMsg(I2S(l.first.next.next.data))
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
543
Thanks a lot LeP. It seems to only support integers which is rather odd..

What if I want to store, locations, units or something like that?

Well most of the time you don't want to store a single thing, but a collection of things; that is structs. And as seen above you can use structs as integers so it perfectly makes sense to only allow integers.

I agree that it isn't the nicest design but it works bretty good 99% of the time (in vJass) and when you actually only want to store a single thing you can always wrap your location inside some struct. or any other way to associate your location with an integer.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
I see, I will need to work with structs then. Shouldn't be a big deal.

Jeez the issues is raining over me.. now jasshelper screams when I try to declare a List.. (both of them throws errors at me)

"undeclared function sc__List.create()"

JASS:
struct x
	static List l = List.create()
endstruct

globals
	List xx = List.create()
endglobals

edit: it works fine if I use a local varaible, but then I can't use it later on..
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
You cannot do it in a globals block because globals are pushed to the top when it compiles to raw jass and from there, it won't see the function.

You can write

JASS:
struct x
    static List l

    static method onInit takes nothing returns nothing
        set l = List.create()
    endmethod
endstruct

respectively

JASS:
globals
    List xx
endglobals

function someInitFuncYouCallYourself takes nothing returns nothing
    set xx = List.create()
endfunction

@types: As you have noticed, you can only store integers. In other programming languages, collections like List would normally be generic and you would specify the type of elements they can store. But vJass does not have them and is not very type-safe. It implicitly casts all the struct types to integer.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
Sweet, I feel like I am getting somewhere now..

I am grateful for all the fast replies, guys. Rep party incoming soon :p

and.. yay.. more problems..

JASS:
		call Link.create(l,this)
		set l.first.data.loc = GetRectCenter(GetPlayableMapRect())

this should technically work since 'this' is an integer. But well, it doesn't.

@muzzel
I know.. it's so much easier in c# it's basically a dynamic array, it's super simple.. Unlike linked lists :-/
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
543
Sweet, I feel like I am getting somewhere now..

I am grateful for all the fast replies, guys. Rep party incoming soon :p

and.. yay.. more problems..

JASS:
		call Link.create(l,this)
		set l.first.data.loc = GetRectCenter(GetPlayableMapRect())

this should technically work since 'this' is an integer. But well, it doesn't.

@muzzel
I know.. it's so much easier in c# it's basically a dynamic array, it's super simple.. Unlike linked lists :-/

l.first.data is just some integer, vjass does not know what struct it is (i might not be a struct at all, you know).
You can cast an integer back to some struct: set yourstruct(l.first.data).loc = ...
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,219
no difference. It still throws the error. "l is not of a type that allows . syntax."
JASS:
struct testStruct
	public static List l = List.create()
	static method create takes nothing returns thistype
		local thistype this = thistype.allocate()
		return this
	endmethod
endstruct

function test takes nothing returns nothing
	call BJDebugMsg(I2S(testScruct.l.first))
endfunction
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
typo testScruct -> testStruct

You do not need to flag it public, that's the default option for structs. And we said it before, that you should not write the initialization of struct variables != null in the variable declaration because it will be pushed to the top in the compiled script, wherefrom it cannot call your constructor.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
you can change the code to this:

JASS:
struct testStruct
    public static List l = 0
    static method create takes nothing returns thistype
        return thistype.allocate()
    endmethod

    private static method onInit takes nothing returns nothing
        set l = List.create()
    endmethod
endstruct

This will initialize the List
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Or don't try using libraries that aren't made to be used properly. A simple List is easy to make just think about what you need it to do. Don't use these all-purpose all-efficient every-situation bullshit approaches because usually they're just a pain in the ass to read/use and don't actually give you any benefit.

JASS:
struct ListNode
		private integer data
		private ListNode next
		private ListNode prev
		
		public static method create takes integer data, ListNode next, ListNode prev returns ListNode
				local ListNode N = allocate()
				set N.data = data
				set N.next = next
				set N.prev = prev
				return N
		endmethod
endstruct

struct List
		private ListNode head
		private ListNode tail
		
		public static method create takes nothing returns List
				local List L = allocate()
				set L.head = 0
				set L.tail = 0
				return L
		endmethod
		
		//Do not reveal the internal structures of the List... that is how
		//you get users that are breaking their List structures.
		method append takes integer data returns boolean
				local ListNode N
				if (this.head == 0) then
						set this.head = ListNode.create(data, 0, 0)
						set this.tail = this.head
				else
						set N = ListNode.create(data, 0, this.tail)
						set this.tail.next = N
						set this.tail = N
				endif
		endmethod
		
		method onDestroy takes nothing returns nothing
				local ListNode N = this.head
				local ListNode D
				loop
						exitwhen (N == 0)
						set D = N
						set N = N.next
						call D.destroy()
				endloop
		endmethod
endstruct

I just made this in like 10 seconds.

You should just make these things yourself as needed. People have such vastly different needs for their maps and sites like wc3c just monopolized libraries like this so there was only 1 option. It was good for standardizing things but ultimately nobody needed standardized code, like, ever.
 
Well, there's also my set of libraries for collections. I've coded every single variation of the most common collections, so it has everything you'll ever want if you care about behaviors ^)^.

Here is List

https://github.com/nestharus/JASS/blob/master/jass/Data Structures/List/script.j

And an example for your benefit

JASS:
struct MyList extends array
    implement List

    readonly integer data //store some data
endstruct

struct UseList extends array
    private static method onInit takes nothing returns nothing
        local MyList list = MyList.create()
        local thistype node

        /*
        *    populate
        */
        set list.enqueue().data = 1
        set list.enqueue().data = 2
        set list.enqueue().data = 3
        set list.enqueue().data = 4
        set list.enqueue().data = 5

        /*
        *    loop
        */
        set node = list.first
        loop
            exitwhen node == MyList.sentinel

            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60000, I2S(node.data))

            set node = node.next
        endloop

        /*
        *    pop
        */
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60000, I2S(list.first.data))
        call list.pop()
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60000, I2S(list.first.data))

        /*
        *    destroy
        */
        call list.destroy()
    endmethod
endstruct
It includes nice error messages, in-depth error checking, memory analysis tools (check for leaks?), and so on. That is of course one variant, the standard lib.

Standard: Use a separate allocator for lists and nodes

Shared: Use the same allocator for both lists and nodes (better error checking, but smaller memory limit)

Unique: Add your own nodes (does not create nodes for you)

Nx: Add nodes to your own list (does not create lists for you)

Circular: faster add/remove, slower iteration


The entire index includes binary heaps, trees, lists, queues, stacks, arrays, catalogs, and matrices. A bit more than wurst ; )

https://github.com/nestharus/JASS/tree/master/jass/Data Structures

Most collections were tested using a rigorous test suite.

Some of the collections also have Table variants if 8192 isn't enough (denoted by a T at the end).
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
You'll learn more, acquire a deeper understanding of (v)JASS, and therefore master the scripting language quicker if you try to write your own stuff. It will be really low level at first, but once you are comfortable, you will be able to write high level code.

Start by learning how to use a simple JASS array, and then make a wrapper around it to do a simple List structure with methods like append/add, getSize, and remove. Though a linked list is probably less overhead than a real List (when I say real list I mean a Python list).

Keep in mind when you are working with structs, they are actually just integers representing indices in parallel arrays. So if you set some pre-conditions, you can have very generic data structures which can store any struct. The trick is the client needs to know which struct to cast them back into.

This is the best advice I think:

Berb said:
You should just make these things yourself as needed. People have such vastly different needs for their maps and sites like wc3c just monopolized libraries like this so there was only 1 option. It was good for standardizing things but ultimately nobody needed standardized code, like, ever.

When you're experienced and don't want to worry about implementing all your own data structure, or if you need extreme performance, then use the high quality resources, like Nestharus' (though probably the best option for performance is just to use low level JASS). But don't use them until you really can write your own stuff, since you'll be denying yourself a very important learning experience.
 
Status
Not open for further replies.
Top