156 lines
5.3 KiB
C++
156 lines
5.3 KiB
C++
/* +------------------------------------------------------+
|
|
____/ \____ /| - Open source game framework licensed to freely use, |
|
|
\ / / | copy, modify and sell without restriction |
|
|
+--\ ^__^ /--+ | |
|
|
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
|
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
|
| SPACE ~~~~~ | /
|
|
| ~~~~~~~ BOX |/
|
|
+--------------+
|
|
|
|
Connection objects contain a binary state of either on (connected) or off (not connected). When their state
|
|
is changed, an optional user supplied function corresponding to the state change is run automatically.
|
|
|
|
The functions each have the same return type, number of arguments, and argument types determined by the
|
|
template arguments.
|
|
|
|
By default, the state must change in order for a callback to be triggered. To allow repeat calls to
|
|
trigger a callback, the
|
|
|
|
Original test code:
|
|
|
|
Connection<> connection_d(std::bind(&Game::print_frame_length_history, this));
|
|
connection_d.toggle();
|
|
Connection<int, int, int> connection_f {
|
|
std::function<int(int, int)>(&glm::mod), std::function<int(int, int)>(&glm::mod) };
|
|
Connection<> connection_g = connection_d;
|
|
connection_g.toggle();
|
|
connection_g.disconnect();
|
|
int result;
|
|
result = connection_f.connect(3, 5);
|
|
std::cout << result << " ";
|
|
std::cout << connection_f.disconnect(20, 6) << " ";
|
|
result = connection_f.toggle(800, 120);
|
|
std::cout << result << std::endl;
|
|
result = connection_f.connect(111, 44);
|
|
std::cout << result << std::endl;
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <functional>
|
|
|
|
namespace sb
|
|
{
|
|
|
|
template<typename return_type = void, typename... arguments>
|
|
class Connection
|
|
{
|
|
|
|
private:
|
|
|
|
enum State : bool
|
|
{
|
|
STATE_OFF,
|
|
STATE_ON
|
|
};
|
|
|
|
using callback = std::function<return_type(arguments...)>;
|
|
|
|
State connection_state = STATE_OFF;
|
|
callback on_connect_callback, on_disconnect_callback;
|
|
|
|
public:
|
|
|
|
/*!
|
|
* Without any arguments, the connection object will be in the disconnected state with empty functions. Otherwise,
|
|
* the supplied functions will be added to the connection object. The first function argument will be run on a
|
|
* connection, and the second function argument will be run on a disconnection.
|
|
*
|
|
* @param on_connect_callback function to run on connection
|
|
* @param on_disconnect_callback function to run on disconnection
|
|
*/
|
|
Connection(callback on_connect_callback = callback(), callback on_disconnect_callback = callback())
|
|
{
|
|
if (on_connect_callback)
|
|
{
|
|
on_connect(on_connect_callback);
|
|
if (on_disconnect_callback)
|
|
{
|
|
on_disconnect(on_disconnect_callback);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Set the function that will run when a connection is made. */
|
|
void on_connect(callback on_connect)
|
|
{
|
|
on_connect_callback = on_connect;
|
|
}
|
|
|
|
/* Set the function that will run when a disconnection happens. */
|
|
void on_disconnect(callback on_disconnect)
|
|
{
|
|
on_disconnect_callback = on_disconnect;
|
|
}
|
|
|
|
/* Set state to Connection::STATE_ON and run response function. If return_type is non-void and the
|
|
* connection is already connected, the function will not run and the return value will be a default
|
|
* constructed value of the type return_type. Therefore, return_type must be default constructible. */
|
|
return_type connect(arguments... args)
|
|
{
|
|
if (!*this)
|
|
{
|
|
connection_state = STATE_ON;
|
|
if (on_connect_callback)
|
|
{
|
|
return on_connect_callback(args...);
|
|
}
|
|
}
|
|
return return_type();
|
|
}
|
|
|
|
/* Set state to Connection::STATE_OFF and run response function. If return_type is non-void and the
|
|
* connection is already disconnected, the function will not run and the return value will be a default
|
|
* constructed value of the type return_type. Therefore, return_type must be default constructible. */
|
|
return_type disconnect(arguments... args)
|
|
{
|
|
if (*this)
|
|
{
|
|
connection_state = STATE_OFF;
|
|
if (on_disconnect_callback)
|
|
{
|
|
return on_disconnect_callback(args...);
|
|
}
|
|
}
|
|
return return_type();
|
|
}
|
|
|
|
/* Set state to the opposite of current state, causing the appropriate response function to run. */
|
|
return_type toggle(arguments... args)
|
|
{
|
|
if (*this)
|
|
{
|
|
return disconnect(args...);
|
|
}
|
|
else
|
|
{
|
|
return connect(args...);
|
|
}
|
|
}
|
|
|
|
/* Return true if state is Connection::STATE_ON, false otherwise. */
|
|
bool connected()
|
|
{
|
|
return connection_state;
|
|
}
|
|
|
|
/* When called as a boolean, return the connection state. */
|
|
operator bool()
|
|
{
|
|
return connected();
|
|
}
|
|
|
|
};
|
|
}
|