Author Topic: Enumeration and altering of lists while in a loop - GetFirstPC etc  (Read 1088 times)

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0


               I know in C# you can get exception messages which occur when you try to change the contents of a list, while iterating through each member of the list.

Its something like - Cannot change contents of list while inside it or something or other...

However, I was wondering, does a similar issue exist with Changing the contents of a player list, while cycling though them?

eg

I made modifications to my local copy of nwnx_funcs to use the BootPCWithMessage function, allowing for me to boot players with a customized message. (from the tlk file)

Ok, that works, however, I want to impliment it in my reboot system for the server, so instead of booting the players 3 seconds before the boot occurs, we boot them with a non-invasive message.

Whats nicer, a message that says 'You were booted from the server'  or one that says
'Farewell, and may you die well' etc....


Anyhow...

I was wondering, does the following work?


object oPC  =GetFirstPC();
while(oPC != OBJECT_INVALID)
{
      BootPC(oPC); //Note - this is where my customized function goes.
      oPC = GetNextPC();
}



The issue I seem to have had with this, is that yes, the system did boot me, the first player in the server, however, it did not boot the person after me in the server. (was 2 of us on testing it)

Im wondering if the reason it failed, was because I left, and player 2, suddenly became player 1, and the loop tried to get the 'Next' person, which of course, didnt exist, because the next player, would have been player 2 still.


Im thinking that possible ways around this, would be to assign the boot command, to the players themselves, after a time delay.

Eg -

     DelayCommand(0.10,AssignCommand(oPC,BootPCWithMessage()));

Has anyone else had to contend with iterating through the player list, and kicking players at the same time?
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #1 on: December 31, 2010, 11:28:02 pm »


               Brain storm - I suppose I could just use




while(GetFirstPC() != OBJECT_INVALID)
    {
        //BootPC(oPC);
         BootWithMessage(oPC);
    }



Since this function is intended to boot ALL PC's an all.
               
               

               
            

Legacy_NorthWolf

  • Full Member
  • ***
  • Posts: 143
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #2 on: January 01, 2011, 01:39:53 am »


               Yeah, I would just continuously use GetFirstPC() until the server is completely empty. My guess is that the GetFirst PC/GetNextPC just use the list index to iterate through the list, as opposed to a pointer (which should make it possible to iterate through the list while removing elements).
               
               

               


                     Modifié par NorthWolf, 01 janvier 2011 - 01:42 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #3 on: January 01, 2011, 02:05:20 am »


               The simple way to solve loop issues of this kind is just to add a tiny delay. Also, you should have a validity check preceding any boot you do - booting an invalid character will crash the server.



Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #4 on: January 01, 2011, 02:30:52 am »


               With the additions of nwnx functions I really have no idea how they handle things.  



with vanilla NWN most lists never get anything removed from them untill after the script finishes.  



With creation things normally get add right there and then.  



The only thing I could really suggest for figuring this out would be to use WriteTimestampedLogEntry  to pin down what order things happen in.  



Compair your results with when the PC are logged as leaving.
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #5 on: January 01, 2011, 03:06:52 am »


               Yeah, it was checking the timestamped logs that gave the problem away in the first place.



I got booted, and Mary, one of my players, said she didnt get booted, and she waited around for 30 seconds, and then left of her own accord.



My guess at the time was that I got booted, and she took my place in the GetFirstPC() Slot, which then meant that the GetNextPC() slot was empty, which resulted in the loop ending early.





I've now changed it to use while(GetFirstPC()!=OBJECT_INVALID)

This should both cover the issue that Funky mentioned about potential crashes if kicking non-existant players, and my loop issues.
               
               

               
            

Legacy_virusman

  • Sr. Member
  • ****
  • Posts: 448
  • Karma: +0/-0
Enumeration and altering of lists while in a loop - GetFirstPC etc
« Reply #6 on: January 02, 2011, 11:26:53 am »


               I wouldn't use while(GetFirstPC()!=OBJECT_INVALID) because it has a possibility of generating an infinite loop (i.e. when the NWNX plugin is not present or for some reason the PC can't be booted).

Just use DelayCommand.