Canvas: allow also C++ callable entities as event callbacks.

This commit is contained in:
Thomas Geymayer
2013-10-12 00:29:37 +02:00
parent 9e3172cb04
commit 6deb77dd4d
7 changed files with 60 additions and 33 deletions
+13 -3
View File
@@ -320,12 +320,22 @@ namespace canvas
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
naRef Canvas::addEventListener(const nasal::CallContext& ctx) bool Canvas::addEventListener( const std::string& type,
const EventListener& cb )
{ {
if( !_root_group.get() ) if( !_root_group.get() )
naRuntimeError(ctx.c, "Canvas: No root group!"); throw std::runtime_error("Canvas::AddEventListener: no root group!");
return _root_group->addEventListener(ctx); return _root_group->addEventListener(type, cb);
}
//----------------------------------------------------------------------------
bool Canvas::addNasalEventListener(const std::string& type, naRef code)
{
if( !_root_group.get() )
throw std::runtime_error("Canvas::AddNasalEventListener: no root group!");
return _root_group->addNasalEventListener(type, code);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
+2 -1
View File
@@ -132,7 +132,8 @@ namespace canvas
void update(double delta_time_sec); void update(double delta_time_sec);
naRef addEventListener(const nasal::CallContext& ctx); bool addEventListener(const std::string& type, const EventListener& cb);
bool addNasalEventListener(const std::string& type, naRef code);
void setSizeX(int sx); void setSizeX(int sx);
void setSizeY(int sy); void setSizeY(int sy);
+9 -7
View File
@@ -28,7 +28,8 @@ namespace canvas
{ {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
EventListener::EventListener(naRef code, const SystemAdapterPtr& sys_adapter): NasalEventListener::NasalEventListener( naRef code,
const SystemAdapterPtr& sys_adapter ):
_code(code), _code(code),
_gc_key(-1), _gc_key(-1),
_sys(sys_adapter) _sys(sys_adapter)
@@ -39,23 +40,25 @@ namespace canvas
&& !naIsFunc(code) ) && !naIsFunc(code) )
throw std::runtime_error throw std::runtime_error
( (
"canvas::EventListener: invalid function argument" "canvas::NasalEventListener: invalid function argument"
); );
_gc_key = sys_adapter->gcSave(_code); _gc_key = sys_adapter->gcSave(_code);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
EventListener::~EventListener() NasalEventListener::~NasalEventListener()
{ {
assert( !_sys.expired() ); if( !_sys.expired() )
_sys.lock()->gcRelease(_gc_key); _sys.lock()->gcRelease(_gc_key);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void EventListener::call(const canvas::EventPtr& event) void NasalEventListener::operator()(const canvas::EventPtr& event) const
{ {
SystemAdapterPtr sys = _sys.lock(); SystemAdapterPtr sys = _sys.lock();
if( !sys )
return;
naRef args[] = { naRef args[] = {
nasal::Ghost<EventPtr>::create(sys->getNasalContext(), event) nasal::Ghost<EventPtr>::create(sys->getNasalContext(), event)
@@ -65,6 +68,5 @@ namespace canvas
sys->callMethod(_code, naNil(), num_args, args, naNil()); sys->callMethod(_code, naNil(), num_args, args, naNil());
} }
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+6 -5
View File
@@ -27,14 +27,15 @@ namespace simgear
namespace canvas namespace canvas
{ {
class EventListener class NasalEventListener:
public SGReferenced
{ {
public: public:
EventListener( naRef code, NasalEventListener( naRef code,
const SystemAdapterPtr& sys_adapter ); const SystemAdapterPtr& sys_adapter );
~EventListener(); ~NasalEventListener();
void call(const canvas::EventPtr& event); void operator()(const canvas::EventPtr& event) const;
protected: protected:
naRef _code; naRef _code;
+2 -1
View File
@@ -51,7 +51,6 @@ namespace canvas
SG_FWD_DECL(Text) SG_FWD_DECL(Text)
SG_FWD_DECL(Event) SG_FWD_DECL(Event)
SG_FWD_DECL(EventListener)
SG_FWD_DECL(MouseEvent) SG_FWD_DECL(MouseEvent)
SG_FWD_DECL(Placement) SG_FWD_DECL(Placement)
SG_FWD_DECL(SystemAdapter) SG_FWD_DECL(SystemAdapter)
@@ -73,6 +72,8 @@ namespace canvas
typedef boost::function<Placements( SGPropertyNode*, typedef boost::function<Placements( SGPropertyNode*,
CanvasPtr )> PlacementFactory; CanvasPtr )> PlacementFactory;
typedef boost::function<void(const EventPtr&)> EventListener;
} // namespace canvas } // namespace canvas
} // namespace simgear } // namespace simgear
+24 -14
View File
@@ -173,11 +173,9 @@ namespace canvas
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
naRef Element::addEventListener(const nasal::CallContext& ctx) bool Element::addEventListener( const std::string& type_str,
const EventListener& cb )
{ {
const std::string type_str = ctx.requireArg<std::string>(0);
naRef code = ctx.requireArg<naRef>(1);
SG_LOG SG_LOG
( (
SG_NASAL, SG_NASAL,
@@ -187,17 +185,29 @@ namespace canvas
Event::Type type = Event::strToType(type_str); Event::Type type = Event::strToType(type_str);
if( type == Event::UNKNOWN ) if( type == Event::UNKNOWN )
naRuntimeError( ctx.c, {
"addEventListener: Unknown event type %s", SG_LOG( SG_NASAL,
type_str.c_str() ); SG_WARN,
"addEventListener: Unknown event type " << type_str );
return false;
}
_listener[ type ].push_back _listener[ type ].push_back(cb);
return true;
}
//----------------------------------------------------------------------------
bool Element::addNasalEventListener(const std::string& type, naRef code)
{
SGSharedPtr<NasalEventListener> listener =
new NasalEventListener(code, _canvas.lock()->getSystemAdapter());
return addEventListener
( (
boost::make_shared<EventListener>( code, type,
_canvas.lock()->getSystemAdapter() ) boost::bind(&NasalEventListener::operator(), listener, _1)
); );
return naNil();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -236,8 +246,8 @@ namespace canvas
if( listeners == _listener.end() ) if( listeners == _listener.end() )
return false; return false;
BOOST_FOREACH(EventListenerPtr listener, listeners->second) BOOST_FOREACH(EventListener const& listener, listeners->second)
listener->call(event); listener(event);
return true; return true;
} }
+4 -2
View File
@@ -92,7 +92,9 @@ namespace canvas
*/ */
virtual void update(double dt); virtual void update(double dt);
naRef addEventListener(const nasal::CallContext& ctx); bool addEventListener(const std::string& type, const EventListener& cb);
bool addNasalEventListener(const std::string& type, naRef code);
virtual void clearEventListener(); virtual void clearEventListener();
virtual bool accept(EventVisitor& visitor); virtual bool accept(EventVisitor& visitor);
@@ -189,7 +191,7 @@ namespace canvas
Style _style; Style _style;
std::vector<SGPropertyNode_ptr> _bounding_box; std::vector<SGPropertyNode_ptr> _bounding_box;
typedef std::vector<EventListenerPtr> Listener; typedef std::vector<EventListener> Listener;
typedef std::map<Event::Type, Listener> ListenerMap; typedef std::map<Event::Type, Listener> ListenerMap;
ListenerMap _listener; ListenerMap _listener;