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

Indexing.. again..

Status
Not open for further replies.

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
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:
Level 7
Joined
Oct 19, 2015
Messages
286
That won't work.

Edit: IcemanBo already explained in more detail why not.
The double linked list is the best approach.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
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:
Level 7
Joined
Oct 19, 2015
Messages
286
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?
 
Level 7
Joined
Oct 19, 2015
Messages
286
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.
Top