Created
June 16, 2012 10:00
-
-
Save pghalliday/2940847 to your computer and use it in GitHub Desktop.
Object Oriented OCode Boiler Plate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "opentv.h" | |
#include "assert.h" | |
#include "MyClass.h" | |
/* This method just waits for a quit message and then exits the application */ | |
static void Main_waitToExit(void) | |
{ | |
while (TRUE) | |
{ | |
o_message tMessage; | |
O_ui_get_event_wait(&tMessage); | |
if (O_msg_class(&tMessage) == MSG_CLASS_CONTROL) | |
{ | |
if (O_msg_type(&tMessage) == MSG_TYPE_QUIT) | |
{ | |
O_exit(); | |
} | |
} | |
} | |
} | |
void main(void) | |
{ | |
/* | |
record the current memory available so we | |
can detect memory leaks | |
*/ | |
size_t uMemory = O_heap_available(); | |
MyClass * pInstance = MyClass_create(5); | |
MyInterface * pInterfaceInstance = MyClass_asMyInterface(pInstance); | |
/* Method tests */ | |
assert(MyClass_getMyField(pInstance) == 5); | |
assert(MyInterface_myMethod(pInterfaceInstance, 3) == 8); | |
/* Memory leak test */ | |
MyClass_destroy(pInstance); | |
assert(O_heap_available() == uMemory); | |
/* Stick around so the VSTB does not exit and we know we ran everything */ | |
O_debug("OOOCode: Tests passed\n"); | |
Main_waitToExit(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MyClass.h" | |
#include "opentv.h" | |
struct _MyClass | |
{ | |
int nMyField; | |
}; | |
MyClass * MyClass_create(int nMyField) | |
{ | |
MyClass * pThis = O_malloc(sizeof(MyClass)); | |
pThis->nMyField = nMyField; | |
return pThis; | |
} | |
void MyClass_destroy(MyClass * pThis) | |
{ | |
O_free(pThis); | |
} | |
int MyClass_getMyField(MyClass * pThis) | |
{ | |
return pThis->myField; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MyClass_H | |
#define MyClass_H | |
typedef struct _MyClass MyClass; | |
extern MyClass * MyClass_create(int nMyField); | |
extern void MyClass_destroy(MyClass * pThis); | |
extern int MyClass_getMyField(MyClass * pThis); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "MyClass.h" | |
#include "opentv.h" | |
struct _MyClass | |
{ | |
/* Need a field to store the interface instance */ | |
MyInterface * pMyInterface; | |
int nMyField; | |
}; | |
/* | |
private implementation of a MyInterface_MyMethod method - we keep | |
the void pointer parameter so that we don't have to cast the method | |
when passing it into the interface constructor. Doing so could hide nasty | |
type errors further down the road. | |
*/ | |
static int MyClass_myMethod(void * pInstance, int nArgument) | |
{ | |
/* | |
this #define is an optimisation that I use instead | |
of adding a local variable to the stack. It's pretty | |
optional but I worry about this sort of thing when | |
running code on low horsepower set top boxes | |
*/ | |
#define pThis ((MyClass *) pInstance) | |
/* ooh, look - that's what myMethod is for ;) */ | |
return pThis->nMyField + nArgument; | |
/* | |
let's not forget to undef pThis we may want to use | |
that name a lot in other methods ;) | |
*/ | |
#undef pThis | |
} | |
MyClass * MyClass_create(int nMyField) | |
{ | |
MyClass * pThis = O_malloc(sizeof(MyClass)); | |
/* Construct an interface instance */ | |
pThis->pMyInterface = MyInterface_create(pThis, MyClass_myMethod); | |
pThis->nMyField = nMyField; | |
return pThis; | |
} | |
void MyClass_destroy(MyClass * pThis) | |
{ | |
/* don't forget to destroy the interface instance */ | |
MyInterface_destroy(pThis->pMyInterface); | |
O_free(pThis); | |
} | |
int MyClass_getMyField(MyClass * pThis) | |
{ | |
return pThis->nMyField; | |
} | |
/* Casting convention implementation */ | |
MyInterface * MyClass_asMyInterface(MyClass * pThis) | |
{ | |
return pThis->pMyInterface; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MyClass_H | |
#define MyClass_H | |
/* Need to include the interface header */ | |
#include "MyInterface.h" | |
typedef struct _MyClass MyClass; | |
extern MyClass * MyClass_create(int nMyField); | |
extern void MyClass_destroy(MyClass * pThis); | |
extern int MyClass_getMyField(MyClass * pThis); | |
/* New method to "cast" MyClass to MyInterface */ | |
extern MyInterface * MyClass_asMyInterface(MyClass * pThis); | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MyInterface_H | |
#define MyInterface_H | |
#include "opentv.h" | |
/* | |
Prototype a method signature to be implemented for | |
this interface. Allows the compiler to spot errors | |
but can't get round the void pointer for the instance | |
*/ | |
typedef int (* MyInterface_MyMethod)(void * pInstance, int nArgument); | |
/* Interface structure (vtable?) */ | |
typedef struct | |
{ | |
void * pInstance; | |
MyInterface_MyMethod cbMyMethod; | |
} | |
MyInterface; | |
/* | |
Interface constructor. I use static inline for all | |
interface methods so that they compile out much like | |
preprocessor stuff but also the compiler will help me | |
with type checking, etc | |
*/ | |
static inline MyInterface * MyInterface_create(void * pInstance, MyInterface_MyMethod cbMyMethod) | |
{ | |
MyInterface * pThis = O_malloc(sizeof(MyInterface)); | |
pThis->pInstance = pInstance; | |
pThis->cbMyMethod = cbMyMethod; | |
return pThis; | |
} | |
/* Interface destructor */ | |
static inline void MyInterface_destroy(MyInterface * pThis) | |
{ | |
O_free(pThis); | |
} | |
/* | |
This method allows the implementation of MyInterface_MyMethod | |
to be called thus facilitating polymorphism which is our end goal | |
*/ | |
static inline int MyInterface_myMethod(MyInterface * pThis, int nArgument) | |
{ | |
return pThis->cbMyMethod(pThis->pInstance, nArgument); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment