Friday, April 22, 2011

Object Oriented C ( MACRO!!! Oh no )

Well I took a break from the platformer I'm working on and decided to play around with c language and try to do some macro hacking. :D  I've done oop c stuff in the past using a method like this.

Example of oop c

#include <stdio.h>
#include <stdlib.h>


typedef struct {
    int i;
} Test;

Test* test_newTest() {
    Test* temp = malloc(sizeof(Test));
    return temp;
}

void test_deleteTest(Test* t) {
    free(t);   
}

void test_setI(Test* this, int i) {
    this->i = i;
}

int test_getI(Test* this) {
    return this->i;
}

void test_print(Test* this) {
    printf("%d\n", this->i);
}

int main() {
    Test* t = test_newTest();
   
    test_setI(t, 20);
   
    test_print(t);
   
    test_deleteTest(t);
   
    return 0;
}

As you can see its a great way to modulize your c code.  But there is a problem with this.  And the problem is reusability of code and Most people come from a java, c# or some other scripting background that use traditional oop would go "um...what?" and be quite confused.  Then would say this "Hey that isn't oop noob" or something like that.  Meh, who care what any one else thinks to me this is quite modular.
 So after thinking for a while (and I was really board ) I did a little test project last night to see if I can add a little syntax sugar to that design.  And behold my simple hackish way to add oop sugar to the c lang.

// This is where the class sytax will be created
// This defines the class
#define CLASS(v) typedef struct { v }
// This is the definision of a method
#define METHOD(class, name) class##_##name(class* this
// These 2 will start and end parameter setting
#define START ,
#define END )
// This calls a method
#define CALL(inst, class, name) class##_##name(inst
// These are wrappers for the constructor and destructor
// These need to be implemented
#define CONSTRUCT(class)     void METHOD(class, create)
#define DESTRUCT(class)        void METHOD(class, release) END

#define NEW(class, inst)         inst = (class*)malloc(sizeof(class)); CALL(inst, class, create)
#define DELETE(class, inst)        CALL(inst, class, release) END; free(inst)

I wonder what you expression is at the moment.  If you can interpret this code your mouth is probably dropped of your face because I'm using some really sick looking macro and post some like "Evil!!!"  and I'll simple go "mhahahahahaha just as planned!!!".  Oh well I better explain what going on.

CLASS(v) - This defines your class name,  the sytax for it is really quite simple for class definision.

CLASS(int x; int y;) Vec2;

Thats pretty much it for defining your class,  internal it simple typedef struct but that doesn't really matter now doesn't it. Inside the () this is where you define your attributes or fields.  To decare methods you will need to use the METHOD macro

METHOD(class, name) - This defind your classes methods, these can be any thing.  NOTE: Being to c isn't a full blow object oriented language you can't use all feature of oop like inheritance (just for now), polymorphism( I heard this is possible but haven't implemented yet), data hide level (public, protected, private).  In this simple implementation everything is public.

 Ok how to use this macro

void METHOD(Vec2, setX) START int x END; or {}
int METHOD(Vec2, getX) END; or {}

Quite simle and a lot more meaning full then then the first example.  START and END are used for parameters.  START is optional but END needs to be with it for internal reasons.

CALL(inst, class, name) - This call a method for our class.  inst is the class instance, class is the name of the class and name is the method name.  Like method it uses START and END for parameters like so.

CALL(t, Vec2, setX) START 20 END;
e = CALL(t, Vec2, getX) END;

Pretty simple so far. But there is more.

CONSTRUCT(class) - This is a special method declaration that is use when you are instanlizing a class. (more on that in a moment).  This means when you create an object this will be the first method created.  Just like METHOD you will use START and END for the parameter.

CONSTRUCT(Vec2) START int x, int y END;

And like wise there is also a destructor or in this test lib DESTRUCT(class) which is used when you are deallocating a class.  There is one major difference between CONSTRUCT and DESTRUCT and that is destruct doesn't need parameters.

DESTRUCT(Vec2);

Ok time for memory stuff...

NEW(class, inst) - This creates an instance of a class it doesn't return any thing though because it sets the variable.  Like everything else it take START and END parameters.

NEW(Vec2, v) START 10, 20 END;

and likewise DELETE will deallocate an object.  It also doesn't use the START or END because it doesn't take parameters.

DELETE(Vec2, v);

This is simply a wrapper of the first examples method of doing oop in c lang.  This isn't really complete because I have done more advance stuff with it yet like inheritance and polymorphism but will do it eventually oh well later.


Here is the example of c oop wrapping. NOTE: The example is for linux but it can compiled on any compiler because I'm not using any external library for this example.  And the oop wrapper is header only too so just create your own example to see how it works.

http://www.filehosting.org/file/details/221918/simpleobjexample.zip

No comments:

Post a Comment