SketchUp / api-issue-tracker

Public issue tracker for the SketchUp and LayOut's APIs
https://developer.sketchup.com/
38 stars 10 forks source link

SUEntitiesFromRuby & SUEntitiesToRuby #727

Open thomthom opened 3 years ago

thomthom commented 3 years ago

Ref: https://forums.sketchup.com/t/using-the-observers-and-parsing-the-ruby-args-correctly/178846/5?u=tt_su

DanRathbun commented 3 years ago

Yes, in the cited topic, I gave the same workaround advice you had re: SUEntityGetParentEntities

But this also made me wonder about getting references to other collections, but looking at the docs I realized that the active model "owns" all of the other collections and so (in a "live" use scenario) can be accessed via SUApplicationGetActiveModel or SUEntityGetModel; and then by the various SUModelRef collection accessor functions.

The case of passing the Entities collection reference is not unique. There are a few other of the model's collections that are subclasses of Object and not Entity.

Ie, the following collection objects derive from Object and do not have C API casting functions:

Also does not have casting but, perhaps a simple workaround:

Not Needed currently as there is no exposure in the C API:

All the other collections are subclasses of Entity in the Ruby API, but can they be passed via SUEntityFromRuby ?

I do not think directly as they are exposed in the C API as arrays, whose members are SUEntityRef subtypes and all have casting functions.

So I think all the following collections (which might need to be passed from Ruby observer callbacks) are "in the same boat" as InstancePath, ie, must be passed as arrays and then iterated and cast to their proper type.

So, I would imagine for most coders, that using the workaround to get these C side collections via the various SUModelRef collection accessor functions is preferable to doing all the conversion yourself.

I wonder if a new C API function could identify the Ruby class of the collection and call the appropriate SUModelRef collection accessor function. Ie a SUCollectionFromRuby() function if you will ? Then we would not need a conversion function for each different collection object.

Thoughts ?

sketchupbot commented 3 years ago

Logged as: SKEXT-3251

thomthom commented 3 years ago

So, I would imagine for most coders, that using the workaround to get these C side collections via the various SUModelRef collection accessor functions is preferable to doing all the conversion yourself.

Yea, for the manager classes that the model own directly one would get it from the model.

I wonder if a new C API function could identify the Ruby class of the collection and call the appropriate SUModelRef collection accessor function. Ie a SUCollectionFromRuby() function if you will ?

Not sure how you intended this to work. return types (and out params) are all strongly typed. You cannot return a layer manager or a material manager, not without going about using a union or using a struct the has all the possible return types with a type indicator (a variant).

But there's another snag to this, the C API doesn't have a type of many of the manager classes. Unfortunately a lot of the logic that would ideally be on a manager class was added directly to SUModelRef. So in most cases you have to fetch the model ref any way.

The instance path type is one where we might benefit from an exchange method. Though we want to be careful about these, as they make life time and ownership tricky. With ImageRef we didn't make a copy because images are expensive objects. But with instance path we can just make a copy. (And that's currently possible to do already without any significant performance penalties.)

DanRathbun commented 3 years ago

Not sure how you intended this to work.

I'm not sure either, ... just musing.

Ruby is implemented in C. I wondered if the first member of a collection could be "sniffed" to determine it's type. Lacking this, I also wondered if a conversion function could require a "member type" argument.

[In C] return types (and out params) are all strongly typed.

I was thinking that all the collection getters in the C API return Array. Also function pointers flited through my head.

But I'm not intimate with C. I don't much care for it actually. Can read it, but that's enough to be dangerous. ;)

If it's not feasible. I understand. Forget it. And like what was said, you can get all those collection arrays from SUModelRef anyway.

DanRathbun commented 3 years ago

So for the "Live" C API ... this leaves the Tools collection access which might be moderate priority.

The ExtensionsManager is likely low priority.