diff --git a/Lua API.html b/Lua API.html index 86b9c00c8..25b6f06d6 100644 --- a/Lua API.html +++ b/Lua API.html @@ -330,6 +330,11 @@ ul.auto-toc {
  • Named types
  • Global functions
  • +
  • Recursive table assignment
  • + + +
  • DFHack utilities
  • @@ -430,17 +435,22 @@ or as a result of calling the _field() method. +
    +

    Recursive table assignment

    +

    Recursive assignment is invoked when a lua table is assigned +to a C++ object or field, i.e. one of:

    + +

    The general mode of operation is that all fields of the table +are assigned to the fields of the target structure, roughly +emulating the following code:

    +
    +function rec_assign(ref,table)
    +    for key,value in pairs(table) do
    +        ref[key] = value
    +    end
    +end
    +
    +

    Since assigning a table to a field using = invokes the same +process, it is recursive.

    +

    There are however some variations to this process depending +on the type of the field being assigned to:

    +
      +
    1. If the table contains an assign field, it is +applied first, using the ref:assign(value) method. +It is never assigned as a usual field.

      +
    2. +
    3. When a table is assigned to a non-NULL pointer field +using the ref.field = {...} syntax, it is applied +to the target of the pointer instead.

      +

      If the pointer is NULL, the table is checked for a new field:

      +
        +
      1. If it is nil or false, assignment fails with an error.
      2. +
      3. If it is true, the pointer is initialized with a newly +allocated object of the declared target type of the pointer.
      4. +
      5. Otherwise, table.new must be a named type, or an +object of a type compatible with the pointer. The pointer +is initialized with the result of calling table.new:new().
      6. +
      +

      After this auto-vivification process, assignment proceeds +as if the pointer wasn't NULL.

      +

      Obviously, the new field inside the table is always skipped +during the actual per-field assignment processing.

      +
    4. +
    5. If the target of the assignment is a container, a separate +rule set is used:

      +
        +
      1. If the table contains neither assign nor resize +fields, it is interpreted as an ordinary 1-based lua +array. The container is resized to the #-size of the +table, and elements are assigned in numeric order:

        +
        +ref:resize(#table);
        +for i=1,#table do ref[i-1] = table[i] end
        +
        +
      2. +
      3. Otherwise, resize must be true, false, or +an explicit number. If it is not false, the container +is resized. After that the usual struct-like 'pairs' +assignment is performed.

        +

        In case resize is true, the size is computed +by scanning the table for the largest numeric key.

        +
      4. +
      +

      This means that in order to reassign only one element of +a container using this system, it is necessary to use:

      +
      +{ resize=false, [idx]=value }
      +
      +
    6. +
    +

    Since nil inside a table is indistinguishable from missing key, +it is necessary to use df.NULL as a null pointer value.

    +

    This system is intended as a way to define a nested object +tree using pure lua data structures, and then materialize it in +C++ memory in one go. Note that if pointer auto-vivification +is used, an error in the middle of the recursive walk would +not destroy any objects allocated in this way, so the user +should be prepared to catch the error and do the necessary +cleanup.

    +
    + +
    +

    DFHack utilities

    +

    DFHack utility functions are placed in the dfhack global tree.

    +

    Currently it defines the following features:

    + +
    +

    Persistent configuration storage

    +

    This api is intended for storing configuration options in the world itself. +It probably should be restricted to data that is world-dependent.

    +

    Entries are identified by a string key, but it is also possible to manage +multiple entries with the same key; their identity is determined by entry_id. +Every entry has a mutable string value, and an array of 7 mutable ints.

    + +

    Since the data is hidden in data structures owned by the DF world, +and automatically stored in the save game, these save and retrieval +functions can just copy values in memory without doing any actual I/O. +However, currently every entry has a 180+-byte dead-weight overhead.

    +