Label: ♦english ♦miscellaneous
fu created at Monday, 2012-05-14, 07:08:55
3 Replies, 1694 Hits
Thanks to ClangDao, it has become very easy to create bindings for C/C++ libraries. The latest one is DaoGameKit for the open source 3D game engine GameKit (or gamekit.org ).
Before I started, I thought it maybe very tricky to wrap the complete APIs of GameKit, so I decided to wrap the scripting APIs (in GameKit/Engine/Script/Api) only. But then it turned out they are not completely separated from its Lua support. So I had to try to wrap the raw APIs directly, to my surprise, it turned out not as tricky as I had expected, and for this reason I believe DaoGameKit can be supported officially.
Because GameKit uses cmake, and Dao has cmake support (thanks to Pompei2), it was quite simple to integrate DaoGameKit into the source tree of GameKit. I did have to fix a few bugs and add a few improvements in Dao and ClangDao to be able to fully port the CppDemo to Dao. Now the demo (in Samples/DaoDemo) is fully functional, it has about 2000 lines of codes, not small for a demo:).
There is one important caveat that one must be aware of to avoid memory bug when using DaoGameKit. This caveat roots in the fact that Dao and GameKit have their own ways to manage the deallocation of objects. By default, Dao assumes ownership of C/C++ objects that are allocated by Dao (namely, returned by an allocator or initializer), and assumes no ownership of C/C++ objects returned by a method of another object, for example:
lr = gkLimitRotConstraint();Dao will own and free the C/C++ object wrapped in lr , but not the one wrapped in m_physics . So normally, Dao and GameKit can properly deallocate objects owned by them.
m_physics = tscene.getObject(GK_RESOURCE_PLAYER_PHYS);
The problem arises when an object owned by Dao is passed as a parameter to a GameKit API, and then GameKit assumes new ownership of the object while Dao still owns it and may deallocated it before GameKit has done with the object. For example,
dest.addConstraint(m_xRot, lr);After this call, dest will assume the ownership of the raw object of lr and will deallocate it by itself.
Fortunately, the bindings are generated in a way such that it is always OK if GameKit deallocates the raw object before Dao collects the wrapper. So a simple solution to solve the problem is to ensure the wrapper object of lr will have a life span longer than dest , the simplest way to achieve this is to set lr as a meta field of an object the will surely out-live dest . for example,
self->rotConstraint = lr;where self is a gkGamePlayer object (in the DaoDemo) which will live as long as the program runs, so Dao will collect lr surely after GameKit has done with it. Future improvement to DaoGameKit may eventually eliminate the need for such workaround.
Pompei2 commented at Friday, 2012-05-18, 09:17:55
This is cool news and really shows that ClangDao is getting mature, thumbs up.
Too bad for this little caveat, I guess that's why most languages invent new engines or hand-write pure-language wrappers instead of porting existing ones. I don't have any better idea of a workaround.
fu commented at Saturday, 2012-05-19, 02:38:29
Yes, it is getting mature, and more libraries and modules are coming out, hehe:)
For GameKit, unfortunately it does not use reference counting, otherwise there is a simple solution. Now the only workaround I can think of is to identify class methods that can return objects that own the class instances, so that such methods can be used to test if the instances can be deallocated by Dao GC.
When I looked into the source of GameKit, it is not obvious if such methods exist. The problem is that it uses various manager classes to manage objects, objects of some (maybe most) classes do not have methods to retrieve their managers. There are some methods (e.g. gkConstraint::getObject()) that return objects of gkGameObject, which is usually (I assume) set for an object when it is added to an manager. Maybe I will have to use such methods for a workaround. It also looks like that such managers (at least gkConstraintManager which is what I have checked) are implemented in very simple way, so it really relies on the users to write correct codes (for example, avoiding adding object twice to one or more managers).
fu commented at Saturday, 2012-05-19, 02:43:41
Just to mention: a couple of demos (including the 2000 line one) has been successfully ported to IPhone!
Also: a small piece of instruction on how to setup DaoGameKit can be found in the DaoGameKit.readme file at DaoGameKit/Files .
fu: Dao has finally become feature complete! After the recent implementation of communication channel for tasklets, deferred blocks and exception ... (May.18,05:46)
fu: A new feature for concurrent programming: tasklet communication channels! I have been looking for ways to improve Dao's support for concurrent programming. The most recent imp ... (May.18,00:35)
fu: Dao now supports Go-style panic/exception handling! I recently looked into the panic/ exception handling in the Go programming language (defer- recover), ... (May.07,02:04)