LavishScript:Developing Top-Level Objects

From Lavish Software Wiki
Jump to: navigation, search

Introduction

A Top-Level Object is a LavishScript scripter's entry point into a portion of your world.

Design

Organization

LavishScript is an object-oriented system. Top-Level Objects should ideally be limited to objects that are not a part of another object. For example, you do not want to have a Top-Level Object that specifically retrieves your character's health in a game -- that should be a part of a character object, and referenced by something like "Me" (short and sweet, and easy to understand).

Parameters

Top-Level Objects can use any number of parameters (arguments), accessed through LavishScript via "indices" and accessed in your program via "argc" and "argv" (basically standard for C console apps, though for Top-Level Objects the name of the object is NOT given as an argument). These arguments can be used in any fashion -- they are given to you as text, already parsed for any data sequences and such. You do not need to use any arguments at all. Most Top-Level Objects do not use parameters.

Examples of possible parameter uses:

  • Selection from a list by name
  • Selection from a list by number
Note that this can be done in the same Top-Level Object as searching by name by using the IsNumber helper function to determine whether the argument is a number
  • Search conditions
  • Selection of following parameters
For example, the "If" Top-Level Object returns a string object containing the second parameter if the first is not zero, or the third parameter if it exists and the first is zero. The "Arg" Top-Level Object also returns a string object containing a given parameter based on the first parameter's integer value. The "Select" Top-Level Object returns an int object containing the index of a given parameter, based on matching the first parameter's string value.

Returned Values

Top-Level Objects can return any valid object, or indicate to the system that the object is not valid. You wouldn't want to return an object for "Target" if you did not currently have a target, for example. The Top-Level Object must indicate both the type of object and the object itself.

Forms

A Top-Level Object "form" consists of the Top-Level Object, a returned object type, and a set of parameters. Top-Level Objects can have any number of forms, and the system itself is not concerned with that -- this is simply to describe to your users how to use your Top-Level Object.

The If Top-Level Object has two forms, as described below:

  • string If[condition,value when true]
  • string If[condition,value when true,value when false]

Each form description shows the return type when the Top-Level Object is used in a certain way. In this case, the Top-Level Object will always return a string, but may be used in two different ways.

Some identical ways of using Top-Level Objects may also have multiple return types, depending on external conditions. This is usually undesirable and potentially confusing, but is clearly a possibility and in some cases perfectly acceptable.

Implementation

Function Declaration

A Top-Level Object function declaration looks like this:

bool TLO_If(int argc, char *argv[], LSOBJECT &Dest)

Function Return Value

A Top-Level Object must return true if a valid object is being returned, and false if a valid object is not being returned. It is important to not return true without a valid object!

Function Name

We recommend this simple naming convention for Top-Level Objects, as it clearly shows that it is a Top-Level Object (TLO) and its name. TLO_If, as you probably guessed, is the "If" Top-Level Object.

argc

This parameter to the function is the number of arguments passed via LavishScript indices to the Top-Level Object. For example, ${If[1>2,ERROR]} has two arguments. argc would be 2. This is in contrast to commands, where the argc includes the full name of the command.

argv

This parameter to the function is the array of arguments passed via LavishScript indices to the Top-Level Object. For example, ${If[1>2,ERROR]} would have the following arguments:

  • 1>2
  • ERROR

Each is accessed as a standard C string (character array) using argv[#], which can be shown like so:

  • printf("%s",argv[0]);
1>2
  • printf("%s",argv[1]);
ERROR

Dest

This parameter to the function (short for Destination) stores the "returned" LavishScript object and its type. LSOBJECT has a union that can be used to set the value to any type depending on the object retrieved (for integers use Dest.Int, for floats use Dest.Float, for pointers to things use Dest.Ptr, etc), and a member called ObjectType (or Type for short) which accepts a pointer to a valid LSTypeDefinition. The value placed in the union must be a valid value for the LSTypeDefinition -- you wouldn't want to set Ret.DWord to a random number and then set Ret.Type to pStringType. That would literally be the same as setting a char* variable to a random number, then trying to print the string at that location (which most often would result in a crash). pFloatType expects a float, pIntType expects an integer, pIntPtrType expects a pointer to a 32-bit integer, and so on. Similarly, your custom "player" data type might expect a pointer to a player class. That's all a LavishScript object is, the actual value, and then a "data type" to see how to view it!

Examples

Example 1

A custom player object TLO. In this example, pPlayer is a pointer to the actual player data (which may be a "struct" or "class" in the actual game, for example). The pPlayer pointer is checked, to make sure the player data exists (recalling from earlier that the object must exist if we return true).

bool TLO_Me(int argc, char *argv[], LSOBJECT &Dest)
{
  if (Dest.Ptr=pPlayer)
  {
     Dest.Type=pPlayerType;
     return true;
  }
  return false;
}

See Also