Some changes suggested by cppcheck
parent
0923306404
commit
7dc30a01cd
@ -1,75 +0,0 @@
|
|||||||
#ifndef OENGINE_INPUT_DISPATCHMAP_H
|
|
||||||
#define OENGINE_INPUT_DISPATCHMAP_H
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace OEngine {
|
|
||||||
namespace Input {
|
|
||||||
|
|
||||||
/**
|
|
||||||
DispatchMap is a simple connection system that connects incomming
|
|
||||||
signals with outgoing signals.
|
|
||||||
|
|
||||||
The signals can be connected one-to-one, many-to-one, one-to-many
|
|
||||||
or many-to-many.
|
|
||||||
|
|
||||||
The dispatch map is completely system agnostic. It is a pure data
|
|
||||||
structure and all signals are just integer indices. It does not
|
|
||||||
delegate any actions, but used together with Dispatcher it can be
|
|
||||||
used to build an event system.
|
|
||||||
*/
|
|
||||||
struct DispatchMap
|
|
||||||
{
|
|
||||||
typedef std::set<int> OutList;
|
|
||||||
typedef std::map<int, OutList> InMap;
|
|
||||||
|
|
||||||
typedef OutList::iterator Oit;
|
|
||||||
typedef InMap::iterator Iit;
|
|
||||||
|
|
||||||
InMap map;
|
|
||||||
|
|
||||||
void bind(int in, int out)
|
|
||||||
{
|
|
||||||
map[in].insert(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void unbind(int in, int out)
|
|
||||||
{
|
|
||||||
Iit it = map.find(in);
|
|
||||||
if(it != map.end())
|
|
||||||
{
|
|
||||||
it->second.erase(out);
|
|
||||||
|
|
||||||
// If there are no more elements, then remove the entire list
|
|
||||||
if(it->second.empty())
|
|
||||||
map.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a given input is bound to anything
|
|
||||||
bool isBound(int in) const
|
|
||||||
{
|
|
||||||
return map.find(in) != map.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the list of outputs bound to the given input. Only call this
|
|
||||||
on inputs that you know are bound to something.
|
|
||||||
|
|
||||||
The returned set is only intended for immediate iteration. Do not
|
|
||||||
store references to it.
|
|
||||||
*/
|
|
||||||
const OutList &getList(int in) const
|
|
||||||
{
|
|
||||||
assert(isBound(in));
|
|
||||||
InMap::const_iterator it = map.find(in);
|
|
||||||
assert(it != map.end());
|
|
||||||
const OutList &out = it->second;
|
|
||||||
assert(!out.empty());
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
#endif
|
|
@ -1,78 +0,0 @@
|
|||||||
#ifndef OENGINE_INPUT_DISPATCHER_H
|
|
||||||
#define OENGINE_INPUT_DISPATCHER_H
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <mangle/input/event.hpp>
|
|
||||||
|
|
||||||
#include "dispatch_map.hpp"
|
|
||||||
#include "func_binder.hpp"
|
|
||||||
|
|
||||||
namespace OEngine {
|
|
||||||
namespace Input {
|
|
||||||
|
|
||||||
struct Dispatcher : Mangle::Input::Event
|
|
||||||
{
|
|
||||||
DispatchMap map;
|
|
||||||
FuncBinder funcs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Constructor. Takes the number of actions and passes it to
|
|
||||||
FuncBinder.
|
|
||||||
*/
|
|
||||||
Dispatcher(int actions) : funcs(actions) {}
|
|
||||||
|
|
||||||
void bind(unsigned int action, int key)
|
|
||||||
{
|
|
||||||
assert(action < funcs.getSize());
|
|
||||||
map.bind(key, action);
|
|
||||||
}
|
|
||||||
void unbind(unsigned int action, int key)
|
|
||||||
{
|
|
||||||
assert(action < funcs.getSize());
|
|
||||||
map.unbind(key, action);
|
|
||||||
}
|
|
||||||
bool isBound(int key) const { return map.isBound(key); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
Instigate an event. It is translated through the dispatch map and
|
|
||||||
sent to the function bindings.
|
|
||||||
*/
|
|
||||||
typedef DispatchMap::OutList _O;
|
|
||||||
void event(Type type, int index, const void* p)
|
|
||||||
{
|
|
||||||
// No bindings, nothing happens
|
|
||||||
if(!isBound(index))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Get the mapped actions and execute them
|
|
||||||
const _O &list = map.getList(index);
|
|
||||||
_O::const_iterator it;
|
|
||||||
for(it = list.begin(); it != list.end(); it++)
|
|
||||||
{
|
|
||||||
//catch exceptions thrown in the input handlers so that pressing a key
|
|
||||||
//doesn't cause OpenMw to crash
|
|
||||||
try
|
|
||||||
{
|
|
||||||
funcs.call(*it, p);
|
|
||||||
}
|
|
||||||
catch(const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cerr << "Exception in input handler: " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
std::cerr << "Unknown exception in input handler" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This helps us play nice with Mangle's EventPtr, but it should
|
|
||||||
// really be defined for all the classes in OEngine.
|
|
||||||
typedef boost::shared_ptr<Dispatcher> DispatcherPtr;
|
|
||||||
|
|
||||||
}}
|
|
||||||
#endif
|
|
@ -1,106 +0,0 @@
|
|||||||
#ifndef OENGINE_INPUT_FUNCBINDER_H
|
|
||||||
#define OENGINE_INPUT_FUNCBINDER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace OEngine {
|
|
||||||
namespace Input {
|
|
||||||
|
|
||||||
/**
|
|
||||||
An Action defines the user defined action corresponding to a
|
|
||||||
binding.
|
|
||||||
|
|
||||||
The first parameter is the action index that invoked this call. You
|
|
||||||
can assign the same function to multiple actions, and this can help
|
|
||||||
you keep track of which action was invoked.
|
|
||||||
|
|
||||||
The second parameter is an optional user-defined parameter,
|
|
||||||
represented by a void pointer. In many cases it is practical to
|
|
||||||
point this to temporaries (stack values), so make sure not to store
|
|
||||||
permanent references to it unless you've planning for this on the
|
|
||||||
calling side as well.
|
|
||||||
*/
|
|
||||||
typedef boost::function<void(int,const void*)> Action;
|
|
||||||
|
|
||||||
/**
|
|
||||||
The FuncBinder is a simple struct that binds user-defined indices
|
|
||||||
to functions. It is useful for binding eg. keyboard events to
|
|
||||||
specific actions in your program, but can potentially have many
|
|
||||||
other uses as well.
|
|
||||||
*/
|
|
||||||
class FuncBinder
|
|
||||||
{
|
|
||||||
struct FuncBinding
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
Action action;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<FuncBinding> bindings;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
Constructor. Initialize the struct by telling it how many action
|
|
||||||
indices you intend to bind.
|
|
||||||
|
|
||||||
The indices you use should be 0 <= i < number.
|
|
||||||
*/
|
|
||||||
FuncBinder(int number) : bindings(number) {}
|
|
||||||
|
|
||||||
unsigned int getSize() { return bindings.size(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
Bind an action to an index.
|
|
||||||
*/
|
|
||||||
void bind(int index, Action action, const std::string &name="")
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < (int)bindings.size());
|
|
||||||
|
|
||||||
FuncBinding &fb = bindings[index];
|
|
||||||
fb.action = action;
|
|
||||||
fb.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Unbind an index, reverting a previous bind().
|
|
||||||
*/
|
|
||||||
void unbind(int index)
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < (int)bindings.size());
|
|
||||||
|
|
||||||
bindings[index] = FuncBinding();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Call a specific action. Takes an optional parameter that is
|
|
||||||
passed to the action.
|
|
||||||
*/
|
|
||||||
void call(int index, const void *p=NULL) const
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < (int)bindings.size());
|
|
||||||
|
|
||||||
const FuncBinding &fb = bindings[index];
|
|
||||||
if(fb.action) fb.action(index, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if a given index is bound to anything
|
|
||||||
bool isBound(int index) const
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < (int)bindings.size());
|
|
||||||
|
|
||||||
return !bindings[index].action.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the name associated with an action (empty if not bound)
|
|
||||||
const std::string &getName(int index) const
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < (int)bindings.size());
|
|
||||||
|
|
||||||
return bindings[index].name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
#endif
|
|
@ -1,46 +0,0 @@
|
|||||||
#ifndef OENGINE_INPUT_POLLER_H
|
|
||||||
#define OENGINE_INPUT_POLLER_H
|
|
||||||
|
|
||||||
#include "dispatch_map.hpp"
|
|
||||||
#include <mangle/input/driver.hpp>
|
|
||||||
|
|
||||||
namespace OEngine {
|
|
||||||
namespace Input {
|
|
||||||
|
|
||||||
/** The poller is used to check (poll) for keys rather than waiting
|
|
||||||
for events. */
|
|
||||||
struct Poller
|
|
||||||
{
|
|
||||||
DispatchMap map;
|
|
||||||
Mangle::Input::Driver &input;
|
|
||||||
|
|
||||||
Poller(Mangle::Input::Driver &drv)
|
|
||||||
: input(drv) {}
|
|
||||||
|
|
||||||
/** Bind or unbind a given action with a key. The action is the first
|
|
||||||
parameter, the key is the second.
|
|
||||||
*/
|
|
||||||
void bind(int in, int out) { map.bind(in, out); }
|
|
||||||
void unbind(int in, int out) { map.unbind(in, out); }
|
|
||||||
bool isBound(int in) const { return map.isBound(in); }
|
|
||||||
|
|
||||||
/// Check whether a given action button is currently pressed.
|
|
||||||
typedef DispatchMap::OutList _O;
|
|
||||||
bool isDown(int index) const
|
|
||||||
{
|
|
||||||
// No bindings, no action
|
|
||||||
if(!isBound(index))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Get all the keys bound to this action, and check them.
|
|
||||||
const _O &list = map.getList(index);
|
|
||||||
_O::const_iterator it;
|
|
||||||
for(it = list.begin(); it != list.end(); it++)
|
|
||||||
// If there's any match, we're good to go.
|
|
||||||
if(input.isDown(*it)) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||||||
GCC=g++
|
|
||||||
|
|
||||||
all: funcbind_test dispatch_map_test sdl_driver_test sdl_binder_test
|
|
||||||
|
|
||||||
funcbind_test: funcbind_test.cpp ../func_binder.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
dispatch_map_test: dispatch_map_test.cpp ../dispatch_map.hpp
|
|
||||||
$(GCC) $< -o $@
|
|
||||||
|
|
||||||
sdl_driver_test: sdl_driver_test.cpp
|
|
||||||
$(GCC) $< ../../mangle/input/servers/sdl_driver.cpp -o $@ -I/usr/include/SDL/ -lSDL -I../../
|
|
||||||
|
|
||||||
sdl_binder_test: sdl_binder_test.cpp
|
|
||||||
$(GCC) $< ../../mangle/input/servers/sdl_driver.cpp -o $@ -I/usr/include/SDL/ -lSDL -I../../
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm *_test
|
|
@ -1,54 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "../dispatch_map.hpp"
|
|
||||||
|
|
||||||
using namespace OEngine::Input;
|
|
||||||
|
|
||||||
typedef DispatchMap::OutList OutList;
|
|
||||||
typedef OutList::const_iterator Cit;
|
|
||||||
|
|
||||||
void showList(const DispatchMap::OutList &out)
|
|
||||||
{
|
|
||||||
for(Cit it = out.begin();
|
|
||||||
it != out.end(); it++)
|
|
||||||
{
|
|
||||||
cout << " " << *it << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void showAll(DispatchMap &map)
|
|
||||||
{
|
|
||||||
cout << "\nPrinting everything:\n";
|
|
||||||
for(DispatchMap::Iit it = map.map.begin();
|
|
||||||
it != map.map.end(); it++)
|
|
||||||
{
|
|
||||||
cout << it->first << ":\n";
|
|
||||||
showList(map.getList(it->first));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
cout << "Testing the dispatch map\n";
|
|
||||||
|
|
||||||
DispatchMap dsp;
|
|
||||||
|
|
||||||
dsp.bind(1,9);
|
|
||||||
dsp.bind(2,-5);
|
|
||||||
dsp.bind(2,9);
|
|
||||||
dsp.bind(3,10);
|
|
||||||
dsp.bind(3,12);
|
|
||||||
dsp.bind(3,10);
|
|
||||||
|
|
||||||
showAll(dsp);
|
|
||||||
|
|
||||||
dsp.unbind(1,9);
|
|
||||||
dsp.unbind(5,8);
|
|
||||||
dsp.unbind(3,11);
|
|
||||||
dsp.unbind(3,12);
|
|
||||||
dsp.unbind(3,12);
|
|
||||||
|
|
||||||
showAll(dsp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "../func_binder.hpp"
|
|
||||||
|
|
||||||
void f1(int i, const void *p)
|
|
||||||
{
|
|
||||||
cout << " F1 i=" << i << endl;
|
|
||||||
|
|
||||||
if(p)
|
|
||||||
cout << " Got a nice gift: "
|
|
||||||
<< *((const float*)p) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void f2(int i, const void *p)
|
|
||||||
{
|
|
||||||
cout << " F2 i=" << i << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace OEngine::Input;
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
cout << "This will test the function binding system\n";
|
|
||||||
|
|
||||||
FuncBinder bnd(5);
|
|
||||||
|
|
||||||
bnd.bind(0, &f1, "This is action 1");
|
|
||||||
bnd.bind(1, &f2);
|
|
||||||
bnd.bind(2, &f1, "This is action 3");
|
|
||||||
bnd.bind(3, &f2, "This is action 4");
|
|
||||||
|
|
||||||
bnd.unbind(2);
|
|
||||||
|
|
||||||
for(int i=0; i<5; i++)
|
|
||||||
{
|
|
||||||
cout << "Calling " << i << ": '" << bnd.getName(i) << "'\n";
|
|
||||||
bnd.call(i);
|
|
||||||
if(!bnd.isBound(i)) cout << " (not bound)\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "\nCalling with parameter:\n";
|
|
||||||
float f = 3.1415;
|
|
||||||
bnd.call(0, &f);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
Testing the dispatch map
|
|
||||||
|
|
||||||
Printing everything:
|
|
||||||
1:
|
|
||||||
9
|
|
||||||
2:
|
|
||||||
-5
|
|
||||||
9
|
|
||||||
3:
|
|
||||||
10
|
|
||||||
12
|
|
||||||
|
|
||||||
Printing everything:
|
|
||||||
2:
|
|
||||||
-5
|
|
||||||
9
|
|
||||||
3:
|
|
||||||
10
|
|
@ -1,15 +0,0 @@
|
|||||||
This will test the function binding system
|
|
||||||
Calling 0: 'This is action 1'
|
|
||||||
F1 i=0
|
|
||||||
Calling 1: ''
|
|
||||||
F2 i=1
|
|
||||||
Calling 2: ''
|
|
||||||
(not bound)
|
|
||||||
Calling 3: 'This is action 4'
|
|
||||||
F2 i=3
|
|
||||||
Calling 4: ''
|
|
||||||
(not bound)
|
|
||||||
|
|
||||||
Calling with parameter:
|
|
||||||
F1 i=0
|
|
||||||
Got a nice gift: 3.1415
|
|
@ -1,4 +0,0 @@
|
|||||||
Hold the Q key to quit:
|
|
||||||
You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly
|
|
||||||
|
|
||||||
Bye bye!
|
|
@ -1,4 +0,0 @@
|
|||||||
Hold the Q key to quit:
|
|
||||||
You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly
|
|
||||||
|
|
||||||
Bye bye!
|
|
@ -1,71 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <mangle/input/servers/sdl_driver.hpp>
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "../dispatcher.hpp"
|
|
||||||
#include "../poller.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Mangle::Input;
|
|
||||||
using namespace OEngine::Input;
|
|
||||||
|
|
||||||
enum Actions
|
|
||||||
{
|
|
||||||
A_Quit,
|
|
||||||
A_Left,
|
|
||||||
A_Right,
|
|
||||||
|
|
||||||
A_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
bool quit=false;
|
|
||||||
|
|
||||||
void doExit(int,const void*)
|
|
||||||
{
|
|
||||||
quit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void goLeft(int,const void*)
|
|
||||||
{
|
|
||||||
cout << "Going left\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE);
|
|
||||||
SDLDriver input;
|
|
||||||
Dispatcher *disp = new Dispatcher(A_LAST);
|
|
||||||
Poller poll(input);
|
|
||||||
|
|
||||||
input.setEvent(EventPtr(disp));
|
|
||||||
|
|
||||||
disp->funcs.bind(A_Quit, &doExit);
|
|
||||||
disp->funcs.bind(A_Left, &goLeft);
|
|
||||||
|
|
||||||
disp->bind(A_Quit, SDLK_q);
|
|
||||||
disp->bind(A_Left, SDLK_a);
|
|
||||||
disp->bind(A_Left, SDLK_LEFT);
|
|
||||||
|
|
||||||
poll.bind(A_Right, SDLK_d);
|
|
||||||
poll.bind(A_Right, SDLK_RIGHT);
|
|
||||||
|
|
||||||
cout << "Hold the Q key to quit:\n";
|
|
||||||
//input->setEvent(&mycb);
|
|
||||||
while(!quit)
|
|
||||||
{
|
|
||||||
input.capture();
|
|
||||||
if(poll.isDown(A_Right))
|
|
||||||
cout << "We're going right!\n";
|
|
||||||
SDL_Delay(20);
|
|
||||||
|
|
||||||
if(argc == 1)
|
|
||||||
{
|
|
||||||
cout << "You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << "\nBye bye!\n";
|
|
||||||
|
|
||||||
SDL_Quit();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
#include <mangle/input/servers/sdl_driver.hpp>
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace Mangle::Input;
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
|
||||||
SDL_SetVideoMode(640, 480, 0, SDL_SWSURFACE);
|
|
||||||
SDLDriver input;
|
|
||||||
|
|
||||||
cout << "Hold the Q key to quit:\n";
|
|
||||||
//input->setEvent(&mycb);
|
|
||||||
while(!input.isDown(SDLK_q))
|
|
||||||
{
|
|
||||||
input.capture();
|
|
||||||
SDL_Delay(20);
|
|
||||||
|
|
||||||
if(argc == 1)
|
|
||||||
{
|
|
||||||
cout << "You are running in script mode, aborting. Run this test with a parameter (any at all) to test the input loop properly\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << "\nBye bye!\n";
|
|
||||||
|
|
||||||
SDL_Quit();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
make || exit
|
|
||||||
|
|
||||||
mkdir -p output
|
|
||||||
|
|
||||||
PROGS=*_test
|
|
||||||
|
|
||||||
for a in $PROGS; do
|
|
||||||
if [ -f "output/$a.out" ]; then
|
|
||||||
echo "Running $a:"
|
|
||||||
./$a | diff output/$a.out -
|
|
||||||
else
|
|
||||||
echo "Creating $a.out"
|
|
||||||
./$a > "output/$a.out"
|
|
||||||
git add "output/$a.out"
|
|
||||||
fi
|
|
||||||
done
|
|
Loading…
Reference in New Issue