I have some core engine code that is written in C++, with the intent of keeping it portable. I only have a Cocoa implementation of my outer application, at present, so it's been a slightly academic exercise, but so far, most of the code in my data model remains substantially portable.

Now, as I try to implement undo, I find it difficult and messy to keep the C++ code portable. I have only come up with two similar ways to do this, and I'm curious if others have been down this path and can make any recommendations.

One approach is to use IMPs (Objective-C method implementation pointers) to call back into Objective-C, from C++. That is, the C++ code uses function pointers, essentially, when registering undo actions. These IMPs would presumably be wrapped by a C++ class providing a uniform interface to platform specific undo.

A second part of this solution involves writing some sort of ill-defined Objective-C intermediary that forwards invocations posted by the undo architecture to the appropriate C++ core data model objects. This seems pretty artificial, since the engine objects are moderately lightweight to begin with. As if this solution weren't tedious and ugly enough, note that the engine now projects a fairly Cocoa-specific vision of an undo architecture (good though it may be), as well as some unpleasant mechanics, onto the cross platform engine code.

A second somewhat more refined approach is to write a shallow hierarchy of undo actions ("commands," in GoF parlance), appropriate instances of which are provided by engine objects when registering specific actions to undo, and send these, again via the IMP mechanism, to some intermediary Objective-C code, that repackages the actions as invocations, and forwards those invocations, when invoked by an NSUndoManager, to reapply the actions to their target objects, and clean up.

The second approach seems cleaner to me, since to the extent it forces a specific undo implementation on the engine, it is likely to be more portable / adaptable, and because it localizes the messy platform-specific adaption code almost entirely outside the engine. The undo "action" hierarchy is less elegant than invocations, but that is presumably the price of keeping the engine portable. But are there better plans than this?

It seems to me as if some enhancement to NSUndoManager might facilitate easier interaction with C/C++ code, and that this is probably a common problem, given that data model code is often one of the better candidates for C++ implementation. The Cocoa undo architecture pretty much requires close interaction between a data model and NSUndoManager.

A key part of any potential extensions would be one or more C/C++ accessible entry points. It might also include the ability to stack client-defined undo "action" or invocation objects, as outlined above, or perhaps a way to package C-style variable argument lists and function pointers.

I'm mocking up the "second" approach outlined above in a small test application, and will summarize my findings once I've learned something useful.

[Two+ weeks later...]

I didn't bother to complete my test application. After thinking about it a while, I decided that the inelegance and complexity of this approach was just too great for the benefit, and I decided to ditch cross-platform compatibility, and convert what I had to back to Objective-C++. In practice, this is rippling painfully hard, and necessitating a lot of rework. And it feels terrible to be trashing the work I did to make a portable engine.

So, I'm appealing to anyone who's come up with a better answer than I have to please share. Thanks in advance, -jar
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to