| 6.6.1. | Does the VCF support XML? |
|
Yes. See the VCF::XMLParser class. The XMLParser class can handle
basic xml files (it does not do any validation however). It can parse
xml from a file name, or from string of xml text. Once parsed you can
access the xml document as an enumeration of XMLNodes. Alternately you
can add event handlers to the XMLParser to get notified as it parses
the xml contents.
An example of this looks like this:
VCF::XMLParser parser;
VCF::FileInputStream fs("path/to/some/file.xml");
parser.parse( &fs );
VCF::Enumerator<VCF::XMLNode*>* nodes = parser.getParsedNodes();
while( nodes->hasMoreElements() ) {
XMLNode* node = nodes->nextElement();
if ( node->getName() == "foo" ) {
XMLAttr* barAttr = node->getAttrByName( "bar" );
String barVal = barAttr->getValue();
String nodeCDATA = node->getCDATA();
}
}
}
|
| 6.6.2. | What is the VCF::Interface good for? |
|
The VCF::Interface simply identifies a class as being an "interface". In
and of itself it has no functionality, other than to derve as a base
class for other interfaces.
|
| 6.6.3. | How do I create a new thread ? |
|
You can create a thread by deriving a new class from VCF::Thread,
and override the run() method. In your run() implementation you can
put whatever code you want to execute for your thread. To use the
class you just create a new instance of it, call VCF::Thread::start(),
and you're done. When your thread exits it's run() method, it will
delete itself. For more advanced usages, or to see how to further control
the Thread behaviour (such as prevent auto deletion), see the VCF::Thread
class documention.
A brief example looks like this:
bool canQuit = false;
class MyThread : public VCF::Thread {
public:
virtual bool run() {
int fooVal = 0;
while ( fooVal < 1000 ) {
fooVal ++;
int calcVal = fooVal * sin(0.1234) - cos(0.78 * fooVal/(fooVal*2.0));
}
canQuit = true;
return true;
}
};
int main( int argc, char** argv )
{
FoundationKit::init(argc,argv);
Thread* thread = new MyThread();
thread->start();
while ( !canQuit ) {
}
FoundationKit::terminate();
return 0;
}
|
| 6.6.4. | How about Mutexs, Semaphores, etc ? |
|
Creating a mutex is easy:
Mutex* m = new Mutex();
To lock the mutex, simple call the Mutex::lock() method. If the lock()
fails it will return false. To unlock the mutex call the unlock method.
For example:
Mutex* m = getMyMutex();
m->lock();
String s = "Hello!";
myVectorOfStrings.push_back( s );
m->unlock();
|
| 6.6.5. | Are the collections thread safe ? |
|
Collections are only as safe as the STL version that implements them. Please
check the documentation for the version of the STL that you're using
for more information about this.
|
| 6.6.6. | How do I access a file ? |
|
If you want to read or write the contents of a file, use the
VCF::FileInputStream or VCF::FileOutputStream classes. If you want to
manipulate the file, for example copying it, or deleting it,
use the VCF::File class.
A quick example of reading from a file:
FileInputStream fis("path/to/some/file.txt");
String fileText;
fis >> fileText;
A quick example of writing to a file:
FileOutputStream fos("path/to/some/file.txt");
String fileText = "blah blah blah, yada, yada, yada";
fos << fileText;
A quick example of copying and then deleting a file:
File f("path/to/some/file.txt");
f.copyTo( "some/other/cool/path/file.txt" );
f.remove();
|
| 6.6.7. | How do I change a files name ? |
|
Use the VCF::File class, and call the VCF::File::setName() method.
A quick example of changing the name:
File f("path/to/some/file.txt");
f.setName( "some/other/cool/path/file.txt" );
|
| 6.6.8. | Can I delete the file programmatically ? Does this actually delete the physical file on the hard disk ? |
|
Yes, use the VCF::File class, and call the VCF::File::remove() method.
Be careful as this will really delete the file!
|
| 6.6.9. | Does the VCF support ref counting ? |
|
Yes. The VCF::Object class has methods for handling this. See
VCF::Object::addRef(), and VCF::Object::release().
|
| 6.6.10. | Does the VCF support garbage collecting? |
|
No, at least not at this point. If you need garbage collector
you'll have to implement this integration your self.
|
| 6.6.11. | Does the VCF have a set of collection classes? |
|
Not really. The VCF makes heavy of STL which has an excellent set
of collection classes for virtually any use. What the VCF does provide
is a simple enumeration class that wraps the
STL collection classes so you can get an enumeration back with being
tied to the precise underlying collection implementation.
|
| 6.6.12. | Whats the point of the Object::destroy() and Object::free() methods |
|
In a typical C++ destructor it is not safe to call
virtual methods, yet there are times when you need to do so. To
achieve this the VCF uses the Object::free() method to destroy all
heap based instances. When Object::free() is called, it first calls
Object::destroy(), and then deletes the instance. The Object::destroy()
is a virtual method that you can override in your own classes, and
provides a safe place to reclaim the object's resources and make
virtual function calls.
|
| 6.6.13. | What is the "proper" or preferred way to delete an instance on the Heap? |
|
If the instance is derived (directly or indirectly) from VCF::Object, then
the preferred way to delete the instance is to call the Object::free() member
function. If the instance does not derive from VCF::Object then you can
use the more traditional delete operator.
class MyObject : public VCF::Object {
public:
};
class Stuff {
};
class MyObject2 : public MyObject {
};
int main( int argc, char** argv )
{
Object* instance1 = new MyObject();
MyObject2* instance2 = new MyObject2();
Stuff* instance3 = new Stuff();
//delete all the instances
instance1->free();
instance2->free();
delete instance3;
}
|
| 6.6.14. | When should I create objects on the heap versus the stack in the VCF? |
|
As a general rule, you'll want to create most VCF based objects
on the heap, with the C++ new operator. All of the Component based
classes should be create on the heap, with the exception of a modal
Dialog. Some of the utility classes like Rect, Point, String, and Size can
be created on the stack.
|
| 6.6.15. | What's the deal with the Enumerator class? I thought the VCF only used the STL for collections? |
|
The VCF::Enumerator class is simply a thin wrapper around an STL iterator.
This provides a generic way to enumerate through a collection without having
to care or expose the actual collection implementation type.
|
| 6.6.16. | Does the VCF support Unicode? |
|
Yes. All string handling is done using the UnicodeString class, which is typedeffed to
String. The String class is a thin wrapper around std::basic_string<WideChar> where
WideChar is defined as an unsigned 16 bit type. For Win32, a single exe can run on either
Windows 9.x or WinNT and will use either the ansi versions of the API (Windows 9.x) or
the Unicode versions of the API. This means you don't have to maintain separate builds
for one platform or the other. Internally all string data is maintained in UTF16 format.
|
| 6.6.17. | Does the VCF support i18n and l10n ? |
|
Yes. See the VCF::Locale class. You can change the locale, and by adding the proper resources
to your application, provide localized string translation.
|
| 6.6.18. | How do I use the Input/Output streams? |
|
Input and Output streams are easy to use. You can determine the amount
of data in the stream by calling getSize(). You can write to the stream
using the write() method, or write any basic type (int, char, double,
String) using the specialized write() method. You can write a buffer of
data by passing in a const unsigned char pointer and a size. You can
read from an InputStream in similar fashion, using one of the read
functions.
|
| 6.6.19. | How do I persist my objects data to a file? |
|
Well the easy way is to simply implement the Persistable interface, and
then just pass your object to a stream. For example:
class MyObject : public VCF::Object, public VCF::Persistable {
public:
virtual void saveToStream( VCF::OutputStream * stream ) {
stream->write( myCount_ );
stream->write( myName_ );
}
virtual void loadFromStream( VCF::InputStream * stream ) {
stream->read( myCount_ );
stream->read( myName_ );
}
protected:
int myCount_;
String myName_;
};
int main( int argc, char** argv )
{
FoundationKit::init(argc,argv);
MyObject obj;
FileOutputStream fso("path/to/my/file.txt");
fso.write( &obj ); //or you could have written fso << &obj;
fso.close();
FileInputStream fsi("path/to/my/file.txt");
fsi >> &obj;
fsi.close();
FoundationKit::terminate();
return 0;
}
|
| 6.6.20. | How do I get at the command line arguments sent to my
application (for example, if I wanted to know what file
to open)? |
|
Call FoundationKit::getCommandLine() which will return a CommandLine
object. See the documentation for the VCF::CommandLine class.
CommandLine commandLine = FoundationKit::getCommandLine();
if ( commandLine.hasSwitch("-h") ) {
//show usage listing...
}
|
| 6.6.21. | I got the VCF installed fine and my program compiled and
linked fine, but as soon as I run my application
it crashes! What's wrong? |
|
You may not have initialized it correctly. If you have an app that makes
use of only the FoundationKit, then you have to initialize it like so:
int main( int argc, char** argv )
{
//initialize the FoundationKit
VCF::FoundationKit::init(argc,argv);
//your code here
//close the FoundationKit down
VCF::FoundationKit::terminate();
return 0;
}
Likewise, if your application uses the GraphicsKit, then you need to
initialize the GraphicsKit, by calling GraphicsKit::init(argc,argv).
Initializing the GraphicsKit automatically initializes the FoundationKit,
and terminating the GraphicsKit also terminates the FoundationKit.
For applications that use a GUI the process is a little different.
At the very least you need to create an Application instance,
passing in the argc and argv arguments to the constructor, and then
call Application::main(). The initialization of the
ApplicationKit, GraphicsKit, and FoundationKit will be taken care of for
you. As an example:
int main( int argc, char** argv )
{
VCF::Application* app new VCF::Application( argc, argv );
Application::main();
return 0;
}
|
| 6.6.22. | Is there some kind of sprintf like routine in the VCF?
I can't seem to find anything and I really would like one! |
|
Yes, look in the StringUtils class for the static member function
VCF::StringUtils::format(). You can use like so:
String formattedString =
StringUtils::format( "Hello from: %s at %d seconds to %0X4 at %.2f", "FooBar", 10, 124, 123.34788 );
|