/* C++ Interface Preprocessor
* Goals: 1. Write code and interfaces once, in one place.
* 2. Interface can be spread out across multiple files if necessary.
*
* Following is an example of how the source code might look.
*/
// C++ code that needs to exist on the interface side can be put inside of a 'cpp' block with the 'public' parameter.
cpp(public) {
#include "../config.h"
}
// C++ code that needs to exist in the implementation can be put inside of a 'cpp' block with the 'private' parameter.
cpp(private) {
#include <linked_list.h>
#define LIGHTING_CONSTANT 2.5f
}
// all interfaces are automatically given a project-defined prefix, such as 'I' or 'ee', etc.
// implementations (which are translated) are given a different prefix (and possibly a suffix, like 'Local'), such as
// 'C'.
//
// the 'extends' keyword is for public inheritence. (you can prefix each class with 'private' or 'public', etc, as you
// wish.)
//
// the 'implements' keyword is for local inheritence. (e.g., in the generated implementation)
//
// when inheritting from a template, the keywords 'interface' and 'implementation' are valid as typenames and will be
// replaced with the corresponding name for the given class (if used as 'keyword name') or the current class if no name
// is given. alternatively, the name of the interface as specified in the input source may be used which would imply
// "interface <name>" if used in the extends section, or "implementation <name>" if used in the implements section.
//
// the above also applies to function parameters and other locations where a single identifier is found
interface Light extends IReferenceCounted implements TObject<implementation> {
protected:
// all of the following is translated directly into a C++ file, verbatim except for processing for the name of the
// given class, or 'interface <name>' or 'implementation <name>'.
struct {
CVec3f RGB;
f32 A;
} m_diffuse, m_ambient, m_specular;
f32 m_range, m_angles[2], m_intensity;
// e.g., here there could be: TListBase<interface Entity> m_affectedEntities;
public:
// all methods in the 'public' section are exported with the interface, code and all.
//
// all methods starting with 'abstract' are abstract methods which are part of the interface, regardless of which
// section (public, private, ...) they're in
//
// comment blocks just before a method are considered part of that function's documentation, and will be exported
// with the function (and possibly processed into a documentation format).
//
// comment blocks are laid out as a plain-text description (possibly with markdown?), followed by a list of
// parameters in the format of 'parameterName : description', and the return value as 'return : description'.
// certain items would be given their own sections, such as 'NOTE:' or 'WARNING:' or 'see also:', etc.
//
// within comment blocks, some tokens are considered (such as '@') for macro processing within the comment.
// 'copy' : @copy:section@
// 'subst' : @subst("pattern","replacement"):section@
// Set the diffuse property for this light.
//
// rgb: Unit length vector representing the red, green, and blue contribution from the light.
// a : Unsigned normalized scalar representing the alpha contribution from the light.
abstract void SetDiffuse(const CVec3f &rgb, f32 a=1.0f) {
m_diffuse.RGB = rgb;
m_diffuse.A = a ;
}
// Set the ambient property for this light.
//
// rgb: @copy:SetDiffuse@
// a: @copy:SetDiffuse@
abstract void SetAmbient(const CVec3f &rgb, f32 a=1.0f) {
m_ambient.RGB = rgb;
m_ambient.A = a ;
}
abstract void SetRange(f32 range) {
m_range = range;
}
abstract void SetAngles(f32 inner, f32 outer) {
m_angles[0] = inner;
m_angles[1] = outer;
}
// all methods declared in the public section are exported; all methods declared in the protected or private
// sections will be in the local interface.
//
// this method, being in the public section, will be exported (with all its code because it's not 'abstract')
inline void SetInnerAngle(f32 inner) {
SetAngles(inner, GetOuterAngle());
}
inline void SetOuterAngle(f32 outer) {
SetAngles(GetInnerAngle(), outer);
}
abstract void SetIntensity(f32 intensity) {
m_intensity = intensity;
}
abstract const CVec3f &GetDiffuse() const {
return m_diffuse.RGB;
}
abstract const CVec3f &GetAmbient() const {
return m_ambient.RGB;
}
abstract const CVec3f &GetSpecular() const {
return m_specular.RGB;
}
abstract f32 GetRange() const {
return m_range;
}
abstract f32 GetInnerAngle() const {
return m_angles[0];
}
abstract f32 GetOuterAngle() const {
return m_angles[1];
}
abstract f32 GetIntensity() const {
return m_intensity;
}
}
/* How It Would Integrate Into the Pipeline
* ========================================
* A simple "compiler" would be present that produces a set of .h files (one public and one local) and a .cpp file (with
* all the code from the class).
*
* Said compiler would store intermediate files somewhere for keeping coherent information about the class (such as its
* data members, the methods it exports, etc) between compiler invocations.
*
* Once all of the meta data is created the compiler would take on the role of a linker, of sorts, to generate the
* aforementioned headers and source files.
*
* After those files are available, the C++ compiler would take over as usual.
*/
/* Why This Should Be Done
* =======================
* Boosts productivity for programmers in the beginning of the project, and during maintanence, by making it easier to
* stay focused on the task at hand.
*
* Reduces silly compiler bugs, such as mismatched interfaces between headers and sources.
*
* Makes it easier to expose library functions to multiple languages. For example, a procedural interface could (and
* should!) be exported from the compiler. The same applies for other languages like D, Java, C#, BlitzMax, etc.
* Likewise, script bindings could be generated as well, e.g., for Lua.
*
* The documentation notion presented here would be easy to add on to the compiler for this language, and have it spit
* out HTML and/or doxygen files, etc.
*
* It should be possible to automate a compatibility-layer type of system whereby a old interfaces may be exported for
* applications requesting an older version of the interfaces from a newer version of the library. (Removed code could
* be configured to issue a warning somehow, or try to emulate a system, for example.) Although, this really only
* applies to "plug-in systems," so to speak.
*/
Web -
Tweets
“Things aren't always as they seem. A balloon can spell your doom, but a gory head stump can mean good luck.”