[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