public abstract class SegmentPropagator extends Object implements IThreadAware, IDisposable
segment's
propagator.
This will perform the propagation and produce SegmentResults
.
There are two types of propagation that need to be supported. There is the
normal SegmentPropagator.propagateSegment(SegmentListResults,SegmentConfiguration,ITrackCalculationProgress)
call that will start from where the previous segment
stopped. There is also the SegmentPropagator.propagateTo(agi.foundation.segmentpropagation.SegmentResults, agi.foundation.time.JulianDate)
method that is needed for when
a segment propagated after this one needs to back up for some reason. Propagation
forwards and backwards must be handled as well.
See the Segments topic for more details about using segments.
Modifier | Constructor and Description |
---|---|
protected |
SegmentPropagator(SegmentDefinition previousSegment,
SegmentDefinition creator,
EvaluatorGroup group)
Initializes a new instance.
|
protected |
SegmentPropagator(SegmentPropagator existingInstance,
CopyContext context)
Initializes a new instance as a copy of an existing instance.
|
Modifier and Type | Method and Description |
---|---|
void |
addPropagationFinishedEvent(EventHandler<SegmentPropagationEventArgs> value)
An event that gets raised when propagation finishes.
|
void |
applyResults(SegmentResults results)
This method sets propagator's state via the input
results . |
abstract Object |
clone(CopyContext context)
Clones this object using the specified context.
|
protected void |
defaultStateAdaptation(ITimeBasedState initialState,
ITimeBasedState finalState)
|
void |
dispose()
Releases any resources associated with this instance.
|
protected void |
dispose(boolean disposing)
Releases any resources associated with this instance.
|
List<StateElementAdapter> |
getAdapters()
Gets a list of the
StateElementAdapters that this
segment can use in its propagation. |
SegmentDefinition |
getIdentifier()
Gets the
definition that created this propagator. |
boolean |
getIsThreadSafe()
Gets a value indicating whether the methods on this instance are safe to call from
multiple threads simultaneously.
|
String |
getName()
Gets the name of this
SegmentPropagator . |
SegmentConfiguration |
getOriginalConfiguration()
Gets the original configuration for this segment.
|
IntegrationSense |
getPropagationDirection()
Gets the initial direction of propagation.
|
StateForNextSegmentBehavior |
getStateForNextSegmentBehavior()
Gets which state should be passed to the next
SegmentPropagator . |
SegmentResults |
propagate()
Propagates the segment assuming no initial state is passed in.
|
SegmentResults |
propagate(ITimeBasedState initialState)
Propagates the segment starting from the
initialState . |
SegmentResults |
propagate(ITimeBasedState initialState,
ITrackCalculationProgress progressTracker)
Propagates the segment starting from the
initialState . |
SegmentResults |
propagate(ITimeBasedState initialState,
SegmentListResults cumulativeResults)
Propagates the segment starting from the
initialState . |
SegmentResults |
propagate(SegmentConfiguration editedConfiguration,
ITrackCalculationProgress progressTracker)
Propagates the segment.
|
SegmentResults |
propagate(SegmentListResults cumulativeResults)
Propagates the segment.
|
SegmentResults |
propagate(SegmentListResults cumulativeResults,
SegmentConfiguration editedConfiguration,
ITrackCalculationProgress progressTracker)
Propagates the segment with the given parameters.
|
protected abstract SegmentResults |
propagateSegment(SegmentListResults cumulativeResults,
SegmentConfiguration editedConfiguration,
ITrackCalculationProgress progressTracker)
The method that actually propagates the segment.
|
abstract ITimeBasedState |
propagateTo(SegmentResults results,
JulianDate dateToPropagateTo)
Propagates a segment to the time or independent variable specified in the
dateToPropagateTo . |
void |
removePropagationFinishedEvent(EventHandler<SegmentPropagationEventArgs> value)
An event that gets raised when propagation finishes.
|
protected void |
setOriginalConfiguration(SegmentConfiguration value)
Sets the original configuration for this segment.
|
String |
toString()
Returns a string representation of the object.
|
static boolean |
updateProgressTrackerAndReturnIfCanceled(ITrackCalculationProgress progressTracker)
A helper method to handle the
progress tracker that
the various SegmentPropagator.propagate() methods have. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
close
protected SegmentPropagator(@Nullable SegmentDefinition previousSegment, @Nonnull SegmentDefinition creator, @Nonnull EvaluatorGroup group)
previousSegment
- The previous segment
. If a
SegmentListPropagator
is creating its children propagators
, it should
pass in its previous segment to its first child segment. A valid SegmentPropagator
should be
returned even if this parameter is null
.creator
- The SegmentDefinition
creating this propagator.group
- The EvaluatorGroup
to use when creating evaluators
.protected SegmentPropagator(@Nonnull SegmentPropagator existingInstance, @Nonnull CopyContext context)
See ICloneWithContext.clone(CopyContext)
for more information about how to implement this constructor
in a derived class.
existingInstance
- The existing instance to copy.context
- A CopyContext
that controls the depth of the copy.ArgumentNullException
- Thrown when existingInstance
or context
is null
.public abstract Object clone(CopyContext context)
This method should be implemented to call a copy constructor on the class of the
object being cloned. The copy constructor should take the CopyContext
as a parameter
in addition to the existing instance to copy. The copy constructor should first call
CopyContext.addObjectMapping(T, T)
to identify the newly constructed instance
as a copy of the existing instance. It should then copy all fields, using
CopyContext.updateReference(T)
to copy any reference fields.
A typical implementation of ICloneWithContext
:
public static class MyClass implements ICloneWithContext {
public MyClass(MyClass existingInstance, CopyContext context) {
context.addObjectMapping(existingInstance, this);
someReference = context.updateReference(existingInstance.someReference);
}
@Override
public final Object clone(CopyContext context) {
return new MyClass(this, context);
}
private Object someReference;
}
In general, all fields that are reference types should be copied with a call to
CopyContext.updateReference(T)
. There are a couple of exceptions:
If one of these exceptions applies, the CopyContext
should be given an opportunity
to update the reference before the reference is copied explicitly. Use
CopyContext.updateReference(T)
to update the reference. If CopyContext.updateReference(T)
returns
the original object, indicating that the context does not have a replacement registered,
then copy the object manually by invoking a Clone method, a copy constructor, or by manually
constructing a new instance and copying the values.
alwaysCopy = context.updateReference(existingInstance.alwaysCopy);
if (existingInstance.alwaysCopy != null && alwaysCopy == existingInstance.alwaysCopy) {
alwaysCopy = (AlwaysCopy) existingInstance.alwaysCopy.clone(context);
}
If you are implementing an evaluator (a class that implements IEvaluator
), the
IEvaluator.updateEvaluatorReferences(agi.foundation.infrastructure.CopyContext)
method shares some responsibilities with the
copy context constructor. Code duplication can be avoided by doing the following:
CopyContext.updateReference(T)
. You should still call CopyContext.updateReference(T)
on any references to
non-evaluators.
IEvaluator.updateEvaluatorReferences(agi.foundation.infrastructure.CopyContext)
as the last line in the constructor and pass it the
same CopyContext
passed to the constructor.
IEvaluator.updateEvaluatorReferences(agi.foundation.infrastructure.CopyContext)
as normal. See the reference documentation for
IEvaluator.updateEvaluatorReferences(agi.foundation.infrastructure.CopyContext)
for more information on implementing that method.
public MyClass(MyClass existingInstance, CopyContext context) {
super(existingInstance, context);
someReference = context.updateReference(existingInstance.someReference);
evaluatorReference = existingInstance.evaluatorReference;
updateEvaluatorReferences(context);
}
@Override
public void updateEvaluatorReferences(CopyContext context) {
evaluatorReference = context.updateReference(evaluatorReference);
}
@Override
public Object clone(CopyContext context) {
return new MyClass(this, context);
}
private Object someReference;
private IEvaluator evaluatorReference;
clone
in interface ICloneWithContext
context
- The context to use to perform the copy.public final void dispose()
dispose
in interface IDisposable
protected void dispose(boolean disposing)
disposing
- true
to release both managed and unmanaged resources;
false
to release only unmanaged resources.public boolean getIsThreadSafe()
If this property is true
, all methods and properties are guaranteed to be thread safe.
Conceptually, an object that returns true
for this method acts as if there is a lock
protecting each method and property such that only one thread at a time can be inside any method or
property in the class. In reality, such locks are generally not used and are in fact discouraged. However,
the user must not experience any exceptions or inconsistent behavior that would not be experienced if such
locks were used.
If this property is false
, the behavior when using this class from multiple threads
simultaneously is undefined and may include inconsistent results and exceptions. Clients wishing to use
multiple threads should call CopyForAnotherThread.copy(T)
to get a separate instance of the
object for each thread.
getIsThreadSafe
in interface IThreadAware
public static boolean updateProgressTrackerAndReturnIfCanceled(@Nullable ITrackCalculationProgress progressTracker)
progress tracker
that
the various SegmentPropagator.propagate()
methods have. Because how long propagation will take
cannot be known ahead of time, the progress is reported as -1. You can however use the
progress tracker
to cancel propagation.progressTracker
- The progress tracker
that can be
used to cancel propagation.true
if propagation should stop; otherwise false
.public final void addPropagationFinishedEvent(EventHandler<SegmentPropagationEventArgs> value)
SegmentPropagator.propagateSegment(SegmentListResults,SegmentConfiguration,ITrackCalculationProgress)
method.public final void removePropagationFinishedEvent(EventHandler<SegmentPropagationEventArgs> value)
SegmentPropagator.propagateSegment(SegmentListResults,SegmentConfiguration,ITrackCalculationProgress)
method.@Nonnull public final SegmentDefinition getIdentifier()
definition
that created this propagator.
This is to only be used as an identifier.@Nonnull public final IntegrationSense getPropagationDirection()
public String toString()
java.lang.Object
toString
method returns a string that
"textually represents" this object. The result should
be a concise but informative representation that is easy for a
person to read.
It is recommended that all subclasses override this method.
The toString
method for class Object
returns a string consisting of the name of the class of which the
object is an instance, the at-sign character `@
', and
the unsigned hexadecimal representation of the hash code of the
object. In other words, this method returns a string equal to the
value of:
getClass().getName() + '@' + Integer.toHexString(hashCode())
@Nonnull public final List<StateElementAdapter> getAdapters()
StateElementAdapters
that this
segment can use in its propagation.public final String getName()
SegmentPropagator
.@Nonnull public final StateForNextSegmentBehavior getStateForNextSegmentBehavior()
SegmentPropagator
.protected final void defaultStateAdaptation(ITimeBasedState initialState, ITimeBasedState finalState)
adaptation
of the elements
in the initialState
into the finalState
. Note that
elements that do not exist in both states will not be adapted.public void applyResults(@Nonnull SegmentResults results)
results
.
For SegmentPropagators
that have
state, there may be times when that state should be manually set (sometimes
for performance considerations, when the propagator will be called multiple times and it should
start from where it left off).results
- The results to apply.@Nonnull public final SegmentConfiguration getOriginalConfiguration()
SegmentPropagator.propagateSegment(SegmentListResults,SegmentConfiguration,ITrackCalculationProgress)
method.protected final void setOriginalConfiguration(@Nonnull SegmentConfiguration value)
SegmentPropagator.propagateSegment(SegmentListResults,SegmentConfiguration,ITrackCalculationProgress)
method.@Nonnull public SegmentResults propagate(@Nullable SegmentListResults cumulativeResults, @Nullable SegmentConfiguration editedConfiguration, @Nullable ITrackCalculationProgress progressTracker)
cumulativeResults
- The results
of propagation
up to this point.editedConfiguration
- The segment configuration that some
other segment has determined that this segment should run. If it is null
then use this
segments OriginalConfiguration
(get
/ set
).progressTracker
- An optional progress tracker
.
How long the segment will take to propagate generally is not known ahead of time, so the reported
progress completed is set to -1. However you can cancel propagation with the tracker.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public SegmentResults propagate()
RuntimeException
in such a case.
Depending on the segment type being propagated
the SegmentResults
returned can be safely cast to a more specific type. See the class documentation for
the derived type for more information.
segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public final SegmentResults propagate(@Nullable SegmentListResults cumulativeResults)
cumulativeResults
- The results of all propagation up to this point. This may be null
if this segment is not being propagated in a SegmentListPropagator
.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public final SegmentResults propagate(ITimeBasedState initialState)
initialState
.initialState
- The initial state for this segment to propagate from. This is akin to the
final state of the previous segment; it will be processed by the Adapters
(get
) before being
propagated.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public final SegmentResults propagate(ITimeBasedState initialState, @Nullable SegmentListResults cumulativeResults)
initialState
.initialState
- The initial state for this segment to propagate from. This is usually the
final state of the previous segment. It will be processed by any the Adapters
(get
) before being
propagated.cumulativeResults
- The results of the SegmentListPropagator
that contains this segment. This may
be null
if this segment is being propagated independent of a
SegmentListPropagator
. In the simple case, this is only needed to provide the
StateForNextSegment
(get
) that this SegmentPropagator
should
start propagating from. However, if the concrete SegmentPropagator
will propagate multiple segments,
then the StateForNextSegment
(get
) must be set after each individual SegmentPropagator
is propagated. You may also need to maintain the SegmentResults
(get
) collection to
avoid having the same SegmentResults
included twice (the SegmentResults
for each SegmentPropagator
gets added automatically to the cumulativeResults
when it is propagated). Also, if there is even
the possibility of the SegmentPropagator
needing to back up into a previous segment, the
SegmentListResults.regenerateEphemerisForOverallTrajectory()
method after each child SegmentPropagator
is
propagated.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public final SegmentResults propagate(ITimeBasedState initialState, @Nullable ITrackCalculationProgress progressTracker)
initialState
.initialState
- The initial state for this segment to propagate from. This is usually the
final state of the previous segment. It will be processed by any the Adapters
(get
) before being
propagated.progressTracker
- An optional progress tracker
.
How long the segment will take to propagate generally is not known ahead of time, so the reported
progress completed is set to -1. However you can cancel propagation with the tracker.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull public final SegmentResults propagate(@Nonnull SegmentConfiguration editedConfiguration, @Nullable ITrackCalculationProgress progressTracker)
editedConfiguration
- The segment configuration that some
other segment has determined that this segment should run. If it is null
then use the
segments original configuration.progressTracker
- An optional progress tracker
.
How long the segment will take to propagate generally is not known ahead of time, so the reported
progress completed is set to -1. However you can cancel propagation with the tracker.segments propagation results
. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nonnull protected abstract SegmentResults propagateSegment(@Nullable SegmentListResults cumulativeResults, @Nullable SegmentConfiguration editedConfiguration, @Nullable ITrackCalculationProgress progressTracker)
SegmentPropagator.propagate()
method most appropriate to your problem.cumulativeResults
- The results of the SegmentListPropagator
that contains this segment. This may
be null
if this segment is being propagated independent of a
SegmentListPropagator
. In the simple case, this is only needed to provide the
StateForNextSegment
(get
) that this SegmentPropagator
should
start propagating from. However, if the concrete SegmentPropagator
will propagate multiple segments,
then the StateForNextSegment
(get
) must be set after each individual SegmentPropagator
is propagated. You may also need to maintain the SegmentResults
(get
) collection to
avoid having the same SegmentResults
included twice (the SegmentResults
for each SegmentPropagator
gets added automatically to the cumulativeResults
when it is propagated). Also, if there is even
the possibility of the SegmentPropagator
needing to back up into a previous segment, the
SegmentListResults.regenerateEphemerisForOverallTrajectory()
method after each child SegmentPropagator
is
propagated.editedConfiguration
- The segment configuration that some
other segment has determined that this segment should run. If it is null
then use the
segments OriginalConfiguration
(get
/ set
).progressTracker
- An optional progress tracker
.
How long the segment will take to propagate generally is not known ahead of time, so the reported
progress completed is set to -1. However you can cancel propagation with the tracker.segments propagation results
. This method must fill in all of the relevant
properties in the returned results. See the documentation of the
derived type to determine if these SegmentResults
may be cast to a more specific type.@Nullable public abstract ITimeBasedState propagateTo(@Nonnull SegmentResults results, @Nonnull JulianDate dateToPropagateTo)
Propagates a segment to the time or independent variable specified in the dateToPropagateTo
.
This method is needed to assist the case when segments
might
overlap. If a later segment
realizes that it needs to find a different
final state from this SegmentPropagator
, this method should be used to find that new final state.
Consider calling SegmentListResults.propagateToAssumingTimeBasedStates(agi.foundation.time.JulianDate, agi.foundation.segmentpropagation.SegmentResults, agi.foundation.segmentpropagation.SegmentListResults)
instead of this method directly.
For segments that happen instantaneously then this should
just return the state computed (although generally this method should never
need to be called on such segments since there is no "when" to propagate to, you can pull the state from the
results
directly). For a segment that produces
an ephemeris, this should find the state right before the offset's independent variable and take one step
to that independent variable. If the segment returns
two states at the same time, PropagationDirection
(get
) should be checked, and if propagation is
IntegrationSense.INCREASING
the final state should be returned, or the initial state
if propagation is backwards
.
results
- The results
previously computed by this
SegmentPropagator
. When used with a SegmentListPropagator
, the results of the actual
nested SegmentPropagator
should be passed in.dateToPropagateTo
- The date of the returned state.state
at dateToPropagateTo
.