12.07.2015 Views

Implementation of a Peer-to-Peer Multiplayer Game with ... - DVS

Implementation of a Peer-to-Peer Multiplayer Game with ... - DVS

Implementation of a Peer-to-Peer Multiplayer Game with ... - DVS

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

4.6.2 <strong>Implementation</strong> ConcernsUnlike C++, Standard ML is not object oriented and thus does not have the concept <strong>of</strong> classes. Butthe CUSP API <strong>with</strong> its signatures and implementing structures for endpoints, hosts, streams, etc. can bemapped directly <strong>to</strong> an object oriented API providing a corresponding class for each signature. The mainchallenge when creating C++ bindings for Standard ML is how <strong>to</strong> cleanly map between the garbagecollected Standard ML environment and C++. The solution developed for this purpose is generallyapplicable for mapping Standard ML structures <strong>to</strong> C++ objects.The C interface exported by the Standard ML glue code makes the structures accessible via handles.Whenever a structure is <strong>to</strong> be passed <strong>to</strong> the C part, it is internally s<strong>to</strong>red in an IdBucket which returnsthe index <strong>of</strong> the newly inserted element. That index is passed <strong>to</strong> C as a handle. Accordingly, anyfunction that takes a structure as a parameter is exported <strong>to</strong> C expecting a handle. When called, thestructure is retrieved from the corresponding IdBucket and the wrapped function is invoked. By keepingthe structures in the IdBucket, they remain referenced <strong>with</strong>in Standard ML and thus are preventedfrom being garbage collected while still being needed by the C part. Consequently, it is the C part’sresponsibility <strong>to</strong> free all structures when they are not used anymore. All three operations <strong>of</strong> IdBucket,s<strong>to</strong>ring, retrieving, and removing structures, have O(1) complexity. Structure retrieval is based on anarray lookup by index, while s<strong>to</strong>rage and removal <strong>of</strong> structures pr<strong>of</strong>its from keeping a linked list <strong>of</strong> freecells.The object oriented C++ interface in turn wraps the exported C functions. Although the C functionscan be used directly by applications, that is not recommended. Especially because <strong>of</strong> the need for explicitlyfreeing any handle ever obtained, using the C interface is both inconvenient and error-prone. TheC++ API disburdens the programmer from most <strong>of</strong> those tasks. Each C++ API class basically just keepsa handle <strong>to</strong> the corresponding structure in Standard ML. Creating, copying and deleting classes can bedone in the usual C++ way and the whole handle management is safely wrapped. The resulting C++API classes match the Standard ML signatures (for an overview see 2.5.2) <strong>with</strong> only a few exceptions.But still there is one important difference significantly affecting the usage <strong>of</strong> the C++ API, which isthe lack <strong>of</strong> closures and/or lambda calculus in C++. As the CUSP API is completely asynchronous, thereis <strong>of</strong>ten the need for passing callbacks. Standard ML provides closures, allowing <strong>to</strong> pass functions thatkeep their surrounding scope, greatly simplifying the programming and improving code readability. InC/C++ it is in most cases necessary <strong>to</strong> explicitly define and create an object that keeps the context thethe calling function and that is passed <strong>with</strong> the callback function. This limitation <strong>of</strong> C/C++ cannoteffectively be overcome. The solution chosen here is <strong>to</strong> provide interfaces (i.e., purely virtual classes)as callback types, which is the typical way <strong>of</strong> implementing callbacks in Java 9 . For instance, EndPointdefines a handler interface for the contact<strong>Peer</strong>() method:class EndPoint{(...)class ContactHandler {public:virtual void onContact(Host& host) = 0;virtual void onContactFail() = 0;};void contact<strong>Peer</strong>(const Address& addr , ContactHandler* handler);}(...)9 http://www.javaworld.com/javaworld/javatips/jw-javatip10.html68 4.6 CUSP Bindings

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!