Skip to content

Modules and Interfaces

Chris Dusto edited this page Apr 23, 2017 · 1 revision

Modules

A CECILIA module is any external, dynamically-linked piece of compiled code which CECILIA can use to extend its own functionality. This definition carries a number of implications:

  • "external": When a new module is created, the entire codebase doesn't need to be recompiled
  • "dynamically-linked": Modules can be added or removed at runtime
  • "piece of compiled code": Modules are not scripts, in the traditional sense; they are compiled.
  • "CECILIA can use": Modules have a unified means of access for CECILIA; they implement a number of interfaces through which CECILIA can obtain functionality
  • "extend its own functionality": Modules themselves are only intended for direct use by CECILIA, not other modules. That said, a module can request CECILIA to load another, and native library support is permitted for modules.

Modules can be written in any programming language which has a thorough-enough implementation of CFFI; this allows an operator to write their own modules in the language they are most familiar with.

Interfaces

A CECILIA interface (not to be confused with a user interface) is a predetermined collection of functions with similar purpose that a module can implement. A module can implement multiple interfaces (and any sensible module will implement at least two), and some interfaces can be implemented by multiple different modules (the goal is to have a system of inheritance similar to that of the Common Lisp Object System).

A handful of interface definitions are built into CECILIA's core, and even fewer are implemented. However, modules are able to define new interface definitions, which not only allows new possibilities for inter-module communication, but also allows entire libraries of standardized interfaces to be created as modules.

Usage of Interfaces

Modules implement interfaces, which are collections of functions. Modules also utilize interfaces to communicate with other modules, or the CECILIA core itself. Generally, control passes into a module when one of the interfaces it implements is utilized and subsequently called, and control can be passed to another module by utilizing an interface that other module implements, followed by calling it.

Interface Definition

When an interface is defined, CECILIA is given a list of the functions required to implement the interface, their arguments and return values, and a description of what happens if multiple modules attempt to implement the interface.

Interface Implementation

When an interface is implemented, CECILIA is given a list of function pointers which can be used to perform the tasks the interface is intended to implement.

Interface Utilization

When an interface is utilized, CECILIA checks to ensure there is some form of valid implementation (which can be provided by the definition) for the interface. If there is such a valid implementation, the utilization succeeds. Note that utilization is different from calling; utilization announces an intent to call functions present in an interface.

Interface Calling

After an interface has been utilized by a module, calls to the interface (or, more specifically, one of the functions it exposes) can be made by calling a function built into the CECILIA core. Note that it is an error to call an interface's functions without utilizing the interface first.