-
-
Notifications
You must be signed in to change notification settings - Fork 2
FDL Reference Manual
FDL - the Fluid Definition Language - is an Interface Definition Language designed specifically for Parasol. It is accompanied with a series of tools - idl-c
, idl-compile
and idl-doc
, which parse .fdl
files to produce language headers and user documentation.
This document describes the definition language itself. Instruction on how to use the tools is provided in the FDL Tools manual.
FDL files must be given a .fdl
extension and are expected to start with --$FLUID:Include
on their first line. FDL is a function-oriented document format, meaning the document itself makes calls to the parser so that it has control over the entire process. The first function that is called from the FDL file must be one of the following:
module({ Options... }, Function)
Use module()
to declare the interface of a named module. The following key-values can be provided as Options
:
Key | Description |
---|---|
name | The name of the module. |
copyright | Copyright information declaring the owner(s) of the module, recommended to be kept under 120 characters. |
The Function
is a callback that will define the module interface using functions declared in the next section.
header({ Options... }, Function)
Use header()
to create a language header file that declares constant types and values. Unlike module()
, a header is not permitted to export functional interfaces. The following key-values can be provided as Options
:
Key | Description |
---|---|
path | A simplified path for the header file. For example, a value of system/fields would evaluate to include/system/fields.h when generated as a C++ header. |
copyright | Copyright information declaring the owner(s) of the header, recommended to be kept under 120 characters. |
The Function
is a callback that will define the header content, using the functions declared in the next section.
c_include('<a>', '<b>', ...)
Use c_include()
to specify C/C++ headers that must be included when generating C/C++ header output.
cpp_include('<a>', '<b>', ...)
Use cpp_include()
to specify C++ headers that must be included when generating C++ header output.
c_insert(String)
Use c_insert()
to output C/C++ content when generating C/C++ headers.
platform(PlatformFilter, Function)
Use platform()
when the content described in Function
is for a specific target platform. Valid PlatformFilter
values are windows
, linux
, x11
and osx
. As an example, the following:
platform('X11', function()
c_include('<X11/Xlib.h>', '<X11/extensions/XShm.h>')
end)
Generates the following C header:
#ifdef __xwindows__
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#endif
restrict(Function)
Use restrict()
to prevent the FDL parser from outputting anything contained within Function
.
Consider a situation where an FDL file has a dependency on other FDL files. Using restrict()
as a wrapper will prevent the included definitions from appearing in the generated output, as in this example:
restrict(function()
loadFile(glPath .. 'common.fdl')
loadFile(glPath .. 'common-graphics.fdl')
end)
priority(Function)
Use priority()
to ensure that the content wrapped by Function
is inserted at the top of the generated header file.
privateNames(Values...)
Use privateNames()
to name a series of types that are considered private and not to appear in generated documentation. This does not affect header generation.
hash(Prefix, Format, Values...)
Use hash()
to convert a series of string Values
to their 32-bit hash equivalent, as output by the StrHash()
function. Each value will be named as Prefix_Value
and the generated hash will be formatted in-line with the provided Format
. For example:
hash('SVF', '0x%s',
'APPEND-PATH',
'AZIMUTH')
Generates the following C output:
#define SVF_APPEND_PATH 0x64cbc017
#define SVF_AZIMUTH 0x52cfd287
flags(Prefix, { Options }, Values..., { Manual })
Use flags()
to specify a group of bit-flags suitable for application to an integer of unspecified size. A unique name must be given to Prefix
that will categorise the group of flags.
Available Options
are:
Name | Description |
---|---|
restrict | Do not output the listed flags to the language header file. |
module | Output the listed flags only if flags() has been called from the named module. |
comment | A short description that will be added to documentation for the collection. |
bits | The maximum number of bits recommended for hosting the flags. |
The Values
is a list of strings that define the name of each flag with an appropriate short description, formatted as NAME: Description
. If NAME
contains multiple words, developers are strongly encouraged to use underscores to separate them. Sometimes a flag may have one or more synonyms, in which case the separator bar may be used to specify them, i.e. NAME|ALT_NAME:Description
.
If more control over flag configuration is required, this can be achieved by ending the value list with a table of Manual
settings. If a flag needs to be created that is a superset of other flags, a key-value like the following can be created:
NAME = 'OTHER_FLAG_A|OTHER_FLAG_B|...'
If a flag has a specific value to be associated with it, this can be achieved as follows:
NAME = '0x00000000: Description'
enum(Prefix, { Options }, Values..., { Manual })
Use enum()
to list a collection of named numeric constants that enumerate from zero.
Available Options
are:
Name | Description |
---|---|
restrict | Do not output the listed values to the language header file. |
module | Output the listed values only if enum() has been called from the named module. |
comment | A short description that will be added to documentation for the collection. |
start | Start the count from this value, otherwise default to 0. |
type | The integer type that represents the collection, typically int , short or char . Highly recommended for enabling strong typing. |
The Values
is a list of strings that define the name of each value with an appropriate short description, formatted as NAME: Description
. If NAME
contains multiple words, developers are strongly encouraged to use underscores to separate them.
If more control over flag configuration is required, this can be achieved by ending the value list with a table of Manual
settings. If a flag has a specific value to be associated with it, this can be achieved as follows:
NAME = '0x00000000: Description'
const(Prefix, { Options }, { Values... })
Use const()
to list a collection of named numeric constants with values that are manually provided.
Available Options
are:
Name | Description |
---|---|
restrict | Do not output the listed values to the language header file. |
module | Output the listed values only if const() has been called from the named module. |
comment | A short description that will be added to documentation for the collection. |
type | The integer type that represents the collection, typically int , short or char . Highly recommended for enabling strong typing. |
The Values
are provided as a key-value table. To specify a value without a comment, use the format:
NAME = Value
To attach a comment to the value:
NAME = 'Value: Description'
functionNames(Prefix, Values...)
If a module exports one or more functions, they need to be named so that an export header can be generated. A Prefix
must also be specified that will act as a namespace for the functions. Example:
functionNames('vec',
'DrawPath',
'GenerateEllipse',
'GeneratePath',
'GenerateRectangle')
struct(Name, { Options }, [[ Spec ]], [[ Append ]])
Use struct()
to declare a named structure consisting of field types.
Available Options
are:
Name | Description |
---|---|
restrict | Restricts the output to a specific language. E.g. restrict='c' will generate C header output only. |
module | Output the struct only if struct() has been called from the named module. |
comment | A short description that will be added to documentation for the collection. |
version | Associates a version number (whole numbers only) with the struct. |
type | For C/C++ only, adds a named typedef in conjunction with the struct name. |
The Spec is a multi-line string of named types that define the struct. The template for each line is as follows, where # Comment
is optional:
Type Name # Comment
Example:
struct('VectorPoint', { comment='Structure for the VectorPolygon PointsArray field.' }, [[
double X # The X coordinate of this point.
double Y # The Y coordinate of this point.
bit(uchar) XScaled # TRUE if the X value is scaled to its viewport (between 0 and 1.0).
bit(uchar) YScaled # TRUE if the Y value is scaled to its viewport (between 0 and 1.0).
]])
For information on type definitions, please refer to the Document Formatting manual.
Structs that are output to C/C++ can be augmented with additional information specified in Append
. The information that you provide here will be inserted in its raw form without interpretation from the parser.
class(Name, { Options }, [[ Spec ]], [[ Private ]], [[ Append ]])
Use class()
to declare a named structure consisting of field types.
Available Options
are:
Name | Description |
---|---|
restrict | Restricts the output to a specific language. E.g. restrict='c' will generate C header output only. |
module | Output the class only if class() has been called from the named module. |
comment | A short description that will be added to documentation for the collection. |
version | Associates a version number (Version.Revision ) with the struct. |
type | For C/C++ only, adds a named typedef in conjunction with the struct name. |
base | If the spec is for a sub-class, refer to the name of its base class here. |
src | A table of paths that refer to the C++ source file(s) representing the class. |
references | An optional table referring to flags, enums and constants that are used by the class. Only required if said references are not already declared in the Spec section. |
output | Specifying a path to an output file will generate C definitions for class methods & actions declared by the class. |
The Spec is a multi-line string of named types that define the class. The template for each line is as follows, where # Comment
is optional:
Type Name # Comment
Example:
class('File', { version=1.2, src='../classes/class_file.cpp', output='../classes/class_file_def.c' }, [[
large Position # The current read/write byte position in a file.
int(FL) Flags # File flags and options.
int Static # Set to TRUE if a file object should be static.
oid Target # Specifies a surface ID to target for user feedback and dialog boxes.
ptr(char) Buffer # Points to the internal data buffer if the file content is held in memory.
]])
For information on type definitions, please refer to the Document Formatting manual.
Classes that are output to C/C++ can declare internal content for their struct in Private
. This information will not appear in documentation, nor will it be available to clients using the class. The information that you provide here will be inserted in its raw form without interpretation from the parser.
Customised content for C++ clients can be added to the class with Append
. This feature is typically used for adding C++ specific methods and templates that can aid development, but bear in mind such additions will not be portable to other languages.
methods(Class, Prefix, { Methods })
Use methods()
to declare the public methods of a Class
. A unique Prefix
must be assigned to give the methods a namespace. The Methods
table consists of id
and name
keys to declare the methods. The following example illustrates:
methods('vectorscene', 'Sc', {
{ id=1, name='AddDef' },
{ id=2, name='SearchByID' },
{ id=3, name='FindDef' },
{ id=4, name='Debug' }
})
Each method must have a corresponding FDL method declared in the source code of the class. The parser will use this information when building viable function calls for the methods.