136 lines
3.9 KiB
C++
136 lines
3.9 KiB
C++
/* +------------------------------------------------------+
|
|
____/ \____ /| - Open source game framework licensed to freely use, |
|
|
\ / / | copy, modify and sell without restriction |
|
|
+--\ ^__^ /--+ | |
|
|
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
|
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
|
| SPACE ~~~~~ | /
|
|
| ~~~~~~~ BOX |/
|
|
+--------------+
|
|
|
|
A switch object contains a state of either on or off which can be read by reading the switch in a bool context. A
|
|
switch can be flipped to change the state. If a reaction function has been set, it will run every time the switch
|
|
is flipped. The function must accept a bool as its first argument which will provide the state of the switch. It can
|
|
also accept an arbitrary number of arguments after that and can return a value.
|
|
|
|
This example will flip the switch three times and print the state each time.
|
|
|
|
sb::Switch<> sw1;
|
|
sw1.on_state_change([](bool state) {
|
|
std::cout << "Door is " << (state ? "OPEN" : "CLOSED") << std::endl;
|
|
});
|
|
sw1.flip();
|
|
sw1.flip();
|
|
sw1.flip();
|
|
|
|
The expected output is
|
|
|
|
Door is OPEN
|
|
Door is CLOSED
|
|
Door is OPEN
|
|
|
|
This example ignores the switch state and adds an arbitrary amount to a running tally each flip.
|
|
|
|
sb::Switch<int, int, int> sw2;
|
|
sw2.on_state_change([](bool state, int tally, int add) -> int {
|
|
tally += add;
|
|
std::cout << "Adding " << add << " to tally: " << tally << std::endl;
|
|
return tally;
|
|
});
|
|
int tally = 0;
|
|
tally = sw2.flip(tally, 1);
|
|
tally = sw2.flip(tally, 5);
|
|
tally = sw2.flip(tally, 99);
|
|
|
|
The expected output is
|
|
|
|
Adding 1 to tally: 1
|
|
Adding 5 to tally: 6
|
|
Adding 99 to tally: 105
|
|
|
|
Although the state can just be ignored, it can also be forced to remain in one state. This example uses the
|
|
`&` operator to allow access to the switch itself so it can be turned off automatically after every flip.
|
|
|
|
sb::Switch<void, const std::string&> sw3;
|
|
sw3.on_state_change([&](bool state, const std::string& visitor) {
|
|
if (state)
|
|
{
|
|
std::cout << "Come in " << visitor << ", my door is always " << (state ? "OPEN" : "CLOSED") << std::endl;
|
|
sw3.flip("");
|
|
}
|
|
});
|
|
sw3.flip("Mario");
|
|
sw3.flip("Luigi");
|
|
sw3.flip("Toad");
|
|
|
|
The expected output is
|
|
|
|
Come in Mario, my door is always OPEN
|
|
Come in Luigi, my door is always OPEN
|
|
Come in Toad, my door is always OPEN
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <functional>
|
|
|
|
namespace sb
|
|
{
|
|
template<typename return_type = void, typename... arguments>
|
|
class Switch
|
|
{
|
|
|
|
private:
|
|
|
|
using Reaction = std::function<return_type(bool, arguments...)>;
|
|
inline static const bool STATE_OFF = false;
|
|
inline static const bool STATE_ON = true;
|
|
|
|
bool state = STATE_OFF;
|
|
Reaction reaction;
|
|
|
|
public:
|
|
|
|
/*!
|
|
* The switch object will initialized to the off state. A reaction function can be specified, otherwise it will have an
|
|
* empty reaction function.
|
|
*
|
|
* @param callback function to run on state change
|
|
*/
|
|
Switch(Reaction reaction = Reaction()) : reaction(reaction) {}
|
|
|
|
return_type flip(arguments... args)
|
|
{
|
|
state = !state;
|
|
return reaction(state, args...);
|
|
}
|
|
|
|
/*!
|
|
* Assign the reaction function.
|
|
*
|
|
* @param reaction function to be called when the state is changed
|
|
*/
|
|
void on_state_change(Reaction reaction)
|
|
{
|
|
this->reaction = reaction;
|
|
}
|
|
|
|
/*!
|
|
* @return true if state is Switch::STATE_ON, false otherwise
|
|
*/
|
|
bool on()
|
|
{
|
|
return state;
|
|
}
|
|
|
|
/*!
|
|
* @return when called as a boolean, return state
|
|
*/
|
|
operator bool()
|
|
{
|
|
return on();
|
|
}
|
|
|
|
};
|
|
}
|