Jump to content

[SOLUTION] Processing Arrays with >128 entries


Recommended Posts

Say you have a input Array that you've obtained through some native code means and which has or might have more than 128 entries:

ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe()

 

Say you also have an output Array of some data type other than ObjectReference:

; the struct type
Struct ObjectDescriptor
    ObjectReference TheRef
    Int Status
EndStruct

; array of struct
ObjectDescriptor[] objectsToProcess 

I use a Struct here because I can. You could however use any type here, other than ObjectReference.

Now assume that, for every element in the input Array, you want to put a new instance of the ObjectDescrptor Struct into the output Array.
The traditional approach would be to write a loop that reads each element of the input Array, creates a new Struct and fills it, and finally adds the new Struct to the output Array:

Int i = 0
ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe()
ObjectDescriptor[] objectsToProcess = new ObjectDescriptor[0]
While (i < linkedRefs.Length)
    ObjectDescriptor newDescriptor = new ObjectDescriptor
    newDescriptor.TheRef = linkedRefs[i]
    newDescriptor.Status = 1
    objectsToProcess.Add(newDescriptor)
    i += 1
EndWhile

BUT: The Array.Add() will fail after 128 elements, because Papyrus VM doesn't allow it! And the same is, unfortunately, true if we try to create the Array at a size >128 directly - Papyrus VM won't allow it.

=( =( =(

Now what???

You could rely on the Large Array Patch in LLFourplay.dll of course. Or, you could use MergeArrays() in SUP F4SE.
But what if you want or need to work without any F4SE magic at all? How can you do this then? Is there a simple solution?

Yes. Here's what you do instead:

Int i = 0
ObjectReference[] linkedRefs = refSettlementWorkshop.GetRefsLinkedToMe()
ObjectDescriptor[] objectsToProcess = (linkedRefs as Var[]) as ObjectDescriptor[]
While (i < linkedRefs.Length)
    ObjectDescriptor newDescriptor = new ObjectDescriptor
    newDescriptor.TheRef = linkedRefs[i]
    newDescriptor.Status = 1
    objectsToProcess[i] = newDescriptor
    i += 1
EndWhile

The intermediate cast of ObjectReference[] through Var[] into ObjectDescriptor[] will result in a new Array of type ObjectDescriptor being created, with the same number of entries as the ObjectReference Array has. However, because the data types (ObjectReference vs ObjectDescriptor) are not compatible, all the entries in the resulting Array will be... none. Which coincidentally just so happens to be the exact sort of thing you need here, of course: A properly sized Array, with empty entries you can fill. 🙂

 

Safe and effective. Enjoy!

 

NB: If your output Array is of the same datatype as the input Array, search for my SOLUTION for creating copies of Arrays here in the forum.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...