Advertisement
Guest User

Untitled

a guest
Oct 25th, 2021
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.08 KB | None | 0 0
  1. //_______________________________________________________________________________________________________________________________
  2. // DescX Notes:
  3. //      Index-based arrays for safer/easier to read code.
  4. //      Requires New() and Delete().
  5. //      For Tribes.exe :)
  6. $Array::DefaultName = "Array::Index";       // The "type name" prefixed to instance indicies
  7. $Array::DefaultNull = "";                   // The default null value when an array is invalid
  8.  
  9. // "API":
  10. //
  11. //  Array::New                  Register a new array. Specify what NULL should be, and/or a custom name. Return the name.
  12. //  Array::Delete               Delete a registered array.
  13. //  Array::Get                  Index accessor
  14. //  Array::Insert               Range-enabled insert
  15. //  Array::Fill                 Insert a delimited list of values starting at a given position
  16. //  Array::EraseRange           Null a range of elements. Do nothing else.
  17. //  Array::Shrink               Remove all NULL values and compact the array
  18. //  Array::RemoveRange          EraseRange, and then Shrink
  19. //  Array::Valid                Check if the array was registered with New()
  20. //  Array::Copy                 Copy a registered array into destination registered array. Frees the destination first.
  21. //  Array::CopyToWorld          Quick hack for saving arrays in TRPG. Dumps array data from $Array:: space to $world::Array:: space
  22. //  Array::CopyFromWorld        Same as CopyToWorld, but in reverse.
  23. //
  24. // Underlying globals:
  25. //      $Array::Total               The TOTAL number of calls to New() that generated a new array.
  26. //
  27. //      $Array::Size[name]          The number of elements currently in this array.
  28. //      $Array::Data[name]          The name of this array.
  29. //      $Array::Data[name, X]       The data inside this array
  30. //      $Array::NullValue[name]     The value considered to be NULL for this array's elements. Use with Shrink() to deduplicate/etc
  31. //_______________________________________________________________________________________________________________________________
  32. //
  33. // EXAMPLE      USAGE       AND         EXECUTABLE      TEST
  34. //
  35. //                  !!! STOP !!!
  36. //
  37. //  THIS        TEST        DELETES     ALL         ARRAYS
  38. //
  39. function Array::TestFeaturesAndEcho() {
  40.    
  41.     // test setup  
  42.     for(%x=0;%x<$Array::Total;%x++)
  43.         Array::Delete($Array::DefaultName @ %x);
  44.     $Array::Total = 0;
  45.     $Array::Freed = "";
  46.     function Array::TestPrint(%array) {
  47.         for(%x=0;%x<$Array::Size[%array];%x++)
  48.             echo("    " @ %array @ "[" @ %x @ "] = " @ Array::Get(%array,%x));
  49.     }
  50.    
  51.     echo("--------------------------------");
  52.     echo("- Array test");
  53.     echo("--------------------------------");
  54.     echo("Make 5 new arrays. Work with index 4");
  55.         %array = Array::New();
  56.         %array = Array::New();
  57.         %array = Array::New();
  58.         %array = Array::New();
  59.         %array = Array::New();
  60.    
  61.     echo("--------------------------------");
  62.     echo("Ranged and random insertion");
  63.         Array::Insert(%array, 1, 3);
  64.         Array::Insert(%array, 2, 5, 10);
  65.         Array::Insert(%array, 3, 7);   
  66.         Array::TestPrint(%array);
  67.     echo("PASS IF    " @ $Array::DefaultName @ "4" @ "[] = _ _ _ 1 _ 2 2 3 2 2 2");
  68.    
  69.    
  70.     echo("--------------------------------");
  71.     echo("Shrink");
  72.         Array::Shrink(%array);
  73.         Array::TestPrint(%array);
  74.     echo("PASS IF    " @ $Array::DefaultName @ "4" @ "[] = 1 2 2 3 2 2 2");
  75.    
  76.     echo("--------------------------------");
  77.     echo("Erase elements 3 & 4, no shrink");
  78.         Array::EraseRange(%array, 3, 4);
  79.         Array::TestPrint(%array);
  80.     echo("PASS IF    " @ $Array::DefaultName @ "4" @ "[] = 1 2 2 _ _ 2 2");
  81.    
  82.     echo("--------------------------------");
  83.     echo("Copy to invalid unmanaged name? FAIL");
  84.         Array::Copy(%array, "myCustomName");
  85.         Array::TestPrint("myCustomName");
  86.     echo("PASS IF    nothing prints");
  87.    
  88.     echo("--------------------------------");
  89.     echo("Copy managed to NEW unmanaged");
  90.         %unmanagedArray = Array::New("", "myCustomName");
  91.         Array::Copy(%array, "myCustomName");
  92.         Array::TestPrint("myCustomName");
  93.     echo("PASS IF    myCustomName" @                 "[] = 1 2 2 _ _ 2 2");
  94.    
  95.     echo("--------------------------------");
  96.     echo("Copy unmanaged to managed name");
  97.         Array::Copy(%unmanagedArray, $Array::DefaultName @ "2");
  98.         Array::TestPrint($Array::DefaultName @ "2");
  99.     echo("PASS IF    " @ $Array::DefaultName @ "2" @ "[] = 1 2 2 _ _ 2 2");
  100.    
  101.     echo("--------------------------------");
  102.     echo("Delete managed index 4, then 3");
  103.         Array::Delete($Array::DefaultName @ "4");
  104.         Array::Delete($Array::DefaultName @ "3");
  105.         Array::TestPrint($Array::DefaultName @ "4");
  106.         Array::TestPrint($Array::DefaultName @ "3");
  107.     echo("PASS IF    nothing prints");
  108.    
  109.     echo("--------------------------------");
  110.     echo("Oldest Delete was 4 - does new array reuse 4 ???");
  111.         %testStringA = "This had numbers.";
  112.         %newArray = Array::New();
  113.         Array::Insert(%newArray, %testStringA);
  114.         Array::TestPrint(%newArray);
  115.     echo("PASS IF    " @ $Array::DefaultName @ "4" @ "[] = \"" @ %testStringA @ "\"");
  116.    
  117.     echo("--------------------------------");
  118.     echo("Delete managed and myCustomName");
  119.         Array::Delete("myCustomName");
  120.         for(%x=0;%x<$Array::Total;%x++)
  121.             Array::Delete($Array::DefaultName @ %x);
  122.         for(%x=0;%x<$Array::Total;%x++)
  123.             Array::TestPrint($Array::DefaultName @ %x);
  124.         Array::TestPrint("myCustomName");
  125.         echo($Array::Freed);
  126.     echo("PASS IF    3 0 1 2 4");
  127.     echo("--------------------------------");
  128. }
  129.  
  130.  
  131. //_______________________________________________________________________________________________________________________________
  132. // Retrieve the value of an array. This code uses global variables to work around the inability to pass arrays to functions
  133. function Array::Get(%array, %index) {
  134.     if(!Array::Valid(%array))
  135.         return $Array::DefaultNull;
  136.     %whatIsNull = $Array::NullValue[%array];
  137.     %pos        = floor(%index);
  138.     if(Math::isInteger(%pos) && %pos < $Array::Size[%array])
  139.         return $Array::Data[%array, %index];
  140.     else return %whatIsNull;
  141. }
  142.  
  143. //_______________________________________________________________________________________________________________________________
  144. // Insert a specific value into [a range of] indicies. If the start position is -1, assume end-of-list insertion. Blank assumes front
  145. function Array::Insert(%array, %value, %indexStart, %indexEnd) {
  146.     %inserted = 0;
  147.     if(Array::Valid(%array)) {
  148.         %whatIsNull = $Array::NullValue[%array];   
  149.         if(%indexStart <= 0)        %pos = 0;
  150.         else if(%indexStart == "")  %pos = $Array::Size[%array];
  151.         else                        %pos = floor(%indexStart); 
  152.        
  153.         if(%indexEnd == "")     %end = %pos;
  154.         else                    %end = floor(%indexEnd);
  155.    
  156.         if(Math::isInteger(%pos) && %pos >= 0 && Math::isInteger(%end)) {      
  157.             for(%x=0;%x<=%end;%x++) {
  158.                 if(%x >= $Array::Size[%array]) {
  159.                     $Array::Data[%array,%x] = %whatIsNull;
  160.                     $Array::Size[%array] = %x + 1;
  161.                 }
  162.                 if(%x >= %pos) {
  163.                     %inserted++;
  164.                     $Array::Data[%array,%x] = %value;
  165.                 }
  166.             }
  167.         }
  168.     }
  169.     return %inserted;
  170. }
  171.  
  172. //_______________________________________________________________________________________________________________________________
  173. // Fill the array with a delimited string of values starting at indexStart
  174. function Array::Fill(%array, %flatValueList, %delimiter, %indexStart) {
  175.     %inserted = 0;
  176.     if(Array::Valid(%array)) {
  177.         %whatIsNull = $Array::NullValue[%array];   
  178.         if(%indexStart <= -1)       %pos = 0;
  179.         else if(%indexStart == "")  %pos = $Array::Size[%array];
  180.         else                        %pos = floor(%indexStart);
  181.    
  182.         if(Math::isInteger(%pos) && %pos >= 0 && Math::isInteger(%end)) {          
  183.             %value = "";
  184.             %nextValuePos = String::findSubStr(%flatValueList,%delimiter);
  185.             if(%nextValuePos != -1) {
  186.                 %value          = String::newGetSubStr(%flatValueList,0,%nextValuePos);
  187.                 %flatValueList  = String::newGetSubStr(%flatValueList,%nextValuePos+1,9999);
  188.             } else if (%flatValueList != $Array::NullValue[%array]) {
  189.                 %value          = %flatValueList;
  190.                 %flatValueList  = $Array::NullValue[%array];
  191.             }
  192.        
  193.             for(%x=0; %value != ""; %x++) {
  194.                 if(%x >= $Array::Size[%array]) {
  195.                     $Array::Size[%array] = %x + 1;
  196.                 }
  197.                 if(%x >= %pos){                
  198.                     %inserted++;
  199.                     $Array::Data[%array,%x] = %value;
  200.                     %nextValuePos = String::findSubStr(%flatValueList,%delimiter);
  201.                     if(%nextValuePos != -1) {
  202.                         %value          = String::newGetSubStr(%flatValueList,0,%nextValuePos);
  203.                         %flatValueList  = String::newGetSubStr(%flatValueList,%nextValuePos+1,9999);
  204.                     } else if (%flatValueList != $Array::NullValue[%array]) {
  205.                         %value          = %flatValueList;
  206.                         %flatValueList  = $Array::NullValue[%array];
  207.                     } else break;
  208.                 }              
  209.             }
  210.         }
  211.     }
  212.     return %inserted;
  213. }
  214.  
  215. //_______________________________________________________________________________________________________________________________
  216. // Erase [a range of] indicies from an array without changing the size
  217. function Array::EraseRange(%array, %indexStart, %indexEnd) {
  218.     %removed=0;
  219.     if(Array::Valid(%array)) {
  220.         %pos = floor(%indexStart);
  221.         if(%indexEnd == "") %end = %pos;
  222.         else                %end = floor(%indexEnd);
  223.         %whatIsNull = $Array::NullValue[%array];
  224.         if(Math::isInteger(%pos) && %pos >= 0 && Math::isInteger(%end)) {          
  225.             for(%x=%end;%x>=%pos;%x--){
  226.                 $Array::Data[%array,%x] = %whatIsNull;
  227.                 %removed++;
  228.             }
  229.         }
  230.     }
  231.     return %removed;
  232. }
  233.  
  234. //_______________________________________________________________________________________________________________________________
  235. // Remove nulls from the array and shrink it to the smallest size possible
  236. function Array::Shrink(%array) {
  237.     %removed    = 0;
  238.     if(Array::Valid(%array)) {     
  239.         %whatIsNull = $Array::NullValue[%array];
  240.         %y          = 0;
  241.         for(%x=0;%x<$Array::Size[%array];%x++) {
  242.             if($Array::Data[%array,%x] == %whatIsNull) {
  243.                 %removed++;
  244.             } else {
  245.                 $Array::Data[%array,%y] = $Array::Data[%array,%x];
  246.                 %y++;
  247.             }
  248.         }
  249.         %oldSize = $Array::Size[%array];
  250.         $Array::Size[%array] -= %removed;
  251.         for(%x=$Array::Size[%array];%x<%oldSize;%x++){
  252.             $Array::Data[%array,%x] = "";
  253.         }      
  254.     }
  255.     return %removed;
  256. }
  257.  
  258. //_______________________________________________________________________________________________________________________________
  259. // Remove indicies from an array, and shrink the array to the minimum required size
  260. function Array::RemoveRange(%array, %indexStart, %indexEnd) {
  261.     %removed = Array::EraseRange(%array,%indexStart,%indexEnd);
  262.     if(%removed > 0) Array::Shrink(%array);
  263.     return %removed;
  264. }
  265.  
  266. //_______________________________________________________________________________________________________________________________
  267. // Construct an %array with an optional custom name. Pop the oldest free index off the stack if possible.
  268. function Array::New(%whatIsNull, %optionalName) {
  269.     if(%optionalName != "") {
  270.         %array = %optionalName;    
  271.     } else {
  272.         %topOfFreeStack = GetWord($Array::Freed,0);
  273.         if(%topOfFreeStack != -1) {             // got something to pop? pop pop. poppitty pop paaaawwp pop.           
  274.             $Array::Freed   = String::replace($Array::Freed, %topOfFreeStack @ " ", "");
  275.             %newName        = $Array::DefaultName @ %topOfFreeStack;
  276.         } else {
  277.             %oldTotal = $Array::Total;
  278.             $Array::Total++;
  279.             if(%oldTotal >= $Array::Total) {    // In case of overflow, reuse a trap array to limit damage
  280.                 $Array::Total = %oldTotal;
  281.                 %newName = "Array::OverflowTrap";                  
  282.                 dbecho(999, %newName @ ": PANIC: NO FREE ARRAYS");
  283.             } else {
  284.                 %newName = $Array::DefaultName @ %oldTotal;
  285.             }
  286.         }
  287.         %array = %newName;
  288.     }
  289.    
  290.     $Array::NullValue[%array] = %whatIsNull;
  291.     $Array::Size[%array] = 0;
  292.     $Array::Data[%array] = %array;
  293.     return %array;
  294. }
  295.  
  296. //_______________________________________________________________________________________________________________________________
  297. // Consider this array to be "valid" if it has an integer size and the datastring matches the arraystring
  298. function Array::Valid(%array) {
  299.     return (Math::isInteger($Array::Size[%array]) && $Array::Data[%array] == %array);
  300. }
  301.  
  302. //_______________________________________________________________________________________________________________________________
  303. // Copy an array into a destination array. %destination must be another array, but the user takes responsibility for trampling data
  304. function Array::Copy(%array, %destination) {
  305.     if(Array::Valid(%array)) {
  306.         if(Array::Delete(%destination, true)) { // dont free, just delete
  307.             $Array::Data[%destination]      = %destination;
  308.             $Array::Size[%destination]      = $Array::Size[%array];
  309.             $Array::NullValue[%destination] = $Array::NullValue[%array];
  310.             for(%x=0;%x<$Array::Size[%array];%x++)
  311.                 $Array::Data[%destination,%x] = $Array::Data[%array,%x];   
  312.             return true;
  313.         }
  314.     }
  315.     return false;
  316. }
  317.  
  318.  
  319. //_______________________________________________________________________________________________________________________________
  320. // Copy an array TO the $world:: context
  321. function Array::CopyToWorld(%array) {
  322.     if(Array::Valid(%array)) {
  323.         $world::Array::Data[%array]             = %array;
  324.         $world::Array::Size[%array]             = $Array::Size[%array];
  325.         $world::Array::NullValue[%array]        = $Array::NullValue[%array];
  326.         for(%x=0;%x<$Array::Size[%array];%x++)
  327.             $world::Array::Data[%array,%x]      = $Array::Data[%array,%x]; 
  328.         return true;
  329.     }
  330.     return false;
  331. }
  332.  
  333.  
  334. //_______________________________________________________________________________________________________________________________
  335. // Copy an array FROM the $world:: context
  336. function Array::CopyFromWorld(%array) {
  337.     if(Array::Valid(%array)) {
  338.         $Array::Data[%array]            = %array;
  339.         $Array::Size[%array]            = $world::Array::Size[%array];
  340.         $Array::NullValue[%array]       = $world::Array::NullValue[%array];
  341.         for(%x=0;%x<$Array::Size[%array];%x++)
  342.             $Array::Data[%array,%x]     = $world::Array::Data[%array,%x];  
  343.         return true;
  344.     }
  345.     return false;
  346. }
  347.  
  348. //_______________________________________________________________________________________________________________________________
  349. // Clear its contents and counters. Assume we want to add this array to the "freed" stack (but some code may prefer GarbageCollection())
  350. function Array::Delete(%array, %dontFree) {
  351.     if(Array::Valid(%array)) {
  352.         for(%x=0;%x<$Array::Size[%array];%x++)
  353.             $Array::Data[%array,%x] = "";
  354.         $Array::Data[%array]        = "";
  355.         $Array::Size[%array]        = "";
  356.         $Array::NullValue[%array]   = "";
  357.         if(%dontFree != true) {
  358.             %index = String::replace(%array,$Array::DefaultName,"");
  359.             if(%index != %array && String::findSubStr($Array::Freed, %index) == -1)     // dont "free" user-named objects
  360.                 $Array::Freed = $Array::Freed @ %index @ " ";
  361.         }
  362.         return true;
  363.     }
  364.     return false;
  365. }
  366.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement