LavishScript:Script-Defined Object Types

From Lavish Software Wiki
Jump to: navigation, search

Overview

Script-defined object types allow scripts to create object types that essentially work the same as object types created in C++ (built-in object types, types added by modules, etc), but which can also have script features such as functions. Script-defined object types can have variables, members, methods and functions.

See basic Object Type definition syntax for syntax of creation and usage of script-defined object types.

Self-reference with "This"

Objects may refer to themselves as This. This is necessary in order to access members and methods from within the object. Additionally, This[parent] is a shortcut for casting This to its parent object type, if the object type inherits from another.

Inheritance

A script-defined object type can inherit any other script-defined object type. All variables, members, methods and functions will be available to an object created of the new type, and are abstract (also known as virtual). This means that an object type that inherits another can override its variables, members, methods, or functions. Members and methods of ancestor types can be explicitly called by casting the object to the given type.

objectdef mytype1
{
  method MyMethod()
  {
     echo "This is mytype1:MyMethod"
  }
}
objectdef mytype2 inherits mytype1
{
  method MyMethod(... Params)
  {
    echo "This is mytype2:MyMethod" ${Params[1]} 
    This(mytype1):MyMethod
  }
}

When mytype2:MyMethod[foo] executes, the output would be

This is mytype2:MyMethod foo
This is mytype1:MyMethod

Another type of inheritance is available via a special GetFallthroughObject member (described below), which can allow inheriting a specific object (not type) of any type (script-defined or not).

Calling object functions

Automatically-available members

  • string ObjectName: The name of this object within its parent's variable scope
  • variablescope VariableScope: This object's variable scope
  • bool Inherits[name]: TRUE if the object type inherits, at any ancestral level, an object type with the given name

Special members

GetFallthroughObject

Object types can define an object to fall through to, if a member or method does not exist in itself or an inherited type, including the ToText member described below. The return value is treated as an object for which the member or method execution falls through to.

Consider the following:

objectdef fallthrusample
{
  member:string GetFallthroughObject()
  {
     return String[Hello World!]
  }
}
variable fallthrusample Sample
function main()
{
   echo ${Sample}
   echo ${Sample.Length}
}

The fallthrusample objectdef defines neither a ToText nor Length member, but the echoes will essentially resolve to ${String[Hello World!]} and ${String[Hello World!].Length}.

GetIndex

Objects types can have special handling for indices operating on the object. For example, ${MyObject[42]} would retrieve the object associated with index value 42. All parameters given (as dimensions of the index) are passed to this function. The member atom can of course use the standard object return system to select a return type.

member:string GetIndex(int ID)
{
  return "MyObject index of ${ID}"
}

or...

member:bool GetIndex(string name)
{
  switch ${name}
  {
    case boobies
       return TRUE
  }
  return FALSE
}

ToText

Object types can return a text value when a data sequence ends with an object of that type. For example, ${String[1234]} creates a string object, and the string object type will convert the string object directly to text, and the given data sequence is simply reduced to 1234.

ToText can be defined like so:

member ToText()

It has no parameters, but should return a value.

member ToText()
{
  return "My Object"
}

Special methods

Initialize

The initialize method will be called when an object is created using this object type. It can have any number of parameters, which will be passed from the end of the DeclareVariable command used to create the variable. For example...

objectdef mytype
{
  method Initialize(float NewX, float NewY)
  {
    x:Set[${NewX}]
    y:Set[${NewY}]
  }

  member Location()
  {
    return "${x},${y}"
  }
 
  variable float x
  variable float y
}
function main()
{
  Declare MyVar mytype 1000.0 250.0
  echo ${MyVar.Location}
}

Output:

1000.0,250.0

Initialize routines of ancestor object types are NOT automatically called. If inheriting an object type, that object type's Initialize routine should be explicitly called by your Initialize method.

objectdef mytype1
{
  method Initialize()
  {
  }
}
objectdef mytype2 inherits mytype1
{
  method Initialize()
  {
    This[parent]:Initialize
  }
}

Shutdown

The Shutdown method will be automatically called when an object of this type is destroyed. It does not receive any parameters, and can be defined like so:

method Shutdown()

Shutdown routines of ancestor object types ARE automatically called in reverse order. That is, the immediate object type is the first Shutdown executed, followed by its parent, then its parent's parent, and so on, to the base object type.

See Also