LScript v1.3 Release Notes

LScript v1.3 Release Notes (final)




  UDFs that contained local arrays were randomly crashing Modeler and
  Layout when they were called/activated more than once.


  Added new requester functions:

     reqsize(width,height)

        allows you to set the width and height of the requester panel.  this
        function gives you manual control.

     ctlposition(ctlid,column,row)

        positions a control at the indicated column/row coordinates on the
        requester panel.  once you call this function, LScript relinquishes
        all control on the formatting of your controls. once you call it, you
        must call it for ALL controls on the requester or they will all
        default to (0,0) and stack one upon another.

     ctlpopup(title,default,choices[])

        creates a pop-up control with the values provided.  a pop-up is a
        button-like control that displays a scrolling list of values when it
        is selected with the mouse.

     ctlslider(title,default,minimum,maximum)

        creates a scroll-bar slider whose range matches that provided, and
        includes a numeric input field.

     ctlminislider(title,default,minimum,maximum)

        creates a numeric input field with a scroll button to the immediate
        right.

     ctlsep([column,width])

        this draw a 3D separator horizontally across your requester panel.
        'column' is the starting column (pixel) of the separator, and 'width'
        is number of columns (pixels) of the separator.  if no parameters are
        provided, then the separator will span the entire width of your panel.
        a 'width' of -1 will draw the separator to the right-most limit of
        your panel.


  Added new Light Object Agent methods rgbcolor() and rgbambient()
  for acquiring the RGB colors of a Light


  Corrected globalstore() and globalrecall() to work in the true
  global settings area for LScript


  Corrected a bug in ctlchoice() that would crash the application
  if a non-string element was provided


  Reconfigured the LScript IPC mechanism so that it will work under
  SGI LightWave without crashing the application


  Enhanced the bend() command to work around a bug in Modeler that
  incorrectly interprets the degree parameter as radians


  Corrected a bug in the Bone Object Agent code that prevented
  traversal of an Object's bone chain


  Corrected a bug that prevented access to certain Light, Bone and
  Camera Object Agent methods


  corrected a bug in smooth() that caused it to neglect the second
  'strength' parameter


  A release of memory in the requester control management code was
  randomly causing Panels-related crashes because Panels does not
  create its own local copy of character strings


  Function call parameter and associative assignment lists can now have
  implicit 'nil' elements.  If a position in a parameter or assignment
  list is left empty (i.e., nothing in that position), then that
  position receives an implicit 'nil' setting.

  Consider the following function call parameter example:

      main
      {
          testudf(,"Bob",,15.0,);
      }

      testudf: p1,p2,p3,p4,p5
      {
          info(p1," ",p2," ",p3," ",p4," ",p5);
      }

  This example script would print:

      (nil) Bob (nil) 15 (nil)

  Associative assignments benefit too from this new feature.  Let's
  say you needed only the 3rd, 4th, and 6th elements of a multi-element
  return value:

      main
      {
          str = "23,-45,69.6,100,-.05,15.34";

          (,,p1,p2,,p3) = parse(",",str);

          info(p1," ",p2," ",p3);
      }

  This example script would print:

      69.6 100 15.34

  Please note that implicit 'nil' only works with function call
  parameter lists and associative assignment lists, and only when
  commas (,) are employed.  Leaving an empty parameter entry in
  any other part of the system will likely generate a
  compile-time error.


  Default value assignments can now be made on function argument
  parameters (much like C++).  These default value assignments
  will trigger if the value passed to the function in that
  position is 'nil'.

  Consider the following example:

      main
      {
          testudf(,"Bob",,15.0,);
      }

      testudf: p1 = -3.4,p2,p3 = "pretty",p4,p5
      {
          info(p1," ",p2," ",p3," ",p4," ",p5);
      }

  This example script would print:

      -3.4 Bob pretty 15 (nil)

  If you wish to provide for an actual 'nil' value in your
  function's processing, then you must either avoid using default
  value assignments for that parameter, or use 'nil' as the
  default value.

      main
      {
          testudf(,"Bob",,15.0,);
      }

      testudf: p1,p2,p3 = "pretty",p4,p5
      {
          if(p1)    // if 'p1' == nil, nothing will print
              info(p1," ",p2," ",p3," ",p4," ",p5);
      }


  The angle() function, added in v1.2, was not calculating angles
  accurately.  This has been corrected.  Its speed has also be greatly
  increased.


  Equality testing in the engine has been enhanced to allow for more
  dissimilar type comparisons.  When comparisons take place ('==', '<', etc.),
  the second comparitor is converted to be of an equivalent data type as that
  of the first (if it is not already).

            anumber = 1.5;
            astring = "43.34";

            if(anumber == astring)  // 'astring' is converted into
            {                       // a number for the comparison
                ...

            if(astring == anumber)  // 'anumber' is converted into
            {                       // a string for the comparison

  Be aware that, in some less conventional comparisons, you may get results
  that differ depending upon which comparitor appears first.  In cases where
  the comparitors are too dissimilar, the results are undefined.


  The random(low,high) function was returning values in the range
  (low + 1) to high.  This has been corrected.


  The Object Agent interface has been enhanced to allow arrays of OA-supported
  values to be passed to OA methods.


  Point and polygon identifiers are now their (integer) index equivalents
  instead of their actual internal (unusable) Modeler id values.  As a result,
  they can now be used in comparison testing and array indexing.

        pnts = polyinfo(polygons[1]);       // pnts[2-n] are point index values


  Corrected a bug in the pre-processor causing it not to complete replacements
  on lines where there was more than one macro identifier.


  Support for a new private Object Agent method called 'alias' has been added
  to the LScript OA interface.  The 'alias' method allows for method aliasing,
  wherein an invoked Object Agent method name that cannot otherwise be resolved
  by LScript can be re-directed to another method using the 'alias' private
  method.  The LScript Appendix describing the Object Agent interface will be
  updated with relavent information on this new private method.


  The getfile() function was not accepting a third (optional) path parameter
  under Layout LScript.


  The Item Motion Object Agent set() and get() methods for an object's rotation
  were functioning in terms of radians instead of degrees.  If you are currently
  converting values using the rad() function, you should remove these workarounds
  or you will see erratic behavior in your objects.


  Added the WPOSITION parameter for the Item Motion get() method.  This parameter
  will return the object's World position; useful in cases where the object is
  parented.

        process: ma, frame, time
        {
            // grab World position in case we're parented

            position = ma.get(WPOSITION,time);
            ...


  Corrected a bug with ctltext() that would crash Layout on the DEC Alpha
  whenever it was used.


  Corrected bugs in the run-time environment with regards to the handling of
  'library' files.


  The matchfiles() function was not returning a proper value when no files
  matched the provided pattern.  It now returns 'nil' as it should.


  The run-time system has undergone a minor overhaul.  The binary format of
  compiled scripts now mimics the Interchange File Format (IFF) used by
  LightWave Object files.  This format provides enhanced modularity, and
  will enable the run-time system to be more tolerant of additions to the
  file (meaning re-compiles will become less necessary) in future releases.
  Experimental features have also been added to aid script writers in the
  commercial and semi-commerical distribution of their work.

  Because the file format has change significantly, existing compiled
  scripts will not work with v1.3 of LScript without being re-compiled.
  However, unlike predecessors, v1.3 of the run-time system should now
  be able to detect older binary file version and display an appropriate
  error message (typically "Bad magic value...") instead of crashing.


  With regard to external script components, LScript is now somewhat more
  self-configuring.  When an external component is encountered in a script
  (whether during execution or compiling) that cannot be located through
  available resources, LScript will prompt the user to locate the component
  themselves.  Once successfully located, LScript will update its own internal
  search system so that, while the located component does not move, LScript
  will not have to prompt for its location again.  External components
  upon which scripts can be dependent are things like insert files and Object
  Agent Libraries.


  The randu() now takes an optional integer parameter.  When provided, this
  value will be used to re-seed the pseudo-random number generator, making it
  possible to reproduce specific numerical sequences.


  Integral data types now respond to the following set of messages:

      size()        returns the size of the item
                       - integer and number, returns the the value itself
                       - string, returns the number of characters
                       - vector, returns 1
                       - array, returns the total elements allocated

      count()       returns the count of the item
                       - integer, number and vector, returns 1
                       - string, returns the number of characters
                       - array, returns the number of elements that
                         contain values

      asInt()       returns the data interpreted as an integer
      asNum()       returns the data interpreted as a number
      asStr()       returns the data interpreted as a character string
      asVec()       returns the data interpreted as a vector

      pack()        packs the data
                       - returns a boolean true or false to indicate
                         whether or not packing took place
                       - integer, number and vector, does nothing
                       - string, removes leading whitespace
                       - array, packs elements with values down to
                         remove intervening 'nil' values

      trunc()       truncates the data
                       - returns a boolean true or false to indicate
                         whether or not truncating took place
                       - integer, number and vector, does nothing
                       - string, removes trailing whitespace
                       - array, resizes the array, removing trailing
                         elements whose value is 'nil'

      sortA()       sorts the data
                       - returns a boolean true or false to indicate
                         whether or not sorting took place
                       - integer, number and vector, does nothing
                       - string, sorts characters in ascending order
                       - array, packs, then sorts like elements in
                         ascending order.  integer, number and string
                         are sortable.

      sortD()       sorts the data
                       - returns a boolean true or false to indicate
                         whether or not sorting took place
                       - integer, number and vector, does nothing
                       - string, sorts characters in descending order
                       - array, packs, then sorts like elements in
                         descending order.  integer, number and string
                         are sortable.

      isNil()       tests the data type for 'nil'
                       - returns a boolean true or false
                       - functionally equivalent to performing
                         and equality test (i.e., "data == nil")

      isInt()       tests the data type for integer
                       - returns a boolean true or false
                       - there is no equality test equivalent

      isNum()       tests the data type for number
                       - returns a boolean true or false
                       - there is no equality test equivalent

      isStr()       tests the data type for string
                       - returns a boolean true or false
                       - there is no equality test equivalent

      isVec()       tests the data type for vector
                       - returns a boolean true or false
                       - there is no equality test equivalent

  The following code fragment creates an array of 8 elements, and
  then places values within it at random.  A pack() and a trunc()
  are then performed on the array:

      q[8] = nil;
      q[2] = 1.5; q[4] = "Bob"; q[5] = <1,2,3>;

      info(q.size());
      info(q.count());
      info(q);

      q.pack();

      info(q);

      q.trunc();

      info(q);

  This script code would print the following messages:

      8

      3

      (nil) 1.5 (nil) "Bob" <1,2,3> (nil) (nil) (nil)

      1.5 "Bob" <1,2,3> (nil) (nil) (nil) (nil) (nil)

      1.5 "Bob" <1,2,3>

  While all data types respond to each message, not all operations have
  meaning.  For instance, packing or truncating an integer does nothing.


  The Object requester controls for Layout (ctlmeshitems(),
  ctllightitems(), etc.) now take an optional second parameter
  that can be used to initialize the control to display a specific
  object (instead of the default "(none)" selection).  This second
  parameter can be either a character string that contains the name
  of the object as it is displayed in Layout, or it can be an actual
  LightWave Object value.

  LScript will enforce types when you initialize controls.  What this
  means is that you cannot use a Mesh Object to initialize a Light Object
  control.

     c1 = ctlmeshitems("Select object","Cow.lwo");



  LScript was incorrectly posting an error regarding conflicting
  class names when more than one Object Agent class was declared using
  unique identities in a script.


  A bug in the arithmethic assignment operators (+=, -=, etc.) prevented
  them from correctly dealing with array-element lvalues.  For instance,
  the following line of code would not alter the element value:

     . . .
     i[3] += 15.340;
     . . .

  This has been corrected.


  Arithmetic operations have been streamlined and consolidated internally.
  Certain improper operations that would before have been ignored by LScript
  are now correctly flagged as illegal operations.  For example, the following
  (illegal) arithmetic operation would not produce an error under previous
  releases:

     . . .
     srf[3] = nil;
     t = srf[1] * 255;
     . . .


  A bug with ctlcolor() under Modeler was not accurately returning the values
  entered into the requester.


  The run-time plug-ins were not behaving properly under ScreamerNet.


  The ctl*items() control functions were not properly accepting an
  optional 'nil' argument in the second parameter.


  The Modelr ctlfont() control was not properly accomodating a bug in
  the Modeler's font handling by returning a value that could be used
  directly by maketext().


  The ctltext() function was always returning 'nil' instead of the control's
  identifier.


  Additional Modeler error codes have been trapped by LScript in 'autoerror'
  mode.


  The split() function was not correctly accepting all (internal) string
  data types.


  Assignments to variables containing arrays was being flagged as errors
  instead of warnings by LScript.


  LS/DM was not correctly recognizing return values from the flags()
  function.


  The default behavior for LS/DM scripts without flags() functions is now
  to process in WORLD coordinates instead of LOCAL.  If you want LOCAL
  processing, you must now explicitly return that value.


  The Layout I/O parameter provided to LScript save() and load()
  functions now provides the methods writeString() and readString()
  to deal with storing and retrieving string values in binary files.

     . . .
     save: what, io
     {
         if(what == OBJECTMODE)
         {
             . . .
             io.writeString("Hello!");
             . . .
         }
     }
     . . .
     load: what, io
     {
         if(what == OBJECTMODE)
         {
             . . .
             myString = io.readString();  // returns "Hello!"
             . . .
         }
     }
     . . .