Merge pull request #759 from CapeLeidokos/pr_sketch_exploration_fix

Sketch exploration fix for empty keymaps
pull/765/head
Gergely Nagy 5 years ago committed by GitHub
commit d16397aae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -47,6 +47,22 @@ class KeymapAdaptor {
} }
}; };
// A special case for empty keymaps that makes the compiler happy.
//
class EmptyKeymapAdaptor {
public:
static constexpr uint8_t n_layers = 0;
static constexpr uint8_t layer_size = 0;
constexpr Key getKey(uint8_t layer, uint8_t offset) const {
return Key_NoKey;
}
constexpr Key getKey(uint8_t layer, KeyAddr key_addr) const {
return Key_NoKey;
}
};
// This class implements compile time keymap traversal. // This class implements compile time keymap traversal.
// //
// Every key is visited an the _Accumulation functor decides on how // Every key is visited an the _Accumulation functor decides on how
@ -91,6 +107,27 @@ class AccumulationHelper : public KeymapAdaptor<_n_layers, _layer_size> {
} }
}; };
// A special case for empty keymaps that makes the compiler happy.
//
template<typename _Accumulation>
class EmptyKeymapAccumulationHelper {
private:
const _Accumulation &op_;
typedef typename _Accumulation::ResultType ResultType;
public:
constexpr EmptyKeymapAccumulationHelper(const _Accumulation &op)
: op_{op}
{}
constexpr ResultType apply() const {
return op_.init_value;
}
};
// Accumulation functors to be used with the KeymapInterface's collect // Accumulation functors to be used with the KeymapInterface's collect
// method. // method.
// //
@ -179,10 +216,9 @@ extern void pluginsExploreSketch();
#define _INIT_KEYMAP_EXPLORATION \ #define _INIT_KEYMAP_EXPLORATION \
namespace kaleidoscope { \ namespace kaleidoscope { \
namespace sketch_exploration { \ namespace sketch_exploration { \
class StaticKeymap \
{ \
private: \
\ \
template<bool _keymap_is_empty> \
struct StaticKeymapHelper { \
template<int _n_layers, int _layer_size, typename _Accumulation> \ template<int _n_layers, int _layer_size, typename _Accumulation> \
static constexpr auto accumulationHelper( \ static constexpr auto accumulationHelper( \
const Key (&keymap)[_n_layers][_layer_size], \ const Key (&keymap)[_n_layers][_layer_size], \
@ -193,13 +229,6 @@ extern void pluginsExploreSketch();
_Accumulation>{keymap, op}; \ _Accumulation>{keymap, op}; \
} \ } \
\ \
template<typename _Accumulation> \
static constexpr auto accumulationHelper(const _Accumulation &op) \
-> decltype(accumulationHelper(::keymaps_linear, op)) \
{ \
return accumulationHelper(::keymaps_linear, op); \
} \
\
template<int _n_layers, int _layer_size> \ template<int _n_layers, int _layer_size> \
static constexpr auto keymapAdaptor( \ static constexpr auto keymapAdaptor( \
const Key (&keymap)[_n_layers][_layer_size]) \ const Key (&keymap)[_n_layers][_layer_size]) \
@ -207,12 +236,35 @@ extern void pluginsExploreSketch();
{ \ { \
return KeymapAdaptor<_n_layers, _layer_size>{keymap}; \ return KeymapAdaptor<_n_layers, _layer_size>{keymap}; \
} \ } \
}; \
\
/* Empty keymaps need a special treatment */ \
template<> \
struct StaticKeymapHelper<true> { \
\ \
static constexpr auto keymapAdaptor() \ template<typename _Accumulation> \
-> decltype(keymapAdaptor(::keymaps_linear)) \ static constexpr auto accumulationHelper(const _Accumulation &op) \
-> decltype(EmptyKeymapAccumulationHelper<_Accumulation>{op}) \
{ \
return EmptyKeymapAccumulationHelper<_Accumulation>{op}; \
} \
\
template<typename _Keymap> \
static constexpr auto keymapAdaptor(const _Keymap &) \
-> EmptyKeymapAdaptor \
{ \ { \
return keymapAdaptor(::keymaps_linear); \ return EmptyKeymapAdaptor{}; \
} \ } \
}; \
\
class StaticKeymap \
{ \
private: \
\
static constexpr bool keymap_is_empty \
= (sizeof(::keymaps_linear) == 0); \
\
typedef StaticKeymapHelper<keymap_is_empty> SKH; \
\ \
public: \ public: \
\ \
@ -233,20 +285,20 @@ extern void pluginsExploreSketch();
static constexpr auto collect(const _Accumulation &op) \ static constexpr auto collect(const _Accumulation &op) \
-> typename _Accumulation::ResultType \ -> typename _Accumulation::ResultType \
{ \ { \
return accumulationHelper(op).apply(); \ return SKH::accumulationHelper(::keymaps_linear, op).apply(); \
} \ } \
\ \
/* COMPILE_TIME_USE_ONLY (see explanation above) \ /* COMPILE_TIME_USE_ONLY (see explanation above) \
*/ \ */ \
static constexpr Key getKey(uint8_t layer, KeyAddr key_addr) { \ static constexpr Key getKey(uint8_t layer, KeyAddr key_addr) { \
return keymapAdaptor().getKey(layer, key_addr); \ return SKH::keymapAdaptor(::keymaps_linear).getKey(layer, key_addr); \
} \ } \
\ \
static constexpr uint8_t nLayers() { \ static constexpr uint8_t nLayers() { \
return keymapAdaptor().n_layers; \ return SKH::keymapAdaptor(::keymaps_linear).n_layers; \
} \ } \
static constexpr uint8_t layerSize() { \ static constexpr uint8_t layerSize() { \
return keymapAdaptor().layer_size; \ return SKH::keymapAdaptor(::keymaps_linear).layer_size; \
} \ } \
}; \ }; \
} /* namespace sketch_exploration */ \ } /* namespace sketch_exploration */ \

@ -0,0 +1,28 @@
/* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2013-2019 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace kaleidoscope {
\
namespace sketch_exploration {
// This empty weak symbol is necessary if the KEYMAP(...) macro
// is not used in the sketch.
//
__attribute__((weak))
void pluginsExploreSketch() {}
} // namespace sketch_exploration
} // namespace kaleidoscope
Loading…
Cancel
Save