Canvas: allow also C++ callable entities as event callbacks.
This commit is contained in:
parent
9e3172cb04
commit
6deb77dd4d
@ -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() )
|
||||
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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -132,7 +132,8 @@ namespace canvas
|
||||
|
||||
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 setSizeY(int sy);
|
||||
|
@ -28,7 +28,8 @@ namespace canvas
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
EventListener::EventListener(naRef code, const SystemAdapterPtr& sys_adapter):
|
||||
NasalEventListener::NasalEventListener( naRef code,
|
||||
const SystemAdapterPtr& sys_adapter ):
|
||||
_code(code),
|
||||
_gc_key(-1),
|
||||
_sys(sys_adapter)
|
||||
@ -39,23 +40,25 @@ namespace canvas
|
||||
&& !naIsFunc(code) )
|
||||
throw std::runtime_error
|
||||
(
|
||||
"canvas::EventListener: invalid function argument"
|
||||
"canvas::NasalEventListener: invalid function argument"
|
||||
);
|
||||
|
||||
_gc_key = sys_adapter->gcSave(_code);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
EventListener::~EventListener()
|
||||
NasalEventListener::~NasalEventListener()
|
||||
{
|
||||
assert( !_sys.expired() );
|
||||
_sys.lock()->gcRelease(_gc_key);
|
||||
if( !_sys.expired() )
|
||||
_sys.lock()->gcRelease(_gc_key);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void EventListener::call(const canvas::EventPtr& event)
|
||||
void NasalEventListener::operator()(const canvas::EventPtr& event) const
|
||||
{
|
||||
SystemAdapterPtr sys = _sys.lock();
|
||||
if( !sys )
|
||||
return;
|
||||
|
||||
naRef args[] = {
|
||||
nasal::Ghost<EventPtr>::create(sys->getNasalContext(), event)
|
||||
@ -65,6 +68,5 @@ namespace canvas
|
||||
sys->callMethod(_code, naNil(), num_args, args, naNil());
|
||||
}
|
||||
|
||||
|
||||
} // namespace canvas
|
||||
} // namespace simgear
|
||||
|
@ -27,14 +27,15 @@ namespace simgear
|
||||
namespace canvas
|
||||
{
|
||||
|
||||
class EventListener
|
||||
class NasalEventListener:
|
||||
public SGReferenced
|
||||
{
|
||||
public:
|
||||
EventListener( naRef code,
|
||||
const SystemAdapterPtr& sys_adapter );
|
||||
~EventListener();
|
||||
NasalEventListener( naRef code,
|
||||
const SystemAdapterPtr& sys_adapter );
|
||||
~NasalEventListener();
|
||||
|
||||
void call(const canvas::EventPtr& event);
|
||||
void operator()(const canvas::EventPtr& event) const;
|
||||
|
||||
protected:
|
||||
naRef _code;
|
||||
|
@ -51,7 +51,6 @@ namespace canvas
|
||||
SG_FWD_DECL(Text)
|
||||
|
||||
SG_FWD_DECL(Event)
|
||||
SG_FWD_DECL(EventListener)
|
||||
SG_FWD_DECL(MouseEvent)
|
||||
SG_FWD_DECL(Placement)
|
||||
SG_FWD_DECL(SystemAdapter)
|
||||
@ -73,6 +72,8 @@ namespace canvas
|
||||
typedef boost::function<Placements( SGPropertyNode*,
|
||||
CanvasPtr )> PlacementFactory;
|
||||
|
||||
typedef boost::function<void(const EventPtr&)> EventListener;
|
||||
|
||||
} // namespace canvas
|
||||
} // namespace simgear
|
||||
|
||||
|
@ -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_NASAL,
|
||||
@ -187,17 +185,29 @@ namespace canvas
|
||||
|
||||
Event::Type type = Event::strToType(type_str);
|
||||
if( type == Event::UNKNOWN )
|
||||
naRuntimeError( ctx.c,
|
||||
"addEventListener: Unknown event type %s",
|
||||
type_str.c_str() );
|
||||
{
|
||||
SG_LOG( SG_NASAL,
|
||||
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,
|
||||
_canvas.lock()->getSystemAdapter() )
|
||||
type,
|
||||
boost::bind(&NasalEventListener::operator(), listener, _1)
|
||||
);
|
||||
|
||||
return naNil();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -236,8 +246,8 @@ namespace canvas
|
||||
if( listeners == _listener.end() )
|
||||
return false;
|
||||
|
||||
BOOST_FOREACH(EventListenerPtr listener, listeners->second)
|
||||
listener->call(event);
|
||||
BOOST_FOREACH(EventListener const& listener, listeners->second)
|
||||
listener(event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -92,7 +92,9 @@ namespace canvas
|
||||
*/
|
||||
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 bool accept(EventVisitor& visitor);
|
||||
@ -189,7 +191,7 @@ namespace canvas
|
||||
Style _style;
|
||||
std::vector<SGPropertyNode_ptr> _bounding_box;
|
||||
|
||||
typedef std::vector<EventListenerPtr> Listener;
|
||||
typedef std::vector<EventListener> Listener;
|
||||
typedef std::map<Event::Type, Listener> ListenerMap;
|
||||
|
||||
ListenerMap _listener;
|
||||
|
Loading…
Reference in New Issue
Block a user