-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #496 from leapmotion/feature-altitude
Add an altitude concept to describe filter priorities
- Loading branch information
Showing
9 changed files
with
169 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved. | ||
#pragma once | ||
|
||
namespace autowiring { | ||
|
||
/// <summary> | ||
/// Defines the altitude enumeration concept for AutoFilter instances | ||
/// </summary> | ||
/// <remarks> | ||
/// A filter altitude is an indicator to the AutoFilter scheduler about when a particular filter | ||
/// should be scheduled to receive control. Altitude is a hard requirement, but is subject to | ||
/// a number of stipulations as to when it applies: | ||
/// | ||
/// 1) If two autofilters are both candidates to be run at the same time, the filter with the | ||
/// higher altitude will be run first. | ||
/// 2) If both filters have the same altitude, an arbitrary filter will be selected. | ||
/// 3) When the current filter returns control (IE, its AutoFilter routine returns), the next | ||
/// filter will be run. | ||
/// 4) Deferred AutoFilters are a special case. A deferred AutoFilter is considered to have | ||
/// returned control as soon as its execution has been scheduled; generally this happens very | ||
/// fast. | ||
/// 5) Altitudes only provide an order-of-execution guarantee if NO deferred AutoFilters have been | ||
/// declared in the network. | ||
/// </remarks> | ||
enum class altitude { | ||
// Highest altitude level. Reserved for temporary debug logic and other nonpermanent code that | ||
// must run before all other filter levels | ||
Highest = 0x9000, | ||
|
||
// Instrumentation level, for use with instrumentation code. Instrumentation code often needs to | ||
// observe the inputs to its AutoFilter before any other code has an opportunity to observe it, | ||
// because this code needs information about | ||
Instrumentation = 0x8000, | ||
|
||
// Default altitude for Deferred autofilters. Deferred autofilters are guaranteed to return very | ||
// quickly, even though they may do a lot of work, because they do not tie up the main thread. | ||
Dispatch = 0x7000, | ||
|
||
// Asynchronous filters are designed to be run with a higher priority than standard filters, | ||
// but are still expected to complete very quickly. Because their speedy behavior is implemented | ||
// by the filter, and not guaranteed by Autowiring, asynchronous filters are considered to | ||
// have a lower priority than Deferred filters. | ||
// | ||
// It is expected that AutoFilters which are marked as Asynchronous will do the majority of their | ||
// work in an std::async or other similar call. | ||
Asynchronous = 0x6000, | ||
|
||
// The realtime altitude is a higher-than-normal altitude which may have some tight timing requirements | ||
// but does not run in a separate thread. Realtime filters run after deferred filters have been | ||
// scheduled to run. | ||
Realtime = 0x5000, | ||
|
||
// Default altitude range. Unless otherwise specified, or the filter is marked Deferred, filters | ||
// will normally execute at this priority level. | ||
Standard = 0x4000, | ||
|
||
// Altitude indicator for filters with no hard timing requirements. This is a convenient place to put | ||
// filters that may have extensive CPU usage requirements, or which are not strongly impacted by timing. | ||
// Analytics and diagnostics are typically suitable for execution at the passive level. | ||
Passive = 0x3000, | ||
|
||
// Lowest altitude level. Reserved for temporary debug logic and other nonpermanent code that | ||
// must run after all other filter levels. | ||
Lowest = 0x2000 | ||
}; | ||
|
||
inline altitude operator+(altitude alt, int v) { | ||
return (altitude) ((int) alt + v); | ||
} | ||
|
||
/// <summary> | ||
/// Extracts the altitude of type T, if declared, or infers it if not | ||
/// </summary> | ||
/// <param name="T">The outer type of the AutoFilter</param> | ||
/// <param name="Default">The default to be used if one is not provied by T</param> | ||
template<class T, altitude Default = altitude::Standard> | ||
struct altitude_of { | ||
template<class U> | ||
static std::integral_constant<altitude, U::altitude> select(U*); | ||
|
||
template<class U> | ||
static std::integral_constant<altitude, Default> select(...); | ||
|
||
static const altitude value = decltype(select<T>(nullptr))::value; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved. | ||
#include "stdafx.h" | ||
#include <autowiring/autowiring.h> | ||
|
||
class AutoFilterAltitudeTest: | ||
public testing::Test | ||
{}; | ||
|
||
struct AltitudeValue {}; | ||
|
||
struct AltitudeMonotonicCounter { | ||
std::atomic<int> order{0}; | ||
}; | ||
|
||
template<autowiring::altitude A> | ||
struct HasProfilingAltitude { | ||
static const autowiring::altitude altitude = A; | ||
|
||
AutoRequired<AltitudeMonotonicCounter> ctr; | ||
int order = -1; | ||
|
||
void AutoFilter(const AltitudeValue& val) { | ||
order = ++ctr->order; | ||
} | ||
}; | ||
|
||
TEST_F(AutoFilterAltitudeTest, AltitudeDetection) { | ||
AutoFilterDescriptor desc(std::make_shared<HasProfilingAltitude<autowiring::altitude::Highest>>()); | ||
ASSERT_EQ(autowiring::altitude::Highest, desc.GetAltitude()) << "Filter altitude was not correctly inferred"; | ||
} | ||
|
||
TEST_F(AutoFilterAltitudeTest, StandardAltitudeArrangement) { | ||
AutoCurrentContext()->Initiate(); | ||
|
||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Standard>> alt3; | ||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Asynchronous>> alt1; | ||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Realtime>> alt2; | ||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Passive>> alt4; | ||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Lowest>> alt5; | ||
AutoRequired<HasProfilingAltitude<autowiring::altitude::Dispatch>> alt0; | ||
|
||
AutoRequired<AutoPacketFactory> factory; | ||
auto packet = factory->NewPacket(); | ||
packet->Decorate(AltitudeValue{}); | ||
|
||
// Now we verify things got invoked in the right order: | ||
ASSERT_EQ(1, alt0->order); | ||
ASSERT_EQ(2, alt1->order); | ||
ASSERT_EQ(3, alt2->order); | ||
ASSERT_EQ(4, alt3->order); | ||
ASSERT_EQ(5, alt4->order); | ||
ASSERT_EQ(6, alt5->order); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters