[Kstars-devel] Questions about planet skycomponents
Thomas Kabelmann
thomas.kabelmann at gmx.de
Mon Sep 26 22:18:30 CEST 2005
OK, I see we are getting the SkyObject from KSPopupMenu::initPopupMenu() which
gets it from SkyMap::clickedObject(). setClickedObject() will be called by
SkyMap::objectNearest() which does not anything else than searching for a
SkyObject located in the data lists in KStarsData which doesn't exist
anymore. This list where moved into the components. Currently it's not
implemented to traverse the components and get the SkyObject/s.
So if we want find a skyobject, we must find the component which encapsulates
the SkyObject we are looking for. After finding this component, it would be
easy to store the pointer to the component and the object instead of storing
just the pointer to the object, like now.
But a better way might be, if we add an element ActiveObject to SkyComponent,
so after finding the object in the component, we activate it and just store
the component in SkyMap::clickedObject.
So it looks like this:
SkyComponent {
QList<SkyObjects> internalElementList; // e.g. asteroids
SkyObject *ActiveElement;
bool find(SkyObject *o) {
if (o in internalElmentList) {
ActiveElement = o;
return true;
}
return false;
}
}
and
SkyMap::clickedComponent() {
return ClickedComponent;
}
SkyMap::clickedObject() {
return clickedComponent()->ActiveElement();
}
> No, the Signal sends a pointer to the SkyObject itself which has
> added|removed a trail, not the SkyPoint of the trail. So the Slot will
> have the SkyObject, and can use the object's type (ASTEROID, COMET, PLANET)
> to determine which child owns that object (in the case of PLANETs, it will
> also need the object's name). There's no need to search through the
> Components.
So this is not needed, by my approach above. I also dislike to determine the
component by getting the type from the object. So we are losing the static
type safety from the compiler as we are "casting" the component by a self
defined type. We have to do something like this:
if (o->type() == ASTEROID) AsteroidComponent->AddTrail(o)
else if (o->type() == COMET) CometsComponent->AddTrail(o)
else ...
instead of:
clickedComponent()->addTrail() // addTrail can use ActiveElement
> It seems to me that with the Trailable class does not solve the problem of
> notification. When SkyMap or KStars add or remove a Trail, how does the
> Component find out about it? I think my proposal is simpler than having
It's just the overhead, finding a second time the component, I don't like :-)
> multiple inheritance of an additional class, but maybe I don't fully
> understand. From the point of view of the API, my proposal is also generic
> for all AbstractPlanetComponents. They all have public functions
> addTrail(SkyObject*) and removeTrail(SkyObject*), which get called from the
> slots in SolarSystemComponent described in my prev. message. The
> difference is in the implementation: CometsComp and AsteroidsComp
> add/remove the object from their private QLists of trailed objects, and the
> other classes simply set a private bool member (HasTrail) true/false.
> That's pretty simple, isn't it?
By adding an own list or flag for each component is just error prone, as we
duplicate the code. So doing this by multiple inheritence is much better.
Another way could be adding virtual function add/removeTrail() to the
SkyComponent like your approach. Then we need new abstract components like
ListTrailableComponent and TrailableComponent, which are overriding the
default implementation. AsteroidsComponent is then derived from
ListTrailableComponent.
Thomas
More information about the Kstars-devel
mailing list