Using Bindings with C++ objects

  • I have an existing Carbon app that I'm trying to port to Cocoa. I
    don't want to rewrite everything as an Obj-C object, so I'm looking
    for ways to wrap Cocoa around my C++.

    In one situation, I have a C++ object that represents a Satellite, and
    another that is a SatelliteProxy. In the app, there is a master list
    of Satellite objects, and a SatelliteProxy for each satellite in each
    view that's displaying satellites. The proxy object overrides some of
    the attributes of the graphical representation of a Satellite. For
    example, in one view, the International Space Station (ISS) may have a
    red ground track, and in another view, a green ground track. In this
    instance, there are two ISS SatelliteProxy objects that each refer to
    the single, global (app-wide) ISS Satellite object.

    The user can select SatelliteProxy objects (one or many) in a view,
    then use an inspector to adjust their attributes.For example, if an
    attribute is "Show footprint" (the footprint is the area of the Earth
    that has line-of-site to the satellite at a given instant), and two
    satellites are selected, one with the footprint enabled, the other
    not, the checkbox in the inspector would show a dash. Similarly, if
    both satellites had the footprint enabled, the box would show as
    checked (standard multi-object inspector behavior).

    I'd like to use bindings to facilitate this (as I understand it, this
    is something they're good for). However, they won't work directly on C+
    + objects. I was thinking I could subclass NSArrayController and
    override the valueForKey: methods to manually inspect the key path and
    hard-code queries to the SatelliteProxy objects. One of my concerns
    with this approach is that the NSArrayController's container for the
    collection of SatelliteProxy objects may not be able to contain C++
    objects.

    I'd like to get feedback on this approach. Is it viable? It's okay if
    there's extra effort coding up the key-to-C++ mapping. That's still
    less work than rewriting my classes as Obj-C.

    An alternative is to create a wrapper Obj-C object, one for each
    SatelliteProxy object. I do something similar for the view code I
    wrote in the Carbon app.

    Suggestions?

    TIA,
    Rick
  • Rick,

      I doubt you'd gain anything from using bindings in your case. The
    code you'd have to write to bridge your C++ objects would essentially
    be the same as you'd have to write to implement your master-detail-
    view without bindings.

    Bindings are so useful because they can introspect into ObjC objects.
    Without that, bindings are just a complication on top of MVC, and
    don't get you anything.

    Cheers,
    -- M. Uli Kusterer
    http://www.zathras.de

    Am 22.12.2007 um 23:53 schrieb Rick Mann <rmann...>:

    > I have an existing Carbon app that I'm trying to port to Cocoa. I
    > don't want to rewrite everything as an Obj-C object, so I'm looking
    > for ways to wrap Cocoa around my C++.
    >
    > In one situation, I have a C++ object that represents a Satellite,
    > and another that is a SatelliteProxy. In the app, there is a master
    > list of Satellite objects, and a SatelliteProxy for each satellite
    > in each view that's displaying satellites. The proxy object
    > overrides some of the attributes of the graphical representation of
    > a Satellite. For example, in one view, the International Space
    > Station (ISS) may have a red ground track, and in another view, a
    > green ground track. In this instance, there are two ISS
    > SatelliteProxy objects that each refer to the single, global (app-
    > wide) ISS Satellite object.
    >
    > The user can select SatelliteProxy objects (one or many) in a view,
    > then use an inspector to adjust their attributes.For example, if an
    > attribute is "Show footprint" (the footprint is the area of the
    > Earth that has line-of-site to the satellite at a given instant),
    > and two satellites are selected, one with the footprint enabled, the
    > other not, the checkbox in the inspector would show a dash.
    > Similarly, if both satellites had the footprint enabled, the box
    > would show as checked (standard multi-object inspector behavior).
    >
    > I'd like to use bindings to facilitate this (as I understand it,
    > this is something they're good for). However, they won't work
    > directly on C++ objects. I was thinking I could subclass
    > NSArrayController and override the valueForKey: methods to manually
    > inspect the key path and hard-code queries to the SatelliteProxy
    > objects. One of my concerns with this approach is that the
    > NSArrayController's container for the collection of SatelliteProxy
    > objects may not be able to contain C++ objects.
    >
    > I'd like to get feedback on this approach. Is it viable? It's okay
    > if there's extra effort coding up the key-to-C++ mapping. That's
    > still less work than rewriting my classes as Obj-C.
    >
    > An alternative is to create a wrapper Obj-C object, one for each
    > SatelliteProxy object. I do something similar for the view code I
    > wrote in the Carbon app.
    >
    > Suggestions?
    >
    > TIA,
    > Rick
  • > Rick,
    >
    > I doubt you'd gain anything from using bindings in your case. The
    > code you'd have to write to bridge your C++ objects would essentially
    > be the same as you'd have to write to implement your master-detail-
    > view without bindings.

    But I think writing obj-C wrapper to the C++ class or module and
    binding against that is a good
    alternative than glue code. Its a one time job and definitely would
    make the app
    more cleaner.  Also in future if its decided to port that stuff to
    objective C, then you dont have to mess up
    again with your view classes.

    Regards
    Shripada
  • On Dec 22, 2007, at 2:53 PM, Rick Mann wrote:

    > I'd like to use bindings to facilitate this (as I understand it,
    > this is something they're good for). However, they won't work
    > directly on C++ objects. I was thinking I could subclass
    > NSArrayController and override the valueForKey: methods to manually
    > inspect the key path and hard-code queries to the SatelliteProxy
    > objects. One of my concerns with this approach is that the
    > NSArrayController's container for the collection of SatelliteProxy
    > objects may not be able to contain C++ objects.
    >
    > I'd like to get feedback on this approach. Is it viable? It's okay
    > if there's extra effort coding up the key-to-C++ mapping. That's
    > still less work than rewriting my classes as Obj-C.
    >
    > An alternative is to create a wrapper Obj-C object, one for each
    > SatelliteProxy object. I do something similar for the view code I
    > wrote in the Carbon app.

    Creating a wrapper for the SatelliteProxy and binding to that will
    probably be the easiest thing to do.  You'll wind up with less code
    than you would trying to override things in NSArrayController (and its
    superclasses) to make this work, and your code will be much more
    modular.

    I'll take this as an opportunity to talk about my MVCP[1]
    recommendation for writing cross-platform code, which also works for
    writing single-platform code where you're mixing technologies.
    Instead of a traditional Model-View-Controller architecture, you split
    the controller in two:  One part is a Controller which implements the
    common model-level "interaction" for your architecture, and the other
    part is a Presenter which implements view/framework-specific
    controller behavior.

    For example, if you're writing an accounting application with a
    "record transaction" button, the target of that button would be a
    Presenter object.  The Presenter would take information from your
    views, convert it to the proper form for your

    It sounds like you're already doing this, just under different names.
    So you don't have very far to go. :)

    To extrapolate an example, though, from the couple of classes you've
    mentioned, here's how I'd approach the design of the application:

      GroundTrackView[V] - a View that displays satellite ground tracks
    (ObjC)
      GroundTrackPresenter[P] - a Presenter that manages display of
    satellite ground tracks (ObjC++)
      SatelliteProxy[C] - a Controller to do bookkeeping for satellite
    ground tracks (C++)
      Satellite[M] - a Model representing a satellite (C++)

    For one Satellite I might have one or more SatelliteProxy objects,
    each of which would probably be wrapped by or interfaced to by one
    GroundTrackPresenter, each of which would be interacted with by one
    GroundTrackView.

    If I subsequently wanted to implement a .NET, GNOME, or even Web 2.0
    version of this application, only the View layer and Presenter layer
    code needs to be written anew.  The applications logic is in its Model
    layer and the interaction with this logic is handled by its Controller
    layer.

    -- Chris

    [1] I used to call this MVCC, where the first controller was a "model
    controller" and the second was a "view controller."  But Cocoa now has
    an NSViewController class that's used for a different purpose, so I've
    changed the name of the "view controller" to "presenter."  In a lot of
    ways it's just Model-View-Presenter but with an extra layer between
    the Model and Presenter to handle interaction in a more abstract
    fashion.  This can also be useful for apps that also want to expose
    (say) a scripting API.
  • Using bindings for anything other than MODEL <--> VIEW is not recommended by
    Apple...
    See this message:

    http://lists.apple.com/archives/Cocoa-dev/2005/May/msg02490.html

    On May 26, 2005, at 7:39 PM, mmalcolm crawford wrote:

    After all the other writing I omitted the main point:
    You typically should not bind one model object to another.  The primary goal
    of bindings is to keep user views synchronised with models.  You bind an
    attribute of a UI widget to the property of a model object...

    If you find yourself doing anything different than binding an attribute of a
    UI widget to the property of a model object, then you're probably going to
    get into more trouble than you would expect.

    On Dec 22, 2007 2:53 PM, Rick Mann <rmann...> wrote:

    > I have an existing Carbon app that I'm trying to port to Cocoa. I
    > don't want to rewrite everything as an Obj-C object, so I'm looking
    > for ways to wrap Cocoa around my C++.
    >
    > In one situation, I have a C++ object that represents a Satellite, and
    > another that is a SatelliteProxy. In the app, there is a master list
    > of Satellite objects, and a SatelliteProxy for each satellite in each
    > view that's displaying satellites. The proxy object overrides some of
    > the attributes of the graphical representation of a Satellite. For
    > example, in one view, the International Space Station (ISS) may have a
    > red ground track, and in another view, a green ground track. In this
    > instance, there are two ISS SatelliteProxy objects that each refer to
    > the single, global (app-wide) ISS Satellite object.
    >
    > The user can select SatelliteProxy objects (one or many) in a view,
    > then use an inspector to adjust their attributes.For example, if an
    > attribute is "Show footprint" (the footprint is the area of the Earth
    > that has line-of-site to the satellite at a given instant), and two
    > satellites are selected, one with the footprint enabled, the other
    > not, the checkbox in the inspector would show a dash. Similarly, if
    > both satellites had the footprint enabled, the box would show as
    > checked (standard multi-object inspector behavior).
    >
    > I'd like to use bindings to facilitate this (as I understand it, this
    > is something they're good for). However, they won't work directly on C+
    > + objects. I was thinking I could subclass NSArrayController and
    > override the valueForKey: methods to manually inspect the key path and
    > hard-code queries to the SatelliteProxy objects. One of my concerns
    > with this approach is that the NSArrayController's container for the
    > collection of SatelliteProxy objects may not be able to contain C++
    > objects.
    >
    > I'd like to get feedback on this approach. Is it viable? It's okay if
    > there's extra effort coding up the key-to-C++ mapping. That's still
    > less work than rewriting my classes as Obj-C.
    >
    > An alternative is to create a wrapper Obj-C object, one for each
    > SatelliteProxy object. I do something similar for the view code I
    > wrote in the Carbon app.
    >
    > Suggestions?
    >
    > TIA,
    > Rick
    >
  • On Mon, 24 Dec 2007 11:59:35 +0530, Shripada Hebbar <shripada...>
    > wrote:
    >> Rick,
    >>
    >> I doubt you'd gain anything from using bindings in your case. The
    >> code you'd have to write to bridge your C++ objects would
    >> essentially be the same as you'd have to write to implement your
    >> master-detail-view without bindings.
    >
    > But I think writing obj-C wrapper to the C++ class or module and
    > binding against that is a good alternative than glue code. Its a one
    > time job and definitely would make the app more cleaner.  Also in
    > future if its decided to port that stuff to objective C, then you
    > dont have to mess up again with your view classes.

    Yes, absolutely (if I understand completely what you are suggesting
    Shripada): one of the motivations for dropping in the NSMutableArray
    wrappers and light-weight NSObject proxies was for future migration of
    the 'engine' portion of the application to Cocoa/Obj-C (should we
    ultimately decide to make that transition).  There would be no need to
    change the bindings or update the nibs (except, perhaps to update
    class names)--just swap in the new NSMutableArray and 'real'
    replacements for the proxies.

    Mike
previous month december 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today