Difference between revisions of "LavishScript:Developing Top-Level Objects"

From Lavish Software Wiki
Jump to navigation Jump to search
m
Line 1: Line 1:
= Introduction =
+
== 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.
 +
 
 +
=== 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 [[TLO:If|If]] Top-Level Object has two forms, as described below:
 +
*[[DataType:string|string]] '''If['''condition''','''value when true''']'''
 +
*[[DataType:string|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.
 +
 
 +
== Implementation ==
 +
=== Function Declaration ===
 +
A Top-Level Object function declaration looks like this:
 +
bool TLO_If(int argc, char *argv[], LSTYPEVAR &Ret)
 +
 
 +
==== 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 using argv[#], which can be shown like so:
 +
*printf("%s",argv[0]);
 +
:1>2
 +
*printf("%s",argv[1]);
 +
:ERROR
 +
 
 +
==== Ret ====
 +
This parameter to the function (sometimes referred to as Dest) stores the "returned" LavishScript object and its type.  LSTYPEVAR has a '''union''' that can be used to set the value to any type depending on the member used (e.g. Ret.DWord, Ret.Ptr, Ret.Float, etc), and a member called Type which accepts a pointer to a valid LSType.  The value placed in the union must be a valid value for the LSType -- 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[], LSTYPEVAR &Ret)
 +
{
 +
  if (Ret.Ptr=pPlayer)
 +
  {
 +
      Ret.Type=pPlayerType;
 +
      return true;
 +
  }
 +
  return false;
 +
}
  
= Basics =
 
  
 
{{stub}}
 
{{stub}}

Revision as of 04:01, 16 May 2005

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.

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.

Implementation

Function Declaration

A Top-Level Object function declaration looks like this:

bool TLO_If(int argc, char *argv[], LSTYPEVAR &Ret)

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 using argv[#], which can be shown like so:

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

Ret

This parameter to the function (sometimes referred to as Dest) stores the "returned" LavishScript object and its type. LSTYPEVAR has a union that can be used to set the value to any type depending on the member used (e.g. Ret.DWord, Ret.Ptr, Ret.Float, etc), and a member called Type which accepts a pointer to a valid LSType. The value placed in the union must be a valid value for the LSType -- 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[], LSTYPEVAR &Ret)
{
  if (Ret.Ptr=pPlayer)
  {
     Ret.Type=pPlayerType;
     return true;
  }
  return false;
}