Bringing more object orientation to C programming
Posted: Sun Apr 02, 2017 3:53 pm
I've started a project to bring more object style programming to plain C and Amiga, after I figured out how to use APICALL trick to add function calls to C struct's. I've made a oo.library (oo for object orientation) which contains all New...Object() and Dispose...Object() function calls to create objects based on internal classes of the library. All the rest is handled through the objects themselves. The classes will initialize all of the internal variables properly, all the allocations and freeing is done on your behalf, opening and closing everything is done for you. The oo.library opens and closes all necessary OS libraries and OS classes for you. The idea is coding is simplier, faster development, writing less code is needed and coding is safer for newbies and lazy programmers leading to more bug free software hopefully. The classes takes care of all the low level stuff on your behalf.
The base is Toolobj object/class. (I chose the name because Application library and Utility library exists already. But I don't think a Tool library exists.) The Toolobj object takes care of signal waiting and events handling calling your events handler functions. The tool object takes care of opening and closing a language catalog as well. And some more.
The window class contains a LoadGUI method to read a GUI definition from a file. I'm calling it GUI Markup Language, which follows Reaction programming directly. Or you can create a GUI creating the objects individually.
This whole project is far away from finished or anything useful and will require a lot of work.
Currently *partially* implemented classes are: Toolobj, Windowobj, Fileobj, Dirobj, Listobj, Nodeobj, Hookobj, Layout, Button, Stringgadget, Label, Networkobj, Clipobj (clipboard).
Examples:
The TestApp.gui file:
The base is Toolobj object/class. (I chose the name because Application library and Utility library exists already. But I don't think a Tool library exists.) The Toolobj object takes care of signal waiting and events handling calling your events handler functions. The tool object takes care of opening and closing a language catalog as well. And some more.
The window class contains a LoadGUI method to read a GUI definition from a file. I'm calling it GUI Markup Language, which follows Reaction programming directly. Or you can create a GUI creating the objects individually.
This whole project is far away from finished or anything useful and will require a lot of work.
Currently *partially* implemented classes are: Toolobj, Windowobj, Fileobj, Dirobj, Listobj, Nodeobj, Hookobj, Layout, Button, Stringgadget, Label, Networkobj, Clipobj (clipboard).
Examples:
Code: Select all
BOOL Quit=FALSE;
int32 HandleAppIconEvents(struct Hook *hook, WINDOWOBJ *winobj, uint32 value)
{
if (winobj!=NULL) { winobj->Uniconify(); }
} // HandleAppIconEvents
int32 HandleDockEvents(struct Hook *hook, WINDOWOBJ *winobj, uint32 value)
{
} // HandleDockEvents
int32 HandleMainWinEvents(struct Hook *hook, WINDOWOBJ *winobj, uint32 myclass)
{
uint16 mycode=(uint16)(uint32)hook->h_Data;
switch (myclass & WMHI_CLASSMASK)
{
case WMHI_CLOSEWINDOW: Quit=TRUE;
break;
case WMHI_ICONIFY: winobj->Iconify();
break;
case WMHI_UNICONIFY: winobj->Uniconify();
break;
case WMHI_GADGETUP:
switch (myclass & WMHI_GADGETMASK)
{
case 1:
printf("Gadget 1 clicked\n");
break;
case 2:
Quit=TRUE;
break;
}
break;
}
if (Quit) { return -1; } else { return 0; }
} // HandleMainWinEvents
int main(int argc, char **argv)
{
struct Library *OOBase=(struct Library *)IExec->OpenLibrary("oo.library",1);
if (OOBase!=NULL)
{
struct OOIFace *IOO=(struct OOIFace *)IExec->GetInterface(OOBase,"main",1,NULL);
if (IOO!=NULL)
{
if (argc==0) // Launched from Workbench
{ TOOLOBJ *tool=(TOOLOBJ *)IOO->NewToolObject("TestApp",TRUE,(struct WBStartup *)argv); }
else // Launched from CLI/Shell
{ TOOLOBJ *tool=(TOOLOBJ *)IOO->NewToolObject(argc[0],TRUE,NULL); }
if (tool!=NULL)
{
tool->AddAppEventHandler(HandleAppIconEvents);
BUTTON *but1=(BUTTON *)IOO->NewButtonGadgetObject(1,TRUE,tool->GetCatalogStr(1,"Ok"),FALSE);
BUTTON *but2=(BUTTON *)IOO->NewButtonGadgetObject(2,TRUE,tool->GetCatalogStr(2,"_Cancel"),FALSE);
if ((but1!=NULL) && (but2!=NULL))
{
LAYOUT *layout=(LAYOUT *)IOO->NewLayoutGadgetObject(0,LAYOUT_ORIENT_HORIZ);
if (layout!=NULL)
{
WINDOWOBJ *mainwin=(WINDOWOBJ *)IOO->NewWindowObject(tool,"main");
if (mainwin!=NULL)
{
mainwin->SetTitle("TestApp");
mainwin->SetIconName("ram:TestApp");
mainwin->EnableGadgets(TRUE,TRUE,TRUE,TRUE);
mainwin->EnableIconifyGadget(TRUE);
mainwin->SetWindowWidth(600);
mainwin->SetWindowHeight(300);
layout->AddObject(but1);
layout->AddObject(but2);
mainwin->SetLayout(layout); // An alternative way: mainwin->SetLayoutObject(layout->GetObject());
// object->GetObject() will return a memory pointer to Intuition's Object* type of class/image/gadget object
mainwin->Open();
tool->AddWindowEventHandler(mainwin,HandleMainWinEvents);
tool->Run(); // This one takes care of signal waiting and calling your HandleAppIconEvents() and HandleMainWinEvents() functions
// It's time to quit...
IOO->DisposeWindowObject(mainwin);
}
IOO->DisposeLayoutGadgetObject(layout);
}
IOO->DisposeButtonGadgetObject(but1);
IOO->DisposeButtonGadgetObject(but2);
}
IOO->DisposeToolObject(tool);
}
IExec->DropInterface((struct Interface *)IOO);
}
else printf("TestApp ERROR: Can't open oo main interface\n");
IExec->CloseLibrary(OOBase);
}
else printf("TestApp ERROR: Can't open oo.library v1\n");
}
Code: Select all
struct Library *OOBase=(struct Library *)IExec->OpenLibrary("oo.library",1);
if (OOBase!=NULL)
{
struct OOIFace *IOO=(struct OOIFace *)IExec->GetInterface(OOBase,"main",1,NULL);
if (IOO!=NULL)
{
TOOLOBJ *tool=(TOOLOBJ *)IOO->NewToolObject("TestApp",TRUE,(struct WBStartup *)argv);
if (tool!=NULL)
{
tool->AddAppEventHandler(HandleAppIconEvents);
WINDOWOBJ *mainwin=(WINDOWOBJ *)IOO->NewWindowObject(tool,"main");
if (mainwin!=NULL)
{
mainwin->SetTitle("TestApp");
mainwin->SetIconName("ram:TestApp");
mainwin->EnableGadgets(TRUE,TRUE,TRUE,TRUE);
mainwin->EnableIconifyGadget(TRUE);
mainwin->SetWindowWidth(600);
mainwin->SetWindowHeight(300);
mainLayout=mainwin->LoadGUI("TestApp.gui");
if (mainLayout!=NULL)
{
mainwin->Open();
tool->AddWindowEventHandler(mainwin,HandleMainWinEvents);
tool->Run();
// Time to quit...
}
else printf("TestApp ERROR: Couldn't load GUI ml\n");
IOO->DisposeWindowObject(mainwin);
}
}
}
IOO->DisposeToolObject(tool);
}
IExec->DropInterface((struct Interface *)IOO);
}
else printf("TestApp ERROR: Can't open oo main interface\n");
IExec->CloseLibrary(OOBase);
}
else printf("TestApp ERROR: Can't open oo.library v1\n");
Code: Select all
<?guiml version="1.0"?>
<!DOCTYPE GUI>
<layout orientation="horizontal">
<button id="1" label="Ok" catalogid="1" active="true" weightedwidth="100" weightedheight="0" />
<button id="2" label="_Cancel" catalogid="2" active="true" weightedwidth="100" weightedheight="0" />
<string id="3" active="true" maxchars="100" weightedwidth="0" weightedheight="0" />
</layout>