Monday, November 10, 2008

Static linkage notes

When you statically link to the VCF, you won't automatically pick up the resource images and default ICO for the windows. You can fix by adding the ApplicationKit.res file, which does get built for you, to your link step. In VC6, go to the Link tab of your project's settings, and add the ApplicationKit.res like so:

$(VCF_ROOT)/lib/ApplicationKit.res

This will fix it so you get access to resources for the ApplicationKit.

Thursday, May 1, 2008

Working with Delegates in Visual Form Files

So you've got your interface put together via your Visual Form File resource. Now you want to hook up some event handlers or callbacks in your application code to the UI. No problem!

The first thing you need to to is write the code. Let's start off by using our application class as a place to put the callbacks. Later on we'll investigate using the main window class as well, but for now, lets look at our app class:


class LOLCatsApp : public Application {
public:

};


OK let's put in some code to handle a button click. The command button class has a delegate that takes a function with one parameter, a ButtonEvent* and returns nothing (void). Since ButtonEvent derives from Event, and in this case we really don't care much about the event per se, we can "cheat" a bit and simply write a function that takes a generic Event*.


class LOLCatsApp : public Application {
public:
void myCallBack( Event* ) {
Dialog::showMessage( "Hello there!" );
}
};


Now we've defined our callback. Let's add it to the application for later retrieval:


class LOLCatsApp : public Application {
public:
LOLCatsApp( int argc, char** argv ) :
Application(argc, argv) {
addCallback( new ClassProcedure1<Event*,LOLCatsApp>(this, &LOLCatsApp::myCallBack), "LOLCatsApp::myCallBack" );
}

void myCallBack( Event* ) {
Dialog::showMessage( "Hello there!" );
}
};


An application is component, and therefore can have 0 or more callbacks. So we call the app's addCallback() method and create a link to our callback function making sure to give a correct name.

At this point, we've defined/implemented a callback function, and added it to the list of callbacks the application maintains and that can be retreived by others via a call to the app's getCallback() function. All we have left is to hook the application's callback to the component in our VFF definition.

Like properties, a component can expose the delegates it has via the VCF's RTTI macros. This allows you to access them in the vff definition. The rule for this is that each object block, i.e.

object MyObj : MyClass

end


has an option delegates section, defined like so:

object MyObj : MyClass
delegates
end
end


Within this block, you can reference the delegates of the component and then assign an array of callbacks to the delegate. Each callback in the array will be added to the delegate. In other words:

object MyObj : MyClass
delegates
MyDelegate = [SomeComponentName@SomeComponentClass::SomeCallBackFunction]
end
end

Each item in the array of callbacks has the following format: the name of a valid component instance, the "@" character, and the name of the callback. Technically the name of the callback can be anything you want, however the convention is to use fully qualified C++ names, so that's usually the name of the component instance's class, the "::" qualifier, and the name of the method.

The component referenced can be any component in the VFF definition, or it can be the name of the app class. By default, the name of the app is it's class name *unless* you explicitly change it before you load up your form(s).

Armed with this information, lets add our callback to a button:

object myBtn : VCF::CommandButton
caption = 'Click Me'
delegates
ButtonClicked = [LOLCatsApp@LOLCatsApp::myCallBack]
end
end


When the form is loaded the framework will look at the myBtn instance, get access to it's ButtonClicked delegate and the callback named "LOLCatsApp::myCallBack" in the LOLCatsApp instance, and then add the callback to the delegate. At that point everything is "wired" together - when you click the button, the LOLCatsApp::myCallBack code will be invoked!

One question might be how to know what delegates are available. You can always browse the code, but that may nor may not immediately tell you that the delegate is exposed via the RTTI macros. Another way is use the new ClassRegistry Browser ( ClassRegistryBrowser.zip ). This is a graphical program that shows all the registered classes in the VCF's ClassRegistry. A class must be registered in the ClassRegistry for it to available for reference in a VFF definition. When you select a class, the program then iterates through all of the properties and delegates of the class. Something a bit like this:



Using this tool you can definitively determine what delegates are available and can be safely referenced in your VFF definition.

Now, let's make a change and instead of using our app class, lets use our window class to hold our callback. Let's add the code to our class first:


class LOLCatsWindow : public Window {
public:
LOLCatsWindow();

virtual ~LOLCatsWindow(){};

void myCallBack( Event* ) {
Dialog::showMessage( "Hello there!" );
}

};


Add our callback:

class LOLCatsWindow : public Window {
public:
LOLCatsWindow() {
addCallback( new ClassProcedure1<Event*,LOLCatsWindow>(this, &LOLCatsWindow::myCallBack), "LOLCatsWindow::myCallBack" );

}

virtual ~LOLCatsWindow(){};

void myCallBack( Event* ) {
Dialog::showMessage( "Hello there!" );
}

};


And then wire it up in the VFF:

object LOLCats : VCF::Window
object myBtn : VCF::CommandButton
caption = 'Click Me'
delegates
ButtonClicked = [LOLCats@LOLCatsWindow::myCallBack]
end
end
end


That's it! You've now got your window class handling a button click.

This same technique can be applied to any component that exposes delegates through the VCF's RTTI. For more examples you might want to look at the following:
vcf/examples/LOLCats
vcf/examples/ClassRegistryBrowser
vcf/examples/ListViews

Monday, April 14, 2008

Models, Views, and Items - a Saga for the Ages

In the recent past we had a tight coupling between a Model and an Item. The idea
was that an Item represented an individual "thing", or element of data, in the model. The implementation of the model worked out how to store the item (i.e. as
a std::vector<item*> for example). This meant that the model had to store a collection of Items, regardless of what theses items stood for, and the design of the Item meant that it stored all sorts of UI information that meant nothing to the model, such as the item's state, color, font, etc. So what happened is that the Item class ended up storing all sorts of data, some of which was relevant to the item's UI and some relevant to the model. This made it more difficult than necessary to make general purpose models.

So, I'm proposing breaking the direct connection of having a model store Items. Instead the model *only* stores data, which is really as it should be. The collection of Items, if appropriate, is maintained instead by the View/Control. Thus the Item becomes a "bridge" between the Model and the control, and is used by the control/view to help "compartmentalize" the drawing process and allow for things like custom item rendering. You could even think of the Item as a sort of "mini" View.

The model will allow for data access by using the VariantData class. Obviously we could use templates for this, but that has it's own issues. I think, in this case, it's easier to understand and to deal with using VariantData classes. Remembering that the public interface, common to a specific type of model (for example, a list model) would use VariantData types for it's methods, but the actual storage could be accomplished however you want. The default storage implementation might be, for a list model, an array of VariantData, but a custom design could certainly use something else, so long as methods are implemented correctly.

The Model class has a generic method for getting
and setting data that allows you to get or set an element of data using a VariantData class to hold the data, and also to specify an optional "key" using a VariantData class to hold the key information. So, if you had a model that represented an array of doubles, then the "key" might be an integer that indicated the index to use to set or get an element from the array, while the result of the "get" or the data for the "set", a double value, would be stored in the VariantData instance. All of this would be done using the generic get and set methods of the Model class. Of course you could provide your own more specific set of methods on your concrete model class. For example, the ListModel provides a set of methods for getting and setting values in a collection of data. It also implements the generic Model get/set methods - you can use either one, it's up to you.

So, to reiterate: a Model stores data, an Item stores visual information and serves as a bridge between the control and model. An Item does NOT store data relevant to the model. An Item may have methods that allow you to retrieve data from the model, but they are simply convience methods, you achieve the same thing by calling the appropriate methods on the specific model class.

Lets look at some changes to the base classes for MVC in the framework, specifically the Model and Item classes, and then move on to looking at some specific model types.

The Model class doesn't change a great deal. It still has a collection of Views, and it still has delegates that fire events. It does have several new methods for generically getting or setting data on the model.

class Model {
public:
virtual VariantData getValue( const VariantData& key=VariantData::null() );
virtual VariantData getValueAsString( const VariantData& key=VariantData::null() );

virtual void setValue( const VariantData& value, const VariantData& key=VariantData::null() );
virtual void setValueAsString( const String& value, const VariantData& key=VariantData::null() )
}

The exact implementation is up to the designer of the specific model class. The default
implementations do nothing or return VariantData objects that are set to NULL (the
VariantData's isNull() method will return true).

The Item class has a pointer to the model it's associated with. It has a pointer to the Control it's associated with. It stores data related to it's visual display, specifically, it holds a pointer to a font, display state mask that can hold various values, an image index, a void pointer for some application specific value, if need be, and a boolean value indicating whether or not it's selected. It has a virtual method that is used to indicate whether or not the item can paint itself, and also a virtual method for the actual paint() method.

The Item class is a base class, and there are specific sub classes of it for use by the various controls. For example, there's a ListItem for use in list like controls, a TreeItem for tree or hierarchical controls, a TableCellItem, and so forth.

An Item's lifetime is managed by the control it's associated with. An Item may or may not be created at the moment you make a change to the model. For example, if you have a header control, then for each element you add to the model, a new Item is created. This is OK, as headers rarely have a high number of elements to them (think of a control with more than 100 hundred header items - not very likely). However other controls, like a Tree Control, only create teh items when you need them. This saves enormously on memory since if you have a TreeModel with 1 million elements in it then creating 1 million corresponding TreeItem's doesn't make a whole lot of sense, especially since none of them will be needed right away. Moral of the story: don't cache Item's directly - store the key or index you used to retrieve them instead.




Some changes to specific models are a cleaned up interface, for example the ListModel now looks like this:


class ListModel : public Model {
void insert( const uint32 & index, const VariantData& item );
void add( const VariantData& item );
void remove( const uint32& index );
void set( const uint32& index, const VariantData& item );
virtual void setAsString( const uint32& index, const String& item );
virtual VariantData get( const uint32& index );
virtual String getAsString( const uint32& index );
virtual uint32 getIndexOf( const VariantData& item );
virtual bool getItems( std::vector& items );
virtual Enumerator* getItems();
virtual bool getRange( const uint32& start, const uint32& end, std::vector& items );
virtual uint32 getCount();
}

The functions that you have to implement are for read only support are:

virtual VariantData get( const uint32& index );
virtual uint32 getIndexOf( const VariantData& item );
virtual bool getItems( std::vector& items );
virtual Enumerator* getItems();
virtual bool getRange( const uint32& start, const uint32& end, std::vector& items );
virtual uint32 getCount();

These are fairly self explanatory.

The functions that modify the model, specifically:

void insert( const uint32 & index, const VariantData& item );
void add( const VariantData& item );
void remove( const uint32& index );
void set( const uint32& index, const VariantData& item );

are a little more involved. They are not virtual. Instead they call virtual methods that by default are no ops, and are intended to do the actual work of modifying the underlying collection or data store (whatever that might be). If these methods return a true value, then the non virtual modifier method do the work of ensuring that events are fired on the model's correct delegate(s). This makes is simpler on the implementer, and they don't have to worry about writing a lot of boiler plate code.

The virtual methods for modifying the model are:

virtual bool doInsert( const uint32 & index, const VariantData& item );
virtual bool doRemove( const uint32& index );
virtual bool doSet( const uint32& index, const VariantData& item );

When you call ListModel::insert(), it calls doInsert() to perform the actual data insertion on the collection, and then fires the appropriate events. Likewise, set() calls doSet(), and so forth.

The ListModel has support for adding/removing/getting sub items, and these methods work in a similar fashion as the previous functions. One note: sub items are zero indexed, so if you have a list model with an element at index 0, and it has 2 sub items, then the sub item indices would be 0 and 1, and you could access them by calling ListModel::getSubItem(0,0) and ListModel::getSubItem(0,1).


The list control's have been modified (or are in the process of being modified) to use a common ListControl base class. This provides a common set of functionality for dealing with a list of items and displaying them to the user. Controls that derive from this are the ListViewControl, ListBoxControl, and DropDownControl. The ListControl handles events from the ListModel and deals with creating or removing ListItems accordingly. The class looks something like this (only listing methods dealing with Items):

class ListControl {
ListModel* getListModel();
void setListModel(ListModel * model);
ListItem* addItem( const String& caption, const uint32 imageIndex=0 );
ListItem* insertItem( const uint32& index, const String& caption, const uint32 imageIndex=0 );
bool itemExists( const uint32& index );
ListItem* getItem( const uint32& index );
void setItem( const uint32& index, ListItem* item );
void selectItem( const uint32& index );
Enumerator* getSelectedItems();
uint32 getFocusedItem();
uint32 getSelectedItem();
uint32 hitTest( const Point& point );
};

Note that these methods are simply meant as shortcuts to using the list model methods for adding/removing elements. Under the hood the list model ends up getting called. With these methods you're limited to the kind of data that you can store since the caption is simply passed to the list model as a string. If the caption is the string "Hello" and your list model is implemented to expect numbers then the data that gets entered into it will be incorrect.

You can add, insert, or remove items, as well as get or set a specific item. Adding/removing items is fairly straight forward. You add an item by specifying a caption and optional image index, and you're returned a ListItem instance.

You can test for the presence of a ListItem by calling itemExists(), which will return true if there is an ListItem at the specified index.

You can change an existing ListItem to something completely different (for example, perhaps you have a custom ListItem that you want to use instead of the default) by calling the setItem, passing in an index and a valid instance. The old ListItem will be deleted and the new one put in it's place. If the new item doesn't have a component owner, then the list control will take over and you don't have to worry about the ownership (and cleanup) of the item.

These changes have been made to other model classes as well, including the TreeModel, the TableModel, the TextModel, and so on. Changes to the various controls to facilitate this have also been made, and the TreeControl and ListViewControl's underlying peer implementation has also changed quite a bit, making them alot more robust.

Monday, November 19, 2007

Busy, busy, busy

Well between work, soccer, and programming in my spare time, I haven't updated this in a while. So what's the latest scoop in VCF land? Well while the release isn't yet ready (yes I know, it's been a ridiculously long time between releases, but between personnel changes, and volunteer work on Zod's campaign...), there are some pretty cool things in the pipeline.

Most of the newly added threading code, such as thread methods/functions, thread pools, and the revamped Delegate classes have been added and incorporated into the rest of the VCF kits. We have added support for regular expressions, java script, and network classes back into the trunk (these were in the bluesky directory).

Coming next is advanced support for XML. Not just simple parsing anymore, as we already have that right now, but full blown support for XML including XPath and XSLT. Support for a TextReader interface is also present, as well as getting the full XML document tree. You can also use delegates to handle parsing notification ala SAX2. This is all based on the libxml and lilbxslt libraries from xmlsoft.org. Here are some quick and dirty examples:

SAX2 parsing notification:



void MystartElementSAXFunc2( const xmlChar * name,
const xmlChar ** atts)
{
printf( "@MystartElementSAXFunc2 name: %s\n", (const char*) name );

if ( NULL != atts ) {
const xmlChar** tmp = atts;
while ( *tmp != 0 ) {
printf( "attr: %s\n", (const char*)*tmp );
tmp ++;
}
}
}

#define testxml "<stuff a=\"1\" b=\"23\">"\
"Wow!"\
"<animal>Zebra</animal>"\
"<animal>Cow</animal>"\
"</stuff>"


int main( int argc, char** argv ){

FoundationKit::init( argc, argv );
XMLKit::init( argc, argv );

System::println( "XMLkit XML version: " + XMLKit::getXMLVersion() );
System::println( "XMLkit XSLT version: " + XMLKit::getXSLTVersion() );


{

XMLSaxParser p;
p.StartElement += MystartElementSAXFunc2;

p.parse( testxml );
}
}


A simple TextReader example:

int main( int argc, char** argv ){

FoundationKit::init( argc, argv );
XMLKit::init( argc, argv );
XMLTextReader rdr;
rdr.setXML( testxml );

System::println( "lang: " + rdr.getLang() );
System::println( "uri: " + rdr.getBaseURI() );
System::println( "ns: " + rdr.getNamespaceURI() );

while ( rdr.read() ) {
System::println( "Name: " + rdr.getName() +
" depth: " + rdr.getCurrentDepth() );
System::println( "Inner XML: { " + rdr.readInnerXml() + " }" );
}
}


While this happened the Internet kit got support for asynchronous url retrieval. Before you get get the contents of a URL, but it was blocking. Now a new class has been added so that you can get the contents in async mode. You can do things like this:


AsyncURL* url = new AsyncURL("http://www.w3schools.com/xpath/books.xml");

And in some other thread you can wait for the url to finish:

url->wait();
//do something with the URL contents.
delete url;


Or you can be notified via the delegate:



void urlCompleted( URLEvent* event )
{
URL* url = (URL*)event->getSource();

//do something with the url contents

url->free();
}

AsyncURL* url = new AsyncURL("http://www.w3schools.com/xpath/books.xml");
url->DataComplete += urlCompleted;
url->get();


Finally you can simply wait and block till it's done and extract the contents as a string:

AsyncURL url("http://www.w3schools.com/xpath/books.xml");
url.get();
url.wait();
String xml = url.getDataAsString();


You can create a xml document from the xml string:

AsyncURL url("http://www.w3schools.com/xpath/books.xml");
url.get();
url.wait();
String xml = url.getDataAsString();
XmlDocument doc;
doc.setXML(xml);


You can then iterate through the child nodes:

XmlNode root = doc.getRoot();
std::vector children;
root.getChildren( children );
std::vector::iterator cit = children.begin();
while ( cit != children.end() ) {
XmlNode& child = *cit;
System::println( "Name: " + child.getName() +
", path: " + child.getPath() );
++cit;
}


You can use XPath to perform queries:

std::vector nodes;
VariantData res = doc.matches( "/bookstore/book[1]", nodes );
System::println( "doc.matches() returned: " + res.toString() );

for (size_t i=0;i < nodes.size();i++ ) {
const XmlNode& n = nodes[i];
System::println( "Node name: " +
n.getName() + " path: " +
n.getPath() + " text: " +
n.getContent() );
}


The result may be a calculation:

std::vector nodes;
VariantData res = doc.matches( "sum(//price/text())", nodes );
System::println( "doc.matches() returned: " + res.toString() );
}


There's more as well, you can see the complete file here.

In addition to XML there's been some initial work done with creating a cryptography kit based on the OpenSSL library, providing support for most of the core sections of the library. Currently we have support for ciphers, hashes, ASN1, private/public keys, certificates (x509), base64 encoding/decoding, random numbers/data, Big Integers (what OpenSSL refers to as the BIGNUM struct), and IO. Now that those are wrapped up, I'm looking into the SSL side of things. What follows are some samples of the current code:

Hashes:


using namespace VCF::Crypto;

MD2 md2;
MD5 md5;
VCF::Crypto::SHA1 sha1;
VCF::Crypto::SHA sha;
DSS dss;
DSS1 dss1;
RipeMD160 rp160;
char mess1[] = "Test Message";
char mess2[] = "Hello World\n";
MessageDigest::DigestResult res =
md5.hash( (const unsigned char*)mess1, strlen(mess1) );

int i = 0;

printf("md5 Digest is (%d bytes): ", md5.size() );
for(i = 0; i < res.size(); i++) {
printf("%X", res[i]);
}
printf("\n");

Repeated as necessary for the other hashes.

Big integers are pretty simple to use:

BigInteger bi;
bi = 1;

BigInteger bi2 = -120;
int j = bi2;

bi = 1312;
bi2 *= bi;

String bs = bi2.toString();


Generate an RSA key pair and write it to disk:

RSAKeyPair kp;
kp.generate( 2048, RSAKeyPair::expRSA_F4 );
RSAPrivateKey privk = kp.getPrivateKey();
RSAPublicKey pubk = kp.getPublicKey();

privk.setPassword( PASSWORD );

DataEncryptionStandard3CBC des3cbc;
privk.setEncryptionCipher( &des3cbc );


FileOutputStream fos("test2-priv.pem");
fos.write( &privk );

fos.close();

fos.open( "test2-pub.pem" );
fos.write( &pubk );



You can read in the private key buy supplying a password:

RSAPrivateKey pk;
pk.setPassword( PASSWORD );
FileInputStream fis("test2-priv.pem");
fis.read( &pk );

or by using a calback function to supply the password string:

String gimmeThePassword()
{
return String(PASSWORD);
}


RSAPrivateKey pk;
pk.PasswordPrompt += gimmeThePassword;

FileInputStream fis("test2-priv.pem");
fis.read( &pk );

System::println( "RSAPrivateKey: \n" + pk );


X509 certificates can be generated

X509Certificate c;
Key k = c.generateRSA(512,0,365,2);
Key::KeyType t = k.getType();

or read in from an input stream:

FileInputStream fis("test509.cer");
PEMInputStream pis(&fis);

X509Certificate* c2 = pis.readCertificate("");
delete c2;


Obviously more work needs to be done here, but I think this is a good start. The next big thing is understanding how to make use of SSL and how to integrate that.

Finally there's been some progress on writing a ZIP input/output stream class to handle compression/decompression with ZLib. Not so much to post about on that so far.

Well at least everyone knows know I haven't completely thrown in the towel! :)

Saturday, May 19, 2007

ThreadPools in the VCF

So, the threaded methods post got me thinking: if we can create methods that execute in a thread, could we have something fancier such that a delegate's invoke() can take place asynchronously (much like the .Net design of a delegate's BeginInvoke() and EndInvoke())?

Part of the desire for this is to overcome a current weakness in the VCF's delegate design. Currently we can only accept function signatures of the type:

void MyFunction( Event* e );


A new design would allow us to have arbitrary function signatures, which makes it easier to use.

The first thing I wanted to address is making delegate's work with any kind of function signature instead of just limiting people to passing in a single. My major constraint was that I wanted it to work with version 6 of the Visual C++ compiler, which, while I know it's old now, alot of people still use it (myself included), and I wanted to have a stab at making things compatible with it. With that in mind here's a stab at it:


class CallBack {
public:
virtual ~CallBack(){}

String name;
};



class delegate {
public:

~delegate() {
clear();
}

bool empty() const {
return functions.empty();
}

size_t size() const {
return functions.size();
}


void clear() {
std::vector<CallBack*>::iterator it = functions.begin();
while ( it != functions.end() ) {
delete *it;
++it;
}

functions.clear();
}


void add( CallBack* callback ) {
std::vector<CallBack*>::iterator found =
std::find( functions.begin(), functions.end(), callback );

if ( found == functions.end() ) {
functions.push_back( callback );
}
}

void remove( CallBack* callback ) {
std::vector<CallBack*>::iterator found =
std::find( functions.begin(), functions.end(), callback );

if ( found != functions.end() ) {
functions.erase( found );
}
}

std::vector<CallBack*> functions;
};

This is a base class for our delegate, it handle adding/removing our callbacks. The callback is started be defining a base class for a callback method. It has a single member, a string with the name of the callback method (or some name). This lets us store a generic base pointer to the callbacks. The delegate holds N number of callbacks, and a callback is some specific class that wraps a function pointer of some sort. The specific class of the delegate will then invoke all of it's function callbacks.

Now what we want is the ability to specify the function signature, something like you find on other signal/slot libraries. This means we need to use templates, with definitions for each number of template arguments, i.e. a specific delegate class for function that have 2 arguments, one for no arguments, and so forth. In addition, we need to distinguish between functions that return a value, and functions that don't. Hearkening back to my ObjectPascal days, I'll refer to functions that have no return value as Procedures and functions that do have a return value as Functions. Not only do we need to distinguish between return or no return values, thanks to various quirks in C++, we also need to distinguish between whether the function pointer that we wrap is a static function

void MyFunction( int i, double d );

or a class function (a method, or member function of a class)

void MyClass::MyFunction( int i, double d );


So let's look at an attempt to define a function that 1 argument, and no return type.


template <typename ParamType1>
class NullClassType1 {
public:
void m(ParamType1){}
void m(Thread*, ParamType1){}
};


template
<typename P1>

class
Procedure1 : public CallBack {
public
:
typedef
void (*FuncPtr)(P1);


Procedure1():staticFuncPtr(NULL){}

Procedure1(FuncPtr funcPtr):staticFuncPtr(funcPtr){}



virtual
void invoke( P1 p1 ) {
if
( NULL != staticFuncPtr ) {
(*
staticFuncPtr)( p1 );
}
}


FuncPtr staticFuncPtr;
};



template
<typename P1, typename ClassType=NullClassType1<P1> >

class
ClassProcedure1 : public Procedure1<P1> {
public
:
typedef
void (ClassType::*ClassFuncPtr)(P1);


ClassProcedure1():Procedure1<P1>(),classFuncPtr(NULL),funcSrc(NULL){}


ClassProcedure1(ClassType* src, ClassFuncPtr funcPtr):Procedure1<P1>(),classFuncPtr(funcPtr),funcSrc(src){}

ClassProcedure1(ClassType* src, ClassFuncPtr funcPtr, const String& s):

Procedure1<P1>(),classFuncPtr(funcPtr),funcSrc(src){
name = s;
}




virtual
void invoke( P1 p1 ) {
if
( NULL != classFuncPtr && NULL != funcSrc ) {
(
funcSrc->*classFuncPtr)( p1 );
}
}


ClassFuncPtr classFuncPtr;
ClassType* funcSrc;
};


The above code declares two main classes. The first works as a wrapper around procedures (or functions that return no value/void). It has one method used to invoke the function pointer the class wraps. The method is declared as virtual so that in can be overridden in a subclass.

The next class provides a wrapper around a class function, and re-implements the virtual invoke method of it's parent class. This let's us have a base pointer which can be used for either type of function pointer, and makes the delegate implementation easier to handle because now it can handle either type of function wrapper seamlessly.

So, we have functions wrapped up, lets look at our delegate class:


template
<typename P1>

class
Delagate1 : public delegate {
public
:
typedef
void (*FuncPtr)(P1);
typedef
Procedure1<P1> CallbackType;

Delagate1<P1>& operator+= ( FuncPtr rhs ) {
CallbackType* cb = new CallbackType(rhs);

add( cb );
return
*this;
}


Delagate1<P1>& operator+= ( CallBack* rhs ) {
add( rhs );

return
*this;
}



void
invoke( P1 p1 ) {

std::vector<CallBack*>::iterator it = functions.begin();
while
( it != functions.end() ) {

CallBack* cb = *it;
CallbackType* callBack = (CallbackType*)cb;

callBack->invoke( p1 );

++
it;
}
}
};


The main features of the delegate class are that it lets us add functions in two ways: by a direct function pointer, or by as class instance of a callback. The first method let's us write code like this:

void MyCallback( int i )
{


printf( "Hello from MyCallback. i = %d\n", i );
}



Delagate1<int> d1;

d1 += MyCallback;

The other way we can add callbacks, especially callbacks that wrap a class function/method, is like so:

class Snarfy {

public
:
void
thisBlows( int g ) {
printf( "Hello from thisBlows! i: %d, this ptr: %p\n", g, this );
}
};


Snarfy sn;

Delagate1<int> d2;
d2 += new ClassProcedure1<int,Snarfy>(&sn,&Snarfy::thisBlows,"Snarfy::thisBlows");

Previously we wanted to have callbacks as a general class, something that we could identify by name, without having to know the specific class type. However we still need to invoke the callback methods. Because our delegate class has the same function signature template types, we can safely cast the generic callback type to the right template function class type. You can see this occur in the implementation of the delegate's invoke() method. Because we made the function class's invoke method virtual, the correct method will be called for either type, static or class function.

Now we have delegates and callbacks, that can be invoked like so:
d2.invoke( 100 );

A fancier implementation allows us to have delegates that take functions that return values, like this example:
bool funcWithReturnVal( const String& str, double d )
{


bool
result = true;
printf( "duhDoIt() %s, %0.5f, returning %d\n", str.ansi_c_str(), d, result );

return
result;
}


Delagate2R<bool,const String&,double> d3;

d3 += funcWithReturnVal;

bool
result = d3.invoke("Hola", 120.456);

This returns the result of the last callback that was invoked in the delegate's list of callbacks. We can get all the results that were returned like so:

for ( int i=0;i<d3.results.size();i++ ) {

printf( "d2 results[%d]: %d\n", i, (int)d3.results[i] );
}


Now we have delegates reasonably defined, and they should work on most compilers, VC6 or better, GCC, Borland, et al. Now lets look at async delegate invocation.

To fire off the callbacks asynchronously

Next was to try and implement a specific type


Thanks to the site http://www.bedaux.net/cpp2html/ for C++ to HTML formatting.

Wednesday, May 2, 2007

Visual Form File format

XAML this, XAML that, blah, blah, blah. I get so sick of hearing about how great XAML is, as if this were the most mind altering, earth shaking technology to hit the streets in years. Bah Humbug!

We've had something like this for years in the VCF! And the predecessor to XAML dates back even further than that, to Delphi's form files, NeXT's NIB files, and so on. So, I thought I'd post what the format for a Visual Form File (VFF) looks like, in Backus-Naur format:


component-decl ::= "object" component-id component-properties
*(component-decl) [component-delegates] "end"
component-id ::= component-name component-class ["," component-classid]

component-name ::= id
id ::= ALPHA *(ALPHA | DIGIT | '_' )
component-class ::= ALPHA *(ALPHA | DIGIT | '_' | "::" )
component-classid ::= ''' 1*(ALPHA | DIGIT | '-' ) '''

component-properties ::= 1*component-property
component-property ::= property-name '=' property-value
property-name ::= id | property-object-name | property-collection-name
property-object-name ::= id '.' property-name
property-collection-name ::= id '[' property-collection-key ']'
property-collection-key ::= property-number | property-string
property-value ::= property-string | property-number |
property-component-ref | property-enum |
property-enum-mask | property-binary | property-bool


property-string ::= ''' *(ALPHA | DIGIT | 'any printable unicode char' ) '''
property-number ::= 1*DIGIT ['.' 1*(DIGIT) ]
property-component-ref ::= ('@' component-name) | "null"
property-enum ::= id
property-enum-mask ::= '[' property-enum *[',' property-enum] ']'
property-binary ::= '{' binary-data '}'
binary-data ::= 1*(binary-byte)
binary-byte ::= (DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' )
(DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' )
property-bool ::= "true" | "false"

component-delegates ::= "delegates" *(component-delegate-decl) "end"
component-delegate-decl ::= delegate-name '=' delegate-array
delegate-name ::= id
delegate-array ::= '[' 1*(event-handler-ref) ']'
event-handler-ref ::= component-instance '@' component-callback-method
component-instance ::= id
component-callback-method ::= component-classname "::" component-methodname
component-classname ::= id
component-methodname ::= id


A simple example:

object window1 : VCF::Window
top = 500
left = 500
width = 400
height = 300
end

Note that the class name must be a fully qualified C++ class name, including the namespace the class belongs to.

A more complex example might look like this:

object Form1 : Window, 'ED88C0A1-26AB-11d4-B539-00C04F0196DA'
alignment = AlignNone
anchor = 0
bottom = 555.00000
color.blue = 0.78431
color.green = 0.81569
color.red = 0.83137
height = 537.00000
left = 234.00000
name = 'Form1'
top = 70.00000
visible = true
width = 565.00000

object label1 : VCF::Label, 'ED88C09F-26AB-11d4-B539-00C04F0196DA'
anchor = [AnchorLeft,AnchorRight]
bottom = 100.00000
caption = 'This is a label!'
color.blue = 0.50000
color.green = 1.00000
color.red = 0.00000
height = 45.00000
left = 20.00000
name = 'label1'
textAlignment = taTextLeft
top = 55.00000
verticalAlignment = tvaTextCenter
visible = true
width = 300.00000
wordWrap = false

delegates
end
end

delegates
end

end

This is what we use to load up components dynamically at runtime. So a form can be stored in format, and then loaded at runtime, dynamically no less (!), like so:


Window* window = Frame::createWindow( classid(VisualFormFilesWindow) );


So no one thinks we're using some new fangled version of C++, "classid" is simply a macro that gets the VCF Class instance from a given C++ class type.

When you call Frame::createWindow(), you get a new instance of your window class (called VisualFormFilesWindow), with all the controls and components as you've defined them in your VFF file! Voila!

There's more information on the VFF format here:
Visual Form File format

Something to note - in the latest version, we now support collection properties that can be specified via the RTTI macros, and can also be modified via the VFF format, for example:

object myObj : MyObjectWithItems
items[0] = 10
items[1] = 123
end

Thursday, April 26, 2007

Threaded Functions

Here's an interesting thought experiment for functions that get executed in a separate thread.


void doit( int i ) {
printf( "Hello from doit! i: %d\n", i );
}




void doit2( Thread* th, int i ) {
printf( "Hello from doit2! i: %d, th: %p, tid: 0x%04x \n", i, th, th->getThreadID() );

}

class Snarfy {
public:
void thisBlows( int g ) {
printf( "Hello from thisBlows! i: %d, this ptr: %p\n", g, this );
}
};


class Swanky {
public:
void doit( double& d, const String& s ) {
printf( "Hello from Swanky::doit! d: %0.3f, s: %s, this ptr: %p\n",
d, s.ansi_c_str(), this );
}


void doit2( Thread* th, double& d, const String& s ) {
printf( "Hello from Swanky::doit! d: %0.3f, s: %s, this ptr: %p\n",
d, s.ansi_c_str(), this );

for (int i=0;i<10;i++){
th->sleep(1000);
}
}
};

int main( int argc, char** argv ){

FoundationKit::init( argc, argv );



Thread* th = ThreadedProcedure1<int>(10,doit);

th->wait();

th = ThreadedProcedure1<int>(231,doit2);

th->wait();


Snarfy sn;

th = ThreadedProcedure1<int,Snarfy >(&sn,38112,&Snarfy::thisBlows);
th->wait();



String s = "hello";
Swanky sk;

double d = 0.0332;

th = ThreadedProcedure2< double&,const String&, Swanky >(&sk,d,s,&Swanky::doit2);
th->wait();


printf( "Bye!\n");

FoundationKit::terminate();
return 0;
}


The actual implementation gets a bit long winded, but looks something like this:




template <typename ParamType1>
class NullClassType1 {
public:
void m(ParamType1){}
void m(Thread*, ParamType1){}
};


template <typename ParamType1, typename ClassType=NullClassType1<ParamType1> >
class ThreadedProcedure1: public Runnable {
public:

typedef NullClassType1<ParamType1> NullClassType;

typedef void (*ProcPtr1)(ParamType1 p1);
typedef void (*ProcThreadPtr1)(Thread* thread, ParamType1 p1);

typedef void (ClassType::*ClassProcPtr1)( ParamType1 p1 );
typedef void (ClassType::*ClassThreadProcPtr1)( Thread* thread, ParamType1 p1 );



ThreadedProcedure1( ParamType1 p1, ProcPtr1 procPtr ): param1_(p1),
runningThread_(NULL),
procPtr_(NULL),
procThreadPtr_(NULL),
classProcPtr_(NULL),
classThreadProcPtr_(NULL),
instancePtr_(NULL){

ThreadedProcedure1<ParamType1,ClassType>* params =
new ThreadedProcedure1<ParamType1,ClassType>(p1);

params->procPtr_ = procPtr;

runningThread_ = new Thread( params, true, true );
params->runningThread_ = runningThread_;

runningThread_->start();
}

ThreadedProcedure1( ParamType1 p1, ProcThreadPtr1 procPtr ): param1_(p1),
runningThread_(NULL),
procPtr_(NULL),
procThreadPtr_(NULL),
classProcPtr_(NULL),
classThreadProcPtr_(NULL),
instancePtr_(NULL){

ThreadedProcedure1<ParamType1,ClassType>* params =
new ThreadedProcedure1<ParamType1,ClassType>(p1);

params->procThreadPtr_ = procPtr;

runningThread_ = new Thread( params, true, true );
params->runningThread_ = runningThread_;

runningThread_->start();
}

ThreadedProcedure1( ClassType* src, ParamType1 p1, ClassProcPtr1 procPtr ): param1_(p1),
runningThread_(NULL),
procPtr_(NULL),
procThreadPtr_(NULL),
classProcPtr_(NULL),
classThreadProcPtr_(NULL),
instancePtr_(NULL) {

ThreadedProcedure1<ParamType1,ClassType>* params =
new ThreadedProcedure1<ParamType1,ClassType>(p1);

params->classProcPtr_ = procPtr;
params->instancePtr_ = src;

runningThread_ = new Thread( params, true, true );
params->runningThread_ = runningThread_;

runningThread_->start();
}


ThreadedProcedure1( ClassType* src, ParamType1 p1, ClassThreadProcPtr1 procPtr ): param1_(p1),
runningThread_(NULL),
procPtr_(NULL),
procThreadPtr_(NULL),
classProcPtr_(NULL),
classThreadProcPtr_(NULL),
instancePtr_(NULL){

ThreadedProcedure1<ParamType1,ClassType>* params =
new ThreadedProcedure1<ParamType1,ClassType>(p1);

params->classThreadProcPtr_ = procPtr;
params->instancePtr_ = src;

runningThread_ = new Thread( params, true, true );
params->runningThread_ = runningThread_;

runningThread_->start();
}







protected:

ThreadedProcedure1( ParamType1 p1 ): param1_(p1),
runningThread_(NULL),
procPtr_(NULL),
procThreadPtr_(NULL),
classProcPtr_(NULL),
classThreadProcPtr_(NULL),
instancePtr_(NULL){
}

public:
virtual bool run() {


if ( typeid(ClassType) == typeid(NullClassType) ) {
if ( NULL != procThreadPtr_ ) {
(*procThreadPtr_)( runningThread_, param1_ );
}
else if ( NULL != procPtr_ ) {
(*procPtr_)( param1_ );
}
else {
return false;
}
}
else {
if ( NULL != instancePtr_ ) {
if ( NULL != classThreadProcPtr_ ) {
(instancePtr_->*classThreadProcPtr_)( runningThread_, param1_ );
}
else if ( NULL != classProcPtr_ ) {
(instancePtr_->*classProcPtr_)( param1_ );
}
else {
return false;
}

}
}


return true;
}

virtual void stop(){}


operator Thread* () {
return runningThread_;
}
protected:

ParamType1 param1_;
Thread* runningThread_;
ProcPtr1 procPtr_;
ProcThreadPtr1 procThreadPtr_;
ClassProcPtr1 classProcPtr_;
ClassThreadProcPtr1 classThreadProcPtr_;
ClassType* instancePtr_;
};





This allows us to attach a function and execute it in a separate thread, using the various VCF thread classes, such as VCF::Thread and VCF::Runnable to implement it. I'll leave it as an exercise for the reader to add additional arguments. If people like this enough we'll probably put this into the FoundationKit proper.