Indexing.. again..

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 41
Joined
Jun 9, 2011
Messages
13,289
So basically I came up with a simple way to keep track on struct instances and how to update them.

Not quite sure if it would be acceptable in the spell section though. Opinions?
JASS:
//! zinc
	library TEST{
		struct X{
			static integer instances = -1;
			
			method onDestroy(){
				instances -= 1;
			}
			
			method doStuff(){
				BJDebugMsg(I2S(this) + ": " + I2S(GetRandomInt(1,10)));
			}
			
			static method Update(){
				integer i = instances;
				while(i >= 0){
					thistype(i).doStuff();
					i -= 1;
				}
			}
			
			static method create() -> thistype{
				thistype this = thistype.allocate();
				instances += 1;
				return this;
			}
			
			static method onInit(){
				TimerStart(CreateTimer(), 0.75, true, function thistype.Update);
			}
		}
		
		function onInit(){
			X.create();
			X.create();
			X.create();
		}
	}
//! endzinc
 
No, it's not a perfect way.

The first problem is that structs start from one and not from zero.

The second problem is that a gap can occur which might cause problems:

Imagine we have 4 allocated instances. Loop will look like:

1
2
3
4 (MAX)

now we destroy the 3rd instance, and now it looks like:

1
2
_ (MAX)
4

It will try to read the 3rd element, and will ignore the 4th.
So gap has to be filled, for example with dynamic indexing:

JASS:
static thistype array List
static integer Max = -1

static method create
    local thistype this = thistype.allocate()
    Max++
    List[Max] = this

static method deindex takes integer i
    List[i].deallocate()
    List[i] = List[Max]
    Max--

static method onPeriod
    local integer i = Max
    local thistype this
    loop
        set this = List[i]
        exitwhen(i < 0)
            // Do stuff
            if (condition) then
                thistype.deindex(i)
        i--

Note that "deindex" method is static, because we need to know the position in list.

Alternativly one can use a doubly linked list with elemens prev and next, but I think already know about this.
 
Last edited:
That won't work.

Edit: IcemanBo already explained in more detail why not.
The double linked list is the best approach.
 
So basically Structs do not handle its own stuff properly. Never trust vjass -.-

I can solve that by checking if i != 0 though.
JASS:
				while(i >= 0){
					if(i != 0)
					{
						thistype(i).doStuff();
					}
					i -= 1;
				}

edit: Or so I thought, my tests show otherwise.

edit: I will just go with Iceman's solution in lack of better.
 
Last edited:
So basically Structs do not handle its own stuff properly. Never trust vjass -.-
Just because they don't work like you expected them too doesn't mean they don't work correctly. It's just your expectations that were incorrect.

I am still fairly happy as long as I don't have to use the .next and .prev
Why would you not want to use the best solution?
 
That's true, however:
- you need to declare the same number of arrays anyway (next + prev vs static array + instance index), so it's not really a "simpler" solution (unless you can only remove instances from inside the loop, in which case you can skip the instance index)
- a linked list preserves the order of instances which may be important in some, admittedly rare cases

But okay, I agree, a linear stack is fine too. I just find it odd that someone can understand a linear stack but can't figure out a linked list which is just as simple.
 
Status
Not open for further replies.
Back
Top