LavishScript:Object References and Persistence

From Lavish Software Wiki
Jump to: navigation, search

The following information applies to LavishScript in Inner Space 1.12, builds 5929 and later.

LavishScript allows certain types of objects to be referenced by a persistentref, thus allowing various objects to be passed by reference to Functions (including Members, Methods, and Atoms).

Specifically, to be referenced by a persistentref, object types must be defined as supporting persistent behavior. The LavishScript engine assumes non-persistent objects have the shortest possible lifetime, whereas when a persistent object is destroyed, all active references are invalidated by the object itself.

Whether an object type supports persistence can be determined by checking the value of type.PersistentClass (e.g. ${Type[int].PersistentClass}), where no result (NULL) means no persistence. Many LavishScript types support persistence, including:

Using a persistentref object

persistentref supports both immediate and late initialization

Immediate
variable persistentref MyRef = SomeOtherObject
Late
variable persistentref MyRef
MyRef:SetReference[SomeOtherObject]

After persistentref initialization, as long as the referenced object exists it can be accessed directly through MyRef as if it were the original object. Whether the reference is still valid or not can be determined by checking the value of persistentref.Reference, where no result (NULL) means no reference. (e.g. ${MyRef.Reference(exists)})

Passing by reference

Because persistentref supports immediate initialization, a persistentref can be used as a parameter to any Function (including Members, Methods, and Atoms). Additionally, a persistentref can be returned from an explicitly-defined Member.

objectdef someObject 
{ 
  member:persistentref GetItself(persistentref PassedByReference)
  {
     return PassedByReference
  } 

  member:int GetSize(persistentref PassedByReference)
  {
     return ${PassedByReference.Size}
  }

  member:int GetElement(persistentref PassedByReference, string element_key)
  {
     return ${PassedByReference["${element_key.Escape}"]}
  }
}

function main()
{
  variable collection:int MyCollection
  variable someObject SomeObject 

  MyCollection:Set[one,2]
  echo Size of MyCollection (method 1): ${SomeObject.GetItself[MyCollection].Size} -- expected '1'
  echo Size of MyCollection (method 2): ${SomeObject.GetSize[MyCollection]} -- expected '1'
  echo Value of MyCollection[one]: ${SomeObject.GetElement[MyCollection,one]} -- expected '2'
}