#ifndef _GHOST_H #define _GHOST_H /* GHost */ #include #include namespace GHost { //////////////////////////////////////////////////////////////////////////////// /* object the universal object type, information needed for all objects TODO do we really want a universal object class? It seems to me that not everything needs to be descended from it - links, specifically. */ class object { /* Object Identification - TODO we should unify this with object identification in general. `fullname' is the fully-qualified universal identifier for this object. `name' is the personal name for this object, which must be locally unique. TODO work out a sensible ID / naming scheme - do we need meaningful textual names AND numercal IDs for fast lookup? TODO This ID system is woefully inadequate - we need comprehensive metadata on objects, including authorship, time of creation / update, version information, relational linking (e.g. module X requires module Y), attributes, classification, how to view/edit, and documentation. FLEXIBLE is the word! */ string fullname; string name; /* TODO some general class information, methods to determine characteristics? */ virtual bool is_type() = 0; } //////////////////////////////////////////////////////////////////////////////// /* module_type An instance of this class describes the type of a module. */ class module_type : public object { /* Every module has interface nodes, which may be connected to other modules. Many modules have a fixed number of nodes, with distinct names and meanings. Other modules use fixed node-groups, each with a variable number of nodes. An example would be the standard `sum' relation, which declares that two sets of nodes sum to the same value, or a multiplexor. Some modules might dynamically connect new nodes at run-time (within the defined node-groups), for example, a web-server module, A node is functionally similar to a TCP `socket', but it works with objects, not streams. The GHost execution model is conceptually similar to the `select' syscall, with nodes taking the place of file descriptors. We need both order and lookup by name, hence the use of two STL containers. TODO synthesise this pattern. */ vector nodes; map nodes_by_name; /* Every module has a graphical representation, in support of the visual programming system. I do not currently see the need for multiple graphic-forms for a single module. The opposite is the case - the graphic_form member is a pointer, so that multiple module-types can share the same graphic-form. */ module_graphic* graphic_form; /* Text-forms are a natural language representation of a relation (module). Node names are represented amidst free text in parentheses. There is provision for a relation to have more than one text-form; so different nodes may appear as the subject, a variety of expression is possible, and in some forms, not all nodes need appear. Functional forms are supported, the expression node is enclosed in angle-brackets. Multi-language support will be an interesting issue here! We can have a list of text-forms for each language. for example: `(list) has length (length)' `(list) has (length) elements' `(length) is the length of (list)' ` length (list)' */ vector text_forms; /* map modes; } /* what types of module_types are there? compiled interpreted abstract THIS IS INSANE! we need to use prototype copying instead of class instantiation, because this is not working. */ //////////////////////////////////////////////////////////////////////////////// /* compiled_module_type A subclass of module_type, executable, with C++ code implementing the module's behaviour. */ class compiled_module_type { } //////////////////////////////////////////////////////////////////////////////// /* interpreted_module_type A subclass of module_type, executable, defined in terms of smaller modules. */ class interpreted_module_type { } class mode_type { /* high level description of the mode - TODO Need methods for these. These bit fields have one bit for each node */ vector _can_push; vector _can_pop; // alive means there may be spontaneous state changes virtual bool alive() { return false; } // get a state-transition model for this mode, if one exists virtual mode_model *model() { return NULL; } } class mode_model { // this describes a state transition network // here are the possible initial states vector initial; } class state { // a state may have a name string name; // bit fields describing acceptable transitions from this state vector can_push; vector can_pop; /* here is a list of states that the machine may enter spontaneously (e.g. after a timeout elapses, interrupt occurs) */ vector auto_transitions; vector triggers; // TODO should be a map? } class trigger { enum type_t { push, pop } type; int } /* NODE TYPES */ class node_type { string name; path_position position; } class single_node_type : public node_type { bool can_move; // is this useful? } class list_node_type : public node_type { path_position position_end; } class set_node_type : public list_node_type { } class module_graphic { colour colour; path path; } class path { vector segments; } class segment { /* Type closed or open is used for the first segment, to specify what type of path it is - if closed, the last point is automatically set to the first point. */ enum type_t { line, spline } type; point to; } class segment_spline : public segment { point cp1, cp2; } class colour { int rgba; // TODO need to ensure int32, also elsewhere // Should probably use a gnome colour or something } class point { point(double x, double y) : x(x), y(y) {} void set_polar(double a, double r) { x = sin(rad(a))*r; y = cos(rad(a))*r; } double x, y; } class path_position { int segment; float fraction; } } #endif