Canvas: allow also C++ callable entities as event callbacks.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user