Skip to content

Commit

Permalink
Add shift mode support
Browse files Browse the repository at this point in the history
  • Loading branch information
fredemmott committed Jun 30, 2022
1 parent cc8ad70 commit 2d4ab1d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ These can then be added to your code, as shown in `devicedb.h`.
- `HatToButtons`
- `LatchedToMomentaryButton`
- `MomentaryToLatchedButton`
- `Shift`
- `ShortPressLongPress`
- `SquareDeadzone`

Expand Down Expand Up @@ -318,6 +319,20 @@ Does the exact opposite of `LatchedToMomentaryButton`: it converts a short press
stick.Button1 >> MomentaryToLatchedButton() >> vj.Button1;
```

## Shift

Switches between actions, depending on an on/off state:

```C++
bool shifted = false;
stick.Button15 >> &shifted;
stick.Button16 >> Shift {
&shifted,
/* normal behavior */ vj.Button1,
/* shifted behavior */ vj.Button2,
};
```

## ShortPressLongPress

This divides a button into two, depending on if a button is pressed and quickly released, or held for a moment.
Expand Down
46 changes: 46 additions & 0 deletions lib/Shift.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020-present, Fred Emmott <[email protected]>
* All rights reserved.
*
* This source code is licensed under the ISC license found in the LICENSE file
* in the root directory of this source tree.
*/
#pragma once

#include "Sink.h"
#include "SinkPtr.h"

namespace fredemmott::inputmapping {

template <control T>
class Shift : public Sink<T> {
private:
bool* mShifted = nullptr;
SinkPtr<T> mA, mB;

public:
template <convertible_to_sink_ptr<T> A, convertible_to_sink_ptr<T> B>
Shift(bool* shifted, A&& a, B&& b)
: mShifted(shifted),
mA(convert_to_any_sink_ptr(std::forward<A>(a))),
mB(convert_to_any_sink_ptr(std::forward<B>(b))) {
}

virtual void map(typename T::Value value) override {
auto next = *mShifted ? mB : mA;
next->map(value);
}
};

// Help template inference along a bit...

template <convertible_to_sink_ptr<Axis> A, convertible_to_sink_ptr<Axis> B>
Shift(bool*, A, B) -> Shift<Axis>;

template <convertible_to_sink_ptr<Button> A, convertible_to_sink_ptr<Button> B>
Shift(bool*, A, B) -> Shift<Button>;

template <convertible_to_sink_ptr<Hat> A, convertible_to_sink_ptr<Hat> B>
Shift(bool*, A, B) -> Shift<Hat>;

}// namespace fredemmott::inputmapping
1 change: 1 addition & 0 deletions lib/easymode.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "LatchedToMomentaryButton.h"
#include "MomentaryToLatchedButton.h"
#include "Profile.h"
#include "Shift.h"
#include "ShortPressLongPress.h"
#include "SquareDeadzone.h"
#include "connections.h"
Expand Down
35 changes: 35 additions & 0 deletions tests/Shift_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020-present, Fred Emmott <[email protected]>
* All rights reserved.
*
* This source code is licensed under the ISC license found in the LICENSE file
* in the root directory of this source tree.
*/

#include "Shift.h"

#include "MappableVJoyOutput.h"
#include "tests.h"

using namespace fredemmott::inputmapping;

TEST_CASE("Shift") {
bool shifted = false;
TestButton button;
bool a = false, b = false;

button >> Shift(&shifted, &a, &b);

button.emit(true);
REQUIRE(a);
REQUIRE(!b);

button.emit(false);
REQUIRE(!a);
REQUIRE(!b);

shifted = true;
button.emit(true);
REQUIRE(!a);
REQUIRE(b);
}

0 comments on commit 2d4ab1d

Please sign in to comment.