ENIGMA IDE_interface - hpgDesigns/hpgdesigns-dev.io GitHub Wiki

Startup

At startup, the IDE should initialize ENIGMA through its libInit method.

const char* libInit(EnigmaCallbacks* ecs);

This method takes a single parameter containing callback function pointers for use with manipulating progress reporting widgets in the IDE. The IDE should provide a printable console with a progress bar and progress status message (either overlaid onto the progress bar or displayed next to it). The functions provided through this structure are used to manipulate those three facets.

The callback structure uses this format:

struct EnigmaCallbacks
{
 //Opens the EnigmaFrame
 void (*dia_open) ();

 //Appends a given text to the frame log
 void (*dia_add) (const char *);

 //Clears the frame log
 void (*dia_clear) ();

 //Sets the progress bar (0-100)
 void (*dia_progress) (int);

 //Applies a given text to the progress bar
 void (*dia_progress_text) (const char *);


 //Sets the file from which data is redirected to frame log
 void (*output_redirect_file) (const char *);

 //Indicates file completion, dumps remainder to frame log
 void (*output_redirect_reset) ();


 //Executes a given command, returns errors or ret val
 int (*ide_execute) (const char*, const char**, bool);

 //Compresses data. Note image width/height unused
 Image* (*ide_compress_data) (char *, int);
};

Shutdown

When you are done using ENIGMA, you should free its memory with a call to libFree.

void libFree();

Definitions

Before you ask ENIGMA for anything, you should make sure that its definitions are current by calling definitionsModified. This function tells ENIGMA to parse the engine file in search of viable functions and extensions.

dllexport syntax_error *definitionsModified(const char* defcode, const char* targetYaml);

The first parameter to the function is the definitions code created by the user. These are scripts written in the host language (eg, C++), which contain definitions of functions and other items used throughout the entire game. In later versions, this mechanism will be replaced to allow multiple definitions scripts.

The second parameter to this function is an e-YAML description of the build targets, containing the default systems. An example script is as follows:

treat-literals-as: 0
sample-lots-of-radios: 0
inherit-equivalence-from: 0
sample-checkbox: on
sample-edit: DEADBEEF
sample-combobox: 0
inherit-strings-from: 0
inherit-escapes-from: 0
inherit-increment-from: 0

target-audio: OpenAL
target-windowing: xlib
target-compiler: gcc
target-graphics: OpenGL
target-widget: None
target-collision: BBox
target-networking: None

The function returns a pointer to a static syntax_error structure.

Structure syntax_error

The contents of the syntax_error structure are as follows:

struct syntax_error {
  const char *err_str; ///< The text associated with the error.
  int line; ///< The line number on which the error occurred.
  int position; ///< The column number in the line at which the error occurred.
  int absolute_index; ///< The zero-based position in the entire code at which the error occurred.
};

Accessing Definitions

The IDE can access definitions harvested by ENIGMA using its resource_ functions. Names in this API may change drastically in the next major version.

const char* first_available_resource();
const char* next_available_resource();
bool resources_atEnd();

bool resource_isFunction();
  int resource_argCountMin();
  int resource_argCountMax();
  int resource_overloadCount();
  const char* resource_parameters(int i);
int resource_isTypeName();
int resource_isGlobal();

The IDE should begin its iteration using a call to first_available_resource(), and proceed through all definitions using consecutive calls to next_available_resource(). Both functions return the name of the definition, or NULL when there are no more resources available. The IDE can explicitly check if there are no more resources available using resources_atEnd().

The remaining functions are self-explanatory, and are used to get information about the most recently returned resource. As such, these functions should NOT be used in multiple threads concurrently. In the future, the API may be refactored to allow this.

Syntax checking

After definitions are loaded, the IDE can ask ENIGMA to syntax check a piece of code with a call to syntaxCheck.

dllexport syntax_error *syntaxCheck(int script_count, const char* *script_names, const char* code);

The first and second parameter to this function define scripts, which are assumed to take any number of parameters. These script names are needed to suppress syntax errors on undefined functions. The third parameter to this function is simply the code to check.

The function returns a pointer to a static syntax_error structure containing information about the error. In the future, this will be replaced with a callback mechanism.

Compiling

When the user is ready to compile a game, the IDE invokes ENIGMA to do so through the compileEGMf method.

int compileEGMf(EnigmaStruct *es, const char* exe_filename, int mode);

The first parameter to this method is an EnigmaStruct; this structure contains pointers to potentially hundreds of instances of dozens of other structures which define resources. Code for these structures is large, but well-documented or self-explanatory, and so is excluded from this Wiki page. The IDE should populate an instance of this class appropriately and pass it as a pointer to this parameter.

The second parameter is the name of the file to which the given game data should be compiled.

The third parameter is the compilation mode. This is a member of a small enum of modes:

enum {
  emode_run,
  emode_debug,
  emode_design,
  emode_compile,
  emode_rebuild
};