Canvas.hxx | Canvas.hxx | |||
---|---|---|---|---|
// The canvas for rendering with the 2d API | ///@file The canvas for rendering with the 2d API | |||
// | // | |||
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | |||
// | // | |||
// This library is free software; you can redistribute it and/or | // This library is free software; you can redistribute it and/or | |||
// modify it under the terms of the GNU Library General Public | // modify it under the terms of the GNU Library General Public | |||
// License as published by the Free Software Foundation; either | // License as published by the Free Software Foundation; either | |||
// version 2 of the License, or (at your option) any later version. | // version 2 of the License, or (at your option) any later version. | |||
// | // | |||
// This library is distributed in the hope that it will be useful, | // This library is distributed in the hope that it will be useful, | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
skipping to change at line 26 | skipping to change at line 26 | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef CANVAS_HXX_ | #ifndef CANVAS_HXX_ | |||
#define CANVAS_HXX_ | #define CANVAS_HXX_ | |||
#include "canvas_fwd.hxx" | #include "canvas_fwd.hxx" | |||
#include "ODGauge.hxx" | #include "ODGauge.hxx" | |||
#include <simgear/canvas/elements/CanvasGroup.hxx> | #include <simgear/canvas/elements/CanvasGroup.hxx> | |||
#include <simgear/canvas/layout/Layout.hxx> | ||||
#include <simgear/math/SGRect.hxx> | #include <simgear/math/SGRect.hxx> | |||
#include <simgear/nasal/cppbind/NasalObject.hxx> | ||||
#include <simgear/props/PropertyBasedElement.hxx> | #include <simgear/props/PropertyBasedElement.hxx> | |||
#include <simgear/props/propertyObject.hxx> | #include <simgear/props/propertyObject.hxx> | |||
#include <osg/NodeCallback> | #include <osg/NodeCallback> | |||
#include <osg/observer_ptr> | #include <osg/observer_ptr> | |||
#include <boost/scoped_ptr.hpp> | #include <boost/scoped_ptr.hpp> | |||
#include <string> | #include <string> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
/// Canvas 2D drawing API | ||||
namespace canvas | namespace canvas | |||
{ | { | |||
class CanvasMgr; | class CanvasMgr; | |||
class MouseEvent; | class MouseEvent; | |||
class Canvas: | class Canvas: | |||
public PropertyBasedElement | public PropertyBasedElement, | |||
public nasal::Object | ||||
{ | { | |||
public: | public: | |||
enum StatusFlags | enum StatusFlags | |||
{ | { | |||
STATUS_OK, | STATUS_OK, | |||
STATUS_DIRTY = 1, | STATUS_DIRTY = 1, | |||
MISSING_SIZE_X = STATUS_DIRTY << 1, | LAYOUT_DIRTY = STATUS_DIRTY << 1, | |||
MISSING_SIZE_X = LAYOUT_DIRTY << 1, | ||||
MISSING_SIZE_Y = MISSING_SIZE_X << 1, | MISSING_SIZE_Y = MISSING_SIZE_X << 1, | |||
MISSING_SIZE = MISSING_SIZE_X | MISSING_SIZE_Y, | ||||
CREATE_FAILED = MISSING_SIZE_Y << 1 | CREATE_FAILED = MISSING_SIZE_Y << 1 | |||
}; | }; | |||
/** | /** | |||
* This callback is installed on every placement of the canvas in the | * This callback is installed on every placement of the canvas in the | |||
* scene to only render the canvas if at least one placement is visib le | * scene to only render the canvas if at least one placement is visib le | |||
*/ | */ | |||
class CullCallback: | class CullCallback: | |||
public osg::NodeCallback | public osg::NodeCallback | |||
{ | { | |||
skipping to change at line 124 | skipping to change at line 131 | |||
* group | * group | |||
*/ | */ | |||
GroupPtr getOrCreateGroup(const std::string& name); | GroupPtr getOrCreateGroup(const std::string& name); | |||
/** | /** | |||
* Get the root group of the canvas | * Get the root group of the canvas | |||
*/ | */ | |||
GroupPtr getRootGroup(); | GroupPtr getRootGroup(); | |||
/** | /** | |||
* Set the layout of the canvas (the layout will automatically update | ||||
with | ||||
* the viewport size of the canvas) | ||||
*/ | ||||
void setLayout(const LayoutRef& layout); | ||||
/** | ||||
* Enable rendering for the next frame | * Enable rendering for the next frame | |||
* | * | |||
* @param force Force redraw even if nothing has changed (if dirty flag | * @param force Force redraw even if nothing has changed (if dirty flag | |||
* is not set) | * is not set) | |||
*/ | */ | |||
void enableRendering(bool force = false); | void enableRendering(bool force = false); | |||
void update(double delta_time_sec); | void update(double delta_time_sec); | |||
bool addEventListener(const std::string& type, const EventListener& c b); | bool addEventListener(const std::string& type, const EventListener& c b); | |||
bool dispatchEvent(const EventPtr& event); | ||||
void setSizeX(int sx); | void setSizeX(int sx); | |||
void setSizeY(int sy); | void setSizeY(int sy); | |||
int getSizeX() const; | int getSizeX() const; | |||
int getSizeY() const; | int getSizeY() const; | |||
void setViewWidth(int w); | void setViewWidth(int w); | |||
void setViewHeight(int h); | void setViewHeight(int h); | |||
int getViewWidth() const; | int getViewWidth() const; | |||
int getViewHeight() const; | int getViewHeight() const; | |||
SGRect<int> getViewport() const; | SGRect<int> getViewport() const; | |||
bool handleMouseEvent(const MouseEventPtr& event); | bool handleMouseEvent(const MouseEventPtr& event); | |||
bool propagateEvent( EventPtr const& event, | ||||
EventPropagationPath const& path ); | ||||
virtual void childAdded( SGPropertyNode * parent, | virtual void childAdded( SGPropertyNode * parent, | |||
SGPropertyNode * child ); | SGPropertyNode * child ); | |||
virtual void childRemoved( SGPropertyNode * parent, | virtual void childRemoved( SGPropertyNode * parent, | |||
SGPropertyNode * child ); | SGPropertyNode * child ); | |||
virtual void valueChanged (SGPropertyNode * node); | virtual void valueChanged (SGPropertyNode * node); | |||
osg::Texture2D* getTexture() const; | osg::Texture2D* getTexture() const; | |||
CullCallbackPtr getCullCallback() const; | CullCallbackPtr getCullCallback() const; | |||
skipping to change at line 194 | skipping to change at line 210 | |||
_view_height; | _view_height; | |||
PropertyObject<int> _status; | PropertyObject<int> _status; | |||
PropertyObject<std::string> _status_msg; | PropertyObject<std::string> _status_msg; | |||
bool _sampling_dirty, | bool _sampling_dirty, | |||
_render_dirty, | _render_dirty, | |||
_visible; | _visible; | |||
ODGauge _texture; | ODGauge _texture; | |||
GroupPtr _root_group; | ||||
GroupPtr _root_group; | ||||
LayoutRef _layout; | ||||
CullCallbackPtr _cull_callback; | CullCallbackPtr _cull_callback; | |||
bool _render_always; //<! Used to disable automatic lazy rendering (c ulling) | bool _render_always; //<! Used to disable automatic lazy rendering (c ulling) | |||
std::vector<SGPropertyNode*> _dirty_placements; | std::vector<SGPropertyNode*> _dirty_placements; | |||
std::vector<Placements> _placements; | std::vector<Placements> _placements; | |||
std::set<CanvasWeakPtr> _parent_canvases, //<! Canvases showing this canvas | std::set<CanvasWeakPtr> _parent_canvases, //<! Canvases showing this canvas | |||
_child_canvases; //<! Canvases displayed wit hin | _child_canvases; //<! Canvases displayed wit hin | |||
// this canvas | // this canvas | |||
typedef std::map<std::string, PlacementFactory> PlacementFactoryMap; | typedef std::map<std::string, PlacementFactory> PlacementFactoryMap; | |||
static PlacementFactoryMap _placement_factories; | static PlacementFactoryMap _placement_factories; | |||
virtual void setSelf(const PropertyBasedElementPtr& self); | ||||
void setStatusFlags(unsigned int flags, bool set = true); | void setStatusFlags(unsigned int flags, bool set = true); | |||
private: | private: | |||
static SystemAdapterPtr _system_adapter; | static SystemAdapterPtr _system_adapter; | |||
Canvas(const Canvas&); // = delete; | Canvas(const Canvas&); // = delete; | |||
Canvas& operator=(const Canvas&); // = delete; | Canvas& operator=(const Canvas&); // = delete; | |||
}; | }; | |||
End of changes. 13 change blocks. | ||||
6 lines changed or deleted | 24 lines changed or added | |||
CanvasElement.hxx | CanvasElement.hxx | |||
---|---|---|---|---|
// Interface for 2D Canvas elements | ///@file Interface for 2D Canvas elements | |||
// | // | |||
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | |||
// | // | |||
// This library is free software; you can redistribute it and/or | // This library is free software; you can redistribute it and/or | |||
// modify it under the terms of the GNU Library General Public | // modify it under the terms of the GNU Library General Public | |||
// License as published by the Free Software Foundation; either | // License as published by the Free Software Foundation; either | |||
// version 2 of the License, or (at your option) any later version. | // version 2 of the License, or (at your option) any later version. | |||
// | // | |||
// This library is distributed in the hope that it will be useful, | // This library is distributed in the hope that it will be useful, | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
skipping to change at line 44 | skipping to change at line 44 | |||
namespace osg | namespace osg | |||
{ | { | |||
class Drawable; | class Drawable; | |||
} | } | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
/** | ||||
* Baseclass for Elements displayed inside a Canvas. | ||||
*/ | ||||
class Element: | class Element: | |||
public PropertyBasedElement | public PropertyBasedElement | |||
{ | { | |||
public: | public: | |||
/** | /** | |||
* Store pointer to window as user data | * Store pointer to window as user data | |||
*/ | */ | |||
class OSGUserData: | class OSGUserData: | |||
public osg::Referenced | public osg::Referenced | |||
skipping to change at line 72 | skipping to change at line 75 | |||
typedef boost::function<void(Element&, const SGPropertyNode*)> | typedef boost::function<void(Element&, const SGPropertyNode*)> | |||
StyleSetterFuncUnchecked; | StyleSetterFuncUnchecked; | |||
struct StyleSetter: | struct StyleSetter: | |||
public SGReferenced | public SGReferenced | |||
{ | { | |||
StyleSetterFunc func; | StyleSetterFunc func; | |||
SGSharedPtr<StyleSetter> next; | SGSharedPtr<StyleSetter> next; | |||
}; | }; | |||
struct StyleInfo | struct StyleInfo | |||
{ | { | |||
StyleSetter setter; ///!< Function(s) for setting this style | StyleSetter setter; ///< Function(s) for setting this style | |||
std::string type; ///!< Interpolation type | std::string type; ///< Interpolation type | |||
bool inheritable; ///!< Whether children can inherit this style f | bool inheritable; ///< Whether children can inherit this style fr | |||
rom | om | |||
/// their parents | /// their parents | |||
}; | }; | |||
/** | /** | |||
* Coordinate reference frame (eg. "clip" property) | * Coordinate reference frame (eg. "clip" property) | |||
*/ | */ | |||
enum ReferenceFrame | enum ReferenceFrame | |||
{ | { | |||
GLOBAL, ///!< Global coordinates | GLOBAL, ///< Global coordinates | |||
PARENT, ///!< Coordinates relative to parent coordinate frame | PARENT, ///< Coordinates relative to parent coordinate frame | |||
LOCAL ///!< Coordinates relative to local coordinates (parent | LOCAL ///< Coordinates relative to local coordinates (parent | |||
/// coordinates with local transformations applied) | /// coordinates with local transformations applied) | |||
}; | }; | |||
/** | /** | |||
* | * | |||
*/ | */ | |||
virtual ~Element() = 0; | virtual ~Element() = 0; | |||
virtual void setSelf(const PropertyBasedElementPtr& self); | ||||
virtual void onDestroy(); | virtual void onDestroy(); | |||
ElementWeakPtr getWeakPtr() const; | ElementPtr getParent() const; | |||
ElementPtr getParent(); | CanvasWeakPtr getCanvas() const; | |||
/** | /** | |||
* Called every frame to update internal state | * Called every frame to update internal state | |||
* | * | |||
* @param dt Frame time in seconds | * @param dt Frame time in seconds | |||
*/ | */ | |||
virtual void update(double dt); | virtual void update(double dt); | |||
bool addEventListener(const std::string& type, const EventListener& c b); | bool addEventListener(const std::string& type, const EventListener& c b); | |||
virtual void clearEventListener(); | virtual void clearEventListener(); | |||
virtual bool accept(EventVisitor& visitor); | virtual bool accept(EventVisitor& visitor); | |||
virtual bool ascend(EventVisitor& visitor); | virtual bool ascend(EventVisitor& visitor); | |||
virtual bool traverse(EventVisitor& visitor); | virtual bool traverse(EventVisitor& visitor); | |||
virtual bool handleEvent(canvas::EventPtr event); | virtual bool handleEvent(const EventPtr& event); | |||
bool dispatchEvent(const EventPtr& event); | ||||
virtual bool hitBound( const osg::Vec2f& pos, | /** | |||
* | ||||
* @param global_pos Position in global (canvas) coordinate frame | ||||
* @param parent_pos Position in parent coordinate frame | ||||
* @param local_pos Position in local (element) coordinate frame | ||||
*/ | ||||
virtual bool hitBound( const osg::Vec2f& global_pos, | ||||
const osg::Vec2f& parent_pos, | ||||
const osg::Vec2f& local_pos ) const; | const osg::Vec2f& local_pos ) const; | |||
/** | /** | |||
* Get whether the element is visible or hidden (Can be changed with | * Set visibility of the element. | |||
* setting property "visible" accordingly). | */ | |||
void setVisible(bool visible); | ||||
/** | ||||
* Get whether the element is visible or hidden. | ||||
*/ | */ | |||
bool isVisible() const; | bool isVisible() const; | |||
osg::MatrixTransform* getMatrixTransform(); | osg::MatrixTransform* getMatrixTransform(); | |||
osg::MatrixTransform const* getMatrixTransform() const; | osg::MatrixTransform const* getMatrixTransform() const; | |||
/** | ||||
* Transform position to local coordinages. | ||||
*/ | ||||
osg::Vec2f posToLocal(const osg::Vec2f& pos) const; | ||||
virtual void childAdded( SGPropertyNode * parent, | virtual void childAdded( SGPropertyNode * parent, | |||
SGPropertyNode * child ); | SGPropertyNode * child ); | |||
virtual void childRemoved( SGPropertyNode * parent, | virtual void childRemoved( SGPropertyNode * parent, | |||
SGPropertyNode * child ); | SGPropertyNode * child ); | |||
virtual void valueChanged(SGPropertyNode * child); | virtual void valueChanged(SGPropertyNode * child); | |||
virtual bool setStyle( const SGPropertyNode* child, | virtual bool setStyle( const SGPropertyNode* child, | |||
const StyleInfo* style_info = 0 ); | const StyleInfo* style_info = 0 ); | |||
/** | /** | |||
skipping to change at line 151 | skipping to change at line 169 | |||
* @see http://www.w3.org/TR/CSS21/visufx.html#propdef-clip | * @see http://www.w3.org/TR/CSS21/visufx.html#propdef-clip | |||
*/ | */ | |||
void setClip(const std::string& clip); | void setClip(const std::string& clip); | |||
/** | /** | |||
* Clipping coordinates reference frame | * Clipping coordinates reference frame | |||
*/ | */ | |||
void setClipFrame(ReferenceFrame rf); | void setClipFrame(ReferenceFrame rf); | |||
/** | /** | |||
* Write the given bounding box to the property tree | * Get bounding box (may not be as tight as bounding box returned by | |||
* #getTightBoundingBox) | ||||
*/ | ||||
osg::BoundingBox getBoundingBox() const; | ||||
/** | ||||
* Get tight bounding box (child points are transformed to elements | ||||
* coordinate space before calculating the bounding box). | ||||
*/ | */ | |||
void setBoundingBox(const osg::BoundingBox& bb); | osg::BoundingBox getTightBoundingBox() const; | |||
/** | /** | |||
* Get bounding box with children/drawables transformed by passed mat rix | * Get bounding box with children/drawables transformed by passed mat rix | |||
*/ | */ | |||
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) c onst; | virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) c onst; | |||
/** | /** | |||
* Get the transformation matrix (product of all transforms) | * Get the transformation matrix (product of all transforms) | |||
*/ | */ | |||
osg::Matrix getMatrix() const; | osg::Matrix getMatrix() const; | |||
skipping to change at line 177 | skipping to change at line 202 | |||
* | * | |||
* @tparam Derived Type of element (needs to derive from Element) | * @tparam Derived Type of element (needs to derive from Element) | |||
*/ | */ | |||
template<typename Derived> | template<typename Derived> | |||
static | static | |||
typename boost::enable_if< | typename boost::enable_if< | |||
boost::is_base_of<Element, Derived>, | boost::is_base_of<Element, Derived>, | |||
ElementPtr | ElementPtr | |||
>::type create( const CanvasWeakPtr& canvas, | >::type create( const CanvasWeakPtr& canvas, | |||
const SGPropertyNode_ptr& node, | const SGPropertyNode_ptr& node, | |||
const Style& style, | const Style& style = Style(), | |||
Element* parent ) | Element* parent = NULL ) | |||
{ | { | |||
ElementPtr el( new Derived(canvas, node, style, parent) ); | return ElementPtr( new Derived(canvas, node, style, parent) ); | |||
el->setSelf(el); | ||||
return el; | ||||
} | } | |||
protected: | protected: | |||
enum Attributes | enum Attributes | |||
{ | { | |||
TRANSFORM = 1, | TRANSFORM = 1, | |||
BLEND_FUNC = TRANSFORM << 1, | BLEND_FUNC = TRANSFORM << 1, | |||
SCISSOR_COORDS = BLEND_FUNC << 1, | LAST_ATTRIBUTE = BLEND_FUNC << 1 | |||
LAST_ATTRIBUTE = SCISSOR_COORDS << 1 | ||||
}; | }; | |||
enum TransformType | enum TransformType | |||
{ | { | |||
TT_NONE, | TT_NONE, | |||
TT_MATRIX, | TT_MATRIX, | |||
TT_TRANSLATE, | TT_TRANSLATE, | |||
TT_ROTATE, | TT_ROTATE, | |||
TT_SCALE | TT_SCALE | |||
}; | }; | |||
skipping to change at line 214 | skipping to change at line 236 | |||
class RelativeScissor; | class RelativeScissor; | |||
CanvasWeakPtr _canvas; | CanvasWeakPtr _canvas; | |||
Element *_parent; | Element *_parent; | |||
mutable uint32_t _attributes_dirty; | mutable uint32_t _attributes_dirty; | |||
osg::observer_ptr<osg::MatrixTransform> _transform; | osg::observer_ptr<osg::MatrixTransform> _transform; | |||
std::vector<TransformType> _transform_types; | std::vector<TransformType> _transform_types; | |||
Style _style; | Style _style; | |||
std::vector<SGPropertyNode_ptr> _bounding_box; | RelativeScissor *_scissor; | |||
RelativeScissor *_scissor; | ||||
typedef std::vector<EventListener> Listener; | typedef std::vector<EventListener> Listener; | |||
typedef std::map<Event::Type, Listener> ListenerMap; | typedef std::map<int, Listener> ListenerMap; | |||
ListenerMap _listener; | ListenerMap _listener; | |||
typedef std::map<std::string, StyleInfo> StyleSetters; | typedef std::map<std::string, StyleInfo> StyleSetters; | |||
static StyleSetters _style_setters; | static StyleSetters _style_setters; | |||
static void staticInit(); | static void staticInit(); | |||
Element( const CanvasWeakPtr& canvas, | Element( const CanvasWeakPtr& canvas, | |||
const SGPropertyNode_ptr& node, | const SGPropertyNode_ptr& node, | |||
const Style& parent_style, | const Style& parent_style, | |||
Element* parent ); | Element* parent ); | |||
/** | /** | |||
* Returns false on first call and true on any successive call. Use t o | * Returns false on first call and true on any successive call. Use t o | |||
End of changes. 18 change blocks. | ||||
32 lines changed or deleted | 53 lines changed or added | |||
CanvasEvent.hxx | CanvasEvent.hxx | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef CANVAS_EVENT_HXX_ | #ifndef CANVAS_EVENT_HXX_ | |||
#define CANVAS_EVENT_HXX_ | #define CANVAS_EVENT_HXX_ | |||
#include "canvas_fwd.hxx" | #include "canvas_fwd.hxx" | |||
#include <boost/bimap.hpp> | ||||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
class Event | class Event: | |||
public SGReferenced | ||||
{ | { | |||
public: | public: | |||
enum Type | enum Type | |||
{ | { | |||
UNKNOWN, | UNKNOWN, | |||
# define ENUM_MAPPING(name, str) name, | # define ENUM_MAPPING(name, str) name, | |||
# include "CanvasEventTypes.hxx" | # include "CanvasEventTypes.hxx" | |||
# undef ENUM_MAPPING | # undef ENUM_MAPPING | |||
USER_TYPE ///<! first unused id to be used for user defined types ( | CUSTOM_EVENT ///< all user defined event types share the same id. T | |||
not | hey | |||
/// implemented yet) | /// are just differentiated by using the type string. | |||
}; | }; | |||
Type type; | int type; | |||
ElementWeakPtr target, | ElementWeakPtr target, | |||
current_target; | current_target; | |||
double time; | double time; | |||
bool propagation_stopped; | bool propagation_stopped; | |||
Event(); | Event(); | |||
// We need a vtable to allow nasal::Ghost to determine the dynamic ty pe | // We need a vtable to allow nasal::Ghost to determine the dynamic ty pe | |||
// of the actual event instances. | // of the actual event instances. | |||
virtual ~Event(); | virtual ~Event(); | |||
Type getType() const; | /** | |||
* Get whether this events support bubbling | ||||
*/ | ||||
virtual bool canBubble() const; | ||||
/** | ||||
* Set type of event. | ||||
* | ||||
* If no such type exists it is registered. | ||||
*/ | ||||
void setType(const std::string& type); | ||||
int getType() const; | ||||
std::string getTypeString() const; | std::string getTypeString() const; | |||
ElementWeakPtr getTarget() const; | ElementWeakPtr getTarget() const; | |||
ElementWeakPtr getCurrentTarget() const; | ElementWeakPtr getCurrentTarget() const; | |||
double getTime() const; | double getTime() const; | |||
void stopPropagation(); | void stopPropagation(); | |||
static Type strToType(const std::string& str); | static int getOrRegisterType(const std::string& type); | |||
static int strToType(const std::string& type); | ||||
static std::string typeToStr(int type); | ||||
protected: | ||||
struct name {}; | ||||
struct id {}; | ||||
typedef boost::bimaps::bimap< | ||||
boost::bimaps::tagged<std::string, name>, | ||||
boost::bimaps::tagged<int, id> | ||||
> TypeMap; | ||||
static TypeMap& getTypeMap(); | ||||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace simgear | } // namespace simgear | |||
#endif /* CANVAS_EVENT_HXX_ */ | #endif /* CANVAS_EVENT_HXX_ */ | |||
End of changes. 6 change blocks. | ||||
7 lines changed or deleted | 33 lines changed or added | |||
CanvasEventManager.hxx | CanvasEventManager.hxx | |||
---|---|---|---|---|
skipping to change at line 32 | skipping to change at line 32 | |||
#include "canvas_fwd.hxx" | #include "canvas_fwd.hxx" | |||
#include <deque> | #include <deque> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
struct EventTarget | struct EventTarget | |||
{ | { | |||
ElementWeakPtr element; | ElementWeakPtr element; | |||
osg::Vec2f local_pos, | ||||
local_delta; | // Used as storage by EventManager during event propagation | |||
mutable osg::Vec2f local_pos; | ||||
EventTarget( Element* el, | ||||
const osg::Vec2f pos = osg::Vec2f() ): | ||||
element(el), | ||||
local_pos(pos) | ||||
{} | ||||
}; | }; | |||
typedef std::deque<EventTarget> EventPropagationPath; | ||||
inline bool operator==(const EventTarget& t1, const EventTarget& t2) | inline bool operator==(const EventTarget& t1, const EventTarget& t2) | |||
{ | { | |||
return t1.element.lock() == t2.element.lock(); | return t1.element.lock() == t2.element.lock(); | |||
} | } | |||
class EventManager | class EventManager | |||
{ | { | |||
public: | public: | |||
EventManager(); | EventManager(); | |||
bool handleEvent( const MouseEventPtr& event, | bool handleEvent( const MouseEventPtr& event, | |||
const EventPropagationPath& path ); | const EventPropagationPath& path ); | |||
bool propagateEvent( const EventPtr& event, | ||||
const EventPropagationPath& path ); | ||||
protected: | protected: | |||
struct StampedPropagationPath | struct StampedPropagationPath | |||
{ | { | |||
StampedPropagationPath(); | StampedPropagationPath(); | |||
StampedPropagationPath(const EventPropagationPath& path, double tim e); | StampedPropagationPath(const EventPropagationPath& path, double tim e); | |||
void clear(); | void clear(); | |||
bool valid() const; | bool valid() const; | |||
EventPropagationPath path; | EventPropagationPath path; | |||
double time; | double time; | |||
}; | }; | |||
// TODO if we really need the paths modify to not copy around the pat hs | // TODO if we really need the paths modify to not copy around the pat hs | |||
// that much. | // that much. | |||
StampedPropagationPath _last_mouse_down, | StampedPropagationPath _last_mouse_over; | |||
_last_click, | ||||
_last_mouse_over; | ||||
size_t _current_click_count; | size_t _current_click_count; | |||
struct MouseEventInfo: | ||||
public StampedPropagationPath | ||||
{ | ||||
int button; | ||||
osg::Vec2f pos; | ||||
void set( const MouseEventPtr& event, | ||||
const EventPropagationPath& path ); | ||||
} _last_mouse_down, | ||||
_last_click; | ||||
/** | /** | |||
* Propagate click event and handle multi-click (eg. create dblclick) | * Propagate click event and handle multi-click (eg. create dblclick) | |||
*/ | */ | |||
bool handleClick( const MouseEventPtr& event, | bool handleClick( const MouseEventPtr& event, | |||
const EventPropagationPath& path ); | const EventPropagationPath& path ); | |||
/** | /** | |||
* Handle mouseover/enter/out/leave | * Handle mouseover/enter/out/leave | |||
*/ | */ | |||
bool handleMove( const MouseEventPtr& event, | bool handleMove( const MouseEventPtr& event, | |||
const EventPropagationPath& path ); | const EventPropagationPath& path ); | |||
bool propagateEvent( const EventPtr& event, | ||||
const EventPropagationPath& path ); | ||||
/** | /** | |||
* Check if two click events (either mousedown/up or two consecutive | * Check if two click events (either mousedown/up or two consecutive | |||
* clicks) are inside a maximum distance to still create a click or | * clicks) are inside a maximum distance to still create a click or | |||
* dblclick event respectively. | * dblclick event respectively. | |||
*/ | */ | |||
bool checkClickDistance( const EventPropagationPath& path1, | bool checkClickDistance( const osg::Vec2f& pos1, | |||
const EventPropagationPath& path2 ) const; | const osg::Vec2f& pos2 ) const; | |||
EventPropagationPath | EventPropagationPath | |||
getCommonAncestor( const EventPropagationPath& path1, | getCommonAncestor( const EventPropagationPath& path1, | |||
const EventPropagationPath& path2 ) const; | const EventPropagationPath& path2 ) const; | |||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace simgear | } // namespace simgear | |||
#endif /* CANVAS_EVENT_MANAGER_HXX_ */ | #endif /* CANVAS_EVENT_MANAGER_HXX_ */ | |||
End of changes. 7 change blocks. | ||||
12 lines changed or deleted | 28 lines changed or added | |||
CanvasEventVisitor.hxx | CanvasEventVisitor.hxx | |||
---|---|---|---|---|
skipping to change at line 45 | skipping to change at line 45 | |||
enum TraverseMode | enum TraverseMode | |||
{ | { | |||
TRAVERSE_UP, | TRAVERSE_UP, | |||
TRAVERSE_DOWN | TRAVERSE_DOWN | |||
}; | }; | |||
/** | /** | |||
* | * | |||
* @param mode | * @param mode | |||
* @param pos Mouse position | * @param pos Mouse position | |||
* @param delta Mouse movement since last mouse move event | ||||
* @param root Element to dispatch events to if no element is hit | * @param root Element to dispatch events to if no element is hit | |||
*/ | */ | |||
EventVisitor( TraverseMode mode, | EventVisitor( TraverseMode mode, | |||
const osg::Vec2f& pos, | const osg::Vec2f& pos, | |||
const osg::Vec2f& delta, | ||||
const ElementPtr& root = ElementPtr() ); | const ElementPtr& root = ElementPtr() ); | |||
virtual ~EventVisitor(); | virtual ~EventVisitor(); | |||
virtual bool traverse(Element& el); | virtual bool traverse(Element& el); | |||
virtual bool apply(Element& el); | virtual bool apply(Element& el); | |||
const EventPropagationPath& getPropagationPath() const; | const EventPropagationPath& getPropagationPath() const; | |||
protected: | protected: | |||
TraverseMode _traverse_mode; | TraverseMode _traverse_mode; | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 0 lines changed or added | |||
CanvasGroup.hxx | CanvasGroup.hxx | |||
---|---|---|---|---|
skipping to change at line 59 | skipping to change at line 59 | |||
virtual ~Group(); | virtual ~Group(); | |||
ElementPtr createChild( const std::string& type, | ElementPtr createChild( const std::string& type, | |||
const std::string& id = "" ); | const std::string& id = "" ); | |||
ElementPtr getChild(const SGPropertyNode* node); | ElementPtr getChild(const SGPropertyNode* node); | |||
ElementPtr getChild(const std::string& id); | ElementPtr getChild(const std::string& id); | |||
ElementPtr getOrCreateChild( const std::string& type, | ElementPtr getOrCreateChild( const std::string& type, | |||
const std::string& id ); | const std::string& id ); | |||
template<class T> | template<class T> | |||
boost::shared_ptr<T> createChild(const std::string& id = "") | SGSharedPtr<T> createChild(const std::string& id = "") | |||
{ | { | |||
return boost::dynamic_pointer_cast<T>( createChild(T::TYPE_NAME, id ) ); | return dynamic_cast<T*>( createChild(T::TYPE_NAME, id).get() ); | |||
} | } | |||
template<class T> | template<class T> | |||
boost::shared_ptr<T> getChild(const SGPropertyNode* node) | SGSharedPtr<T> getChild(const SGPropertyNode* node) | |||
{ | { | |||
return boost::dynamic_pointer_cast<T>( getChild(node) ); | return dynamic_cast<T*>( getChild(node).get() ); | |||
} | } | |||
template<class T> | template<class T> | |||
boost::shared_ptr<T> getChild(const std::string& id) | SGSharedPtr<T> getChild(const std::string& id) | |||
{ | { | |||
return boost::dynamic_pointer_cast<T>( getChild(id) ); | return dynamic_cast<T*>( getChild(id).get() ); | |||
} | } | |||
template<class T> | template<class T> | |||
boost::shared_ptr<T> getOrCreateChild(const std::string& id) | SGSharedPtr<T> getOrCreateChild(const std::string& id) | |||
{ | { | |||
return | return dynamic_cast<T*>( getOrCreateChild(T::TYPE_NAME, id).get() ) | |||
boost::dynamic_pointer_cast<T>( getOrCreateChild(T::TYPE_NAME, id | ; | |||
) ); | ||||
} | } | |||
/** | /** | |||
* Get first child with given id (breadth-first search) | * Get first child with given id (breadth-first search) | |||
* | * | |||
* @param id Id (value if property node 'id') of element | * @param id Id (value if property node 'id') of element | |||
*/ | */ | |||
ElementPtr getElementById(const std::string& id); | ElementPtr getElementById(const std::string& id); | |||
virtual void clearEventListener(); | virtual void clearEventListener(); | |||
End of changes. 8 change blocks. | ||||
10 lines changed or deleted | 9 lines changed or added | |||
CanvasImage.hxx | CanvasImage.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef CANVAS_IMAGE_HXX_ | #ifndef CANVAS_IMAGE_HXX_ | |||
#define CANVAS_IMAGE_HXX_ | #define CANVAS_IMAGE_HXX_ | |||
#include "CanvasElement.hxx" | #include "CanvasElement.hxx" | |||
#include <simgear/canvas/canvas_fwd.hxx> | #include <simgear/canvas/canvas_fwd.hxx> | |||
#include <simgear/io/HTTPClient.hxx> | ||||
#include <simgear/misc/CSSBorder.hxx> | #include <simgear/misc/CSSBorder.hxx> | |||
#include <simgear/misc/SVGpreserveAspectRatio.hxx> | ||||
#include <osg/Texture2D> | #include <osg/Texture2D> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace HTTP { class Request; } | ||||
namespace canvas | namespace canvas | |||
{ | { | |||
class Image: | class Image: | |||
public Element | public Element | |||
{ | { | |||
public: | public: | |||
static const std::string TYPE_NAME; | static const std::string TYPE_NAME; | |||
static void staticInit(); | static void staticInit(); | |||
skipping to change at line 63 | skipping to change at line 66 | |||
virtual void update(double dt); | virtual void update(double dt); | |||
virtual void valueChanged(SGPropertyNode* child); | virtual void valueChanged(SGPropertyNode* child); | |||
void setSrcCanvas(CanvasPtr canvas); | void setSrcCanvas(CanvasPtr canvas); | |||
CanvasWeakPtr getSrcCanvas() const; | CanvasWeakPtr getSrcCanvas() const; | |||
void setImage(osg::Image *img); | void setImage(osg::Image *img); | |||
void setFill(const std::string& fill); | void setFill(const std::string& fill); | |||
/** | /** | |||
* @see http://www.w3.org/TR/css3-background/#border-image-outset | ||||
*/ | ||||
void setOutset(const std::string& outset); | ||||
/** | ||||
* @see | ||||
* http://www.w3.org/TR/SVG11/coords.html#PreserveAspectRatioAttrib | ||||
ute | ||||
*/ | ||||
void setPreserveAspectRatio(const std::string& scale); | ||||
/** | ||||
* Set image slice (aka. 9-scale) | * Set image slice (aka. 9-scale) | |||
* | * | |||
* @see http://www.w3.org/TR/css3-background/#border-image-slice | * @see http://www.w3.org/TR/css3-background/#border-image-slice | |||
*/ | */ | |||
void setSlice(const std::string& slice); | void setSlice(const std::string& slice); | |||
/** | /** | |||
* Set image slice width. | * Set image slice width. | |||
* | * | |||
* By default the size of the 9-scale grid is the same as specified | * By default the size of the 9-scale grid is the same as specified | |||
* with setSlice/"slice". Using this method allows setting values | * with setSlice/"slice". Using this method allows setting values | |||
* different to the size in the source image. | * different to the size in the source image. | |||
* | * | |||
* @see http://www.w3.org/TR/css3-background/#border-image-width | * @see http://www.w3.org/TR/css3-background/#border-image-width | |||
*/ | */ | |||
void setSliceWidth(const std::string& width); | void setSliceWidth(const std::string& width); | |||
/** | ||||
* http://www.w3.org/TR/css3-background/#border-image-outset | ||||
*/ | ||||
void setOutset(const std::string& outset); | ||||
const SGRect<float>& getRegion() const; | const SGRect<float>& getRegion() const; | |||
bool handleEvent(EventPtr event); | bool handleEvent(const EventPtr& event); | |||
protected: | protected: | |||
enum ImageAttributes | enum ImageAttributes | |||
{ | { | |||
SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle | SRC_RECT = LAST_ATTRIBUTE << 1, // Source image rectangle | |||
DEST_SIZE = SRC_RECT << 1, // Element size | DEST_SIZE = SRC_RECT << 1, // Element size | |||
SRC_CANVAS = DEST_SIZE << 1 | SRC_CANVAS = DEST_SIZE << 1 | |||
}; | }; | |||
virtual void childChanged(SGPropertyNode * child); | virtual void childChanged(SGPropertyNode * child); | |||
void setupDefaultDimensions(); | void setupDefaultDimensions(); | |||
SGRect<int> getTextureDimensions() const; | SGRect<int> getTextureDimensions() const; | |||
void setQuad(size_t index, const SGVec2f& tl, const SGVec2f& br); | void setQuad(size_t index, const SGVec2f& tl, const SGVec2f& br); | |||
void setQuadUV(size_t index, const SGVec2f& tl, const SGVec2f& br); | void setQuadUV(size_t index, const SGVec2f& tl, const SGVec2f& br); | |||
void handleImageLoadDone(HTTP::Request*); | ||||
bool loadImage( osgDB::ReaderWriter& reader, | ||||
const std::string& data, | ||||
HTTP::Request& request, | ||||
const std::string& type ); | ||||
osg::ref_ptr<osg::Texture2D> _texture; | osg::ref_ptr<osg::Texture2D> _texture; | |||
// TODO optionally forward events to canvas | // TODO optionally forward events to canvas | |||
CanvasWeakPtr _src_canvas; | CanvasWeakPtr _src_canvas; | |||
HTTP::Request_ptr _http_request; | ||||
osg::ref_ptr<osg::Geometry> _geom; | osg::ref_ptr<osg::Geometry> _geom; | |||
osg::ref_ptr<osg::DrawArrays>_prim; | osg::ref_ptr<osg::DrawArrays>_prim; | |||
osg::ref_ptr<osg::Vec3Array> _vertices; | osg::ref_ptr<osg::Vec3Array> _vertices; | |||
osg::ref_ptr<osg::Vec2Array> _texCoords; | osg::ref_ptr<osg::Vec2Array> _texCoords; | |||
osg::ref_ptr<osg::Vec4Array> _colors; | osg::ref_ptr<osg::Vec4Array> _colors; | |||
SGPropertyNode *_node_src_rect; | SGPropertyNode *_node_src_rect; | |||
SGRect<float> _src_rect, | SGRect<float> _src_rect, | |||
_region; | _region; | |||
CSSBorder _slice, | SVGpreserveAspectRatio _preserve_aspect_ratio; | |||
_slice_width, | ||||
_outset; | CSSBorder _outset, | |||
_slice, | ||||
_slice_width; | ||||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace canvas | } // namespace canvas | |||
#endif /* CANVAS_IMAGE_HXX_ */ | #endif /* CANVAS_IMAGE_HXX_ */ | |||
End of changes. 9 change blocks. | ||||
9 lines changed or deleted | 28 lines changed or added | |||
CanvasMgr.hxx | CanvasMgr.hxx | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
class CanvasMgr: | class CanvasMgr: | |||
public PropertyBasedMgr | public PropertyBasedMgr | |||
{ | { | |||
public: | public: | |||
/** | /** | |||
* @param node Root node of branch used to control canvass es | * @param node Root node of branch used to control canvasses | |||
*/ | */ | |||
CanvasMgr(SGPropertyNode_ptr node); | CanvasMgr(SGPropertyNode_ptr node); | |||
/** | /** | |||
* Create a new canvas | * Create a new canvas | |||
* | * | |||
* @param name Name of the new canvas | * @param name Name of the new canvas | |||
*/ | */ | |||
CanvasPtr createCanvas(const std::string& name = ""); | CanvasPtr createCanvas(const std::string& name = ""); | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
CanvasObjectPlacement.hxx | CanvasObjectPlacement.hxx | |||
---|---|---|---|---|
// Canvas placement for placing a canvas texture onto osg objects. | ///@file Placement for putting a canvas texture onto OpenSceneGraph objects . | |||
// | // | |||
// It also provides a SGPickCallback for passing mouse events to the canvas and | // It also provides a SGPickCallback for passing mouse events to the canvas and | |||
// manages emissive lighting of the placed canvas. | // manages emissive lighting of the placed canvas. | |||
// | // | |||
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com> | // Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com> | |||
// | // | |||
// This library is free software; you can redistribute it and/or | // This library is free software; you can redistribute it and/or | |||
// modify it under the terms of the GNU Library General Public | // modify it under the terms of the GNU Library General Public | |||
// License as published by the Free Software Foundation; either | // License as published by the Free Software Foundation; either | |||
// version 2 of the License, or (at your option) any later version. | // version 2 of the License, or (at your option) any later version. | |||
// | // | |||
// This library is distributed in the hope that it will be useful, | // This library is distributed in the hope that it will be useful, | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef CANVAS_PICK_PLACEMENT_HXX_ | #ifndef CANVAS_OBJECT_PLACEMENT_HXX_ | |||
#define CANVAS_OBJECT_PLACEMENT_HXX_ | #define CANVAS_OBJECT_PLACEMENT_HXX_ | |||
#include "CanvasPlacement.hxx" | #include "CanvasPlacement.hxx" | |||
#include "canvas_fwd.hxx" | #include "canvas_fwd.hxx" | |||
#include <simgear/scene/util/SGSceneUserData.hxx> | #include <simgear/scene/util/SGSceneUserData.hxx> | |||
#include <osg/Material> | #include <osg/Material> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
/** | ||||
* Place a Canvas onto an osg object (as texture). | ||||
*/ | ||||
class ObjectPlacement: | class ObjectPlacement: | |||
public Placement | public Placement | |||
{ | { | |||
public: | public: | |||
typedef osg::ref_ptr<osg::Group> GroupPtr; | typedef osg::ref_ptr<osg::Group> GroupPtr; | |||
typedef osg::ref_ptr<osg::Material> MaterialPtr; | typedef osg::ref_ptr<osg::Material> MaterialPtr; | |||
ObjectPlacement( SGPropertyNode* node, | ObjectPlacement( SGPropertyNode* node, | |||
const GroupPtr& group, | const GroupPtr& group, | |||
skipping to change at line 75 | skipping to change at line 78 | |||
GroupPtr _group; | GroupPtr _group; | |||
MaterialPtr _material; | MaterialPtr _material; | |||
CanvasWeakPtr _canvas; | CanvasWeakPtr _canvas; | |||
PickCallbackPtr _pick_cb; | PickCallbackPtr _pick_cb; | |||
SGSceneUserDataPtr _scene_user_data; | SGSceneUserDataPtr _scene_user_data; | |||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace simgear | } // namespace simgear | |||
#endif /* CANVAS_PICK_PLACEMENT_HXX_ */ | #endif /* CANVAS_OBJECT_PLACEMENT_HXX_ */ | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 5 lines changed or added | |||
CanvasSystemAdapter.hxx | CanvasSystemAdapter.hxx | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_CANVAS_SYSTEM_ADAPTER_HXX_ | #ifndef SG_CANVAS_SYSTEM_ADAPTER_HXX_ | |||
#define SG_CANVAS_SYSTEM_ADAPTER_HXX_ | #define SG_CANVAS_SYSTEM_ADAPTER_HXX_ | |||
#include "canvas_fwd.hxx" | #include "canvas_fwd.hxx" | |||
class SGSubsystem; | ||||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace HTTP { class Client; } | ||||
namespace canvas | namespace canvas | |||
{ | { | |||
class SystemAdapter | class SystemAdapter | |||
{ | { | |||
public: | public: | |||
virtual ~SystemAdapter() {} | virtual ~SystemAdapter() {} | |||
virtual FontPtr getFont(const std::string& name) const = 0; | virtual FontPtr getFont(const std::string& name) const = 0; | |||
virtual void addCamera(osg::Camera* camera) const = 0; | virtual void addCamera(osg::Camera* camera) const = 0; | |||
virtual void removeCamera(osg::Camera* camera) const = 0; | virtual void removeCamera(osg::Camera* camera) const = 0; | |||
virtual osg::Image* getImage(const std::string& path) const = 0; | virtual osg::Image* getImage(const std::string& path) const = 0; | |||
virtual SGSubsystem* getSubsystem(const std::string& name) const = 0; | ||||
virtual HTTP::Client* getHTTPClient() const = 0; | ||||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace simgear | } // namespace simgear | |||
#endif /* SG_CANVAS_SYSTEM_ADAPTER_HXX_ */ | #endif /* SG_CANVAS_SYSTEM_ADAPTER_HXX_ */ | |||
End of changes. 3 change blocks. | ||||
0 lines changed or deleted | 5 lines changed or added | |||
CanvasText.hxx | CanvasText.hxx | |||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
Text( const CanvasWeakPtr& canvas, | Text( const CanvasWeakPtr& canvas, | |||
const SGPropertyNode_ptr& node, | const SGPropertyNode_ptr& node, | |||
const Style& parent_style, | const Style& parent_style, | |||
Element* parent = 0 ); | Element* parent = 0 ); | |||
~Text(); | ~Text(); | |||
void setText(const char* text); | void setText(const char* text); | |||
void setFont(const char* name); | void setFont(const char* name); | |||
void setAlignment(const char* align); | void setAlignment(const char* align); | |||
int heightForWidth(int w) const; | ||||
int maxWidth() const; | ||||
osg::Vec2 getNearestCursor(const osg::Vec2& pos) const; | osg::Vec2 getNearestCursor(const osg::Vec2& pos) const; | |||
protected: | protected: | |||
class TextOSG; | class TextOSG; | |||
osg::ref_ptr<TextOSG> _text; | osg::ref_ptr<TextOSG> _text; | |||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 2 lines changed or added | |||
Catalog.hxx | Catalog.hxx | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// You should have received a copy of the GNU General Public License | // You should have received a copy of the GNU General Public License | |||
// along with this program; if not, write to the Free Software | // along with this program; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | |||
// | // | |||
#ifndef SG_PACKAGE_CATALOG_HXX | #ifndef SG_PACKAGE_CATALOG_HXX | |||
#define SG_PACKAGE_CATALOG_HXX | #define SG_PACKAGE_CATALOG_HXX | |||
#include <vector> | #include <vector> | |||
#include <ctime> | #include <ctime> | |||
#include <map> | ||||
#include <simgear/misc/sg_path.hxx> | #include <simgear/misc/sg_path.hxx> | |||
#include <simgear/props/props.hxx> | #include <simgear/props/props.hxx> | |||
#include <simgear/structure/SGReferenced.hxx> | ||||
#include <simgear/structure/SGSharedPtr.hxx> | ||||
#include <simgear/package/Delegate.hxx> | #include <simgear/package/Delegate.hxx> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace HTTP { class Client; } | namespace HTTP { class Client; } | |||
namespace pkg | namespace pkg | |||
{ | { | |||
// forward decls | // forward decls | |||
class Package; | class Package; | |||
class Catalog; | class Catalog; | |||
class Root; | class Root; | |||
class Install; | ||||
typedef SGSharedPtr<Package> PackageRef; | ||||
typedef SGSharedPtr<Catalog> CatalogRef; | ||||
typedef SGSharedPtr<Install> InstallRef; | ||||
typedef std::vector<Package*> PackageList; | typedef std::vector<PackageRef> PackageList; | |||
typedef std::vector<Catalog*> CatalogList; | typedef std::vector<CatalogRef> CatalogList; | |||
class Catalog | class Catalog : public SGReferenced | |||
{ | { | |||
public: | public: | |||
virtual ~Catalog(); | virtual ~Catalog(); | |||
static Catalog* createFromUrl(Root* aRoot, const std::string& aUrl); | static CatalogRef createFromUrl(Root* aRoot, const std::string& aUrl); | |||
static Catalog* createFromPath(Root* aRoot, const SGPath& aPath); | static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath); | |||
static CatalogList allCatalogs(); | static CatalogList allCatalogs(); | |||
Root* root() const | Root* root() const | |||
{ return m_root;}; | { return m_root;}; | |||
/** | /** | |||
* perform a refresh of the catalog contents | * perform a refresh of the catalog contents | |||
*/ | */ | |||
void refresh(); | void refresh(); | |||
/** | ||||
* Get all packages in this catalog. | ||||
*/ | ||||
PackageList const& packages() const; | ||||
/** | /** | |||
* retrieve packages in this catalog matching a filter. | * retrieve packages in this catalog matching a filter. | |||
* filter consists of required / minimum values, AND-ed together. | * filter consists of required / minimum values, AND-ed together. | |||
*/ | */ | |||
PackageList packagesMatching(const SGPropertyNode* aFilter) const; | PackageList packagesMatching(const SGPropertyNode* aFilter) const; | |||
/** | /** | |||
* packages which are locally installed | ||||
*/ | ||||
PackageList installedPackages() const; | ||||
/** | ||||
* retrieve all the packages in the catalog which are installed | * retrieve all the packages in the catalog which are installed | |||
* and have a pendig update | * and have a pendig update | |||
*/ | */ | |||
PackageList packagesNeedingUpdate() const; | PackageList packagesNeedingUpdate() const; | |||
SGPath installRoot() const | SGPath installRoot() const | |||
{ return m_installRoot; } | { return m_installRoot; } | |||
std::string id() const; | std::string id() const; | |||
std::string url() const; | std::string url() const; | |||
std::string description() const; | std::string description() const; | |||
Package* getPackageById(const std::string& aId) const; | PackageRef getPackageById(const std::string& aId) const; | |||
InstallRef installForPackage(PackageRef pkg) const; | ||||
/** | /** | |||
* test if the catalog data was retrieved longer ago than the | * test if the catalog data was retrieved longer ago than the | |||
* maximum permitted age for this catalog. | * maximum permitted age for this catalog. | |||
*/ | */ | |||
bool needsRefresh() const; | bool needsRefresh() const; | |||
unsigned int ageInSeconds() const; | unsigned int ageInSeconds() const; | |||
/** | /** | |||
* access the raw property data in the catalog | * access the raw property data in the catalog | |||
*/ | */ | |||
SGPropertyNode* properties() const; | SGPropertyNode* properties() const; | |||
private: | private: | |||
Catalog(Root* aRoot); | Catalog(Root* aRoot); | |||
class Downloader; | class Downloader; | |||
friend class Downloader; | friend class Downloader; | |||
friend class Install; | ||||
void registerInstall(Install* ins); | ||||
void unregisterInstall(Install* ins); | ||||
void parseProps(const SGPropertyNode* aProps); | void parseProps(const SGPropertyNode* aProps); | |||
void refreshComplete(Delegate::FailureCode aReason); | void refreshComplete(Delegate::FailureCode aReason); | |||
void parseTimestamp(); | void parseTimestamp(); | |||
void writeTimestamp(); | void writeTimestamp(); | |||
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; | std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; | |||
Root* m_root; | Root* m_root; | |||
SGPropertyNode_ptr m_props; | SGPropertyNode_ptr m_props; | |||
SGPath m_installRoot; | SGPath m_installRoot; | |||
std::string m_url; | ||||
PackageList m_packages; | PackageList m_packages; | |||
time_t m_retrievedTime; | time_t m_retrievedTime; | |||
typedef std::map<std::string, Package*> PackageWeakMap; | ||||
PackageWeakMap m_variantDict; | ||||
// important that this is a weak-ref to Installs, | ||||
// since it is only cleaned up in the Install destructor | ||||
typedef std::map<PackageRef, Install*> PackageInstallDict; | ||||
PackageInstallDict m_installed; | ||||
}; | }; | |||
} // of namespace pkg | } // of namespace pkg | |||
} // of namespace simgear | } // of namespace simgear | |||
#endif // of SG_PACKAGE_CATALOG_HXX | #endif // of SG_PACKAGE_CATALOG_HXX | |||
End of changes. 13 change blocks. | ||||
6 lines changed or deleted | 41 lines changed or added | |||
Delegate.hxx | Delegate.hxx | |||
---|---|---|---|---|
skipping to change at line 40 | skipping to change at line 40 | |||
/** | /** | |||
* package delegate is the mechanism to discover progress / completion / | * package delegate is the mechanism to discover progress / completion / | |||
* errors in packaging steps asynchronously. | * errors in packaging steps asynchronously. | |||
*/ | */ | |||
class Delegate | class Delegate | |||
{ | { | |||
public: | public: | |||
typedef enum { | typedef enum { | |||
FAIL_SUCCESS = 0, ///< not a failure :) | FAIL_SUCCESS = 0, ///< not a failure :) | |||
FAIL_UNKNOWN = 1, | FAIL_UNKNOWN = 1, | |||
FAIL_IN_PROGRESS, ///< downloading/installation in progress (not a failure :P) | ||||
FAIL_CHECKSUM, ///< package MD5 verificstion failed | FAIL_CHECKSUM, ///< package MD5 verificstion failed | |||
FAIL_DOWNLOAD, ///< network issue | FAIL_DOWNLOAD, ///< network issue | |||
FAIL_EXTRACT, ///< package archive failed to extract cleanly | FAIL_EXTRACT, ///< package archive failed to extract cleanly | |||
FAIL_FILESYSTEM, ///< unknown filesystem error occurred | FAIL_FILESYSTEM, ///< unknown filesystem error occurred | |||
FAIL_VERSION ///< version check mismatch | FAIL_VERSION ///< version check mismatch | |||
} FailureCode; | } FailureCode; | |||
virtual ~Delegate() { } | virtual ~Delegate() { } | |||
/** | /** | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 1 lines changed or added | |||
Effect.hxx | Effect.hxx | |||
---|---|---|---|---|
skipping to change at line 57 | skipping to change at line 57 | |||
class Technique; | class Technique; | |||
class Effect; | class Effect; | |||
class SGReaderWriterOptions; | class SGReaderWriterOptions; | |||
/** | /** | |||
* Object to be initialized at some point after an effect -- and its | * Object to be initialized at some point after an effect -- and its | |||
* containing effect geode -- are hooked into the scene graph. Some | * containing effect geode -- are hooked into the scene graph. Some | |||
* things, like manipulations of the global property tree, are are | * things, like manipulations of the global property tree, are are | |||
* only safe in the update process. | * only safe in the update process. | |||
*/ | */ | |||
class DeferredPropertyListener { | ||||
class InitializeWhenAdded | ||||
{ | ||||
public: | public: | |||
InitializeWhenAdded() : _initialized(false) {}; | virtual void activate(SGPropertyNode* propRoot) {}; | |||
virtual ~InitializeWhenAdded() {}; | virtual ~DeferredPropertyListener() {}; | |||
void initOnAdd(Effect* effect, SGPropertyNode* propRoot) | ||||
{ | ||||
if (!_initialized) { | ||||
initOnAddImpl(effect, propRoot); | ||||
_initialized = true; | ||||
} | ||||
} | ||||
bool getInitialized() const { return _initialized; } | ||||
private: | ||||
virtual void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) = | ||||
0; | ||||
bool _initialized; | ||||
}; | }; | |||
class Effect : public osg::Object | class Effect : public osg::Object | |||
{ | { | |||
public: | public: | |||
META_Object(simgear,Effect) | META_Object(simgear,Effect) | |||
Effect(); | Effect(); | |||
Effect(const Effect& rhs, | Effect(const Effect& rhs, | |||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); | const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); | |||
osg::StateSet* getDefaultStateSet(); | osg::StateSet* getDefaultStateSet(); | |||
skipping to change at line 107 | skipping to change at line 94 | |||
SGPropertyNode_ptr root; | SGPropertyNode_ptr root; | |||
// Pointer to the parameters node, if it exists | // Pointer to the parameters node, if it exists | |||
SGPropertyNode_ptr parametersProp; | SGPropertyNode_ptr parametersProp; | |||
Technique* chooseTechnique(osg::RenderInfo* renderInfo); | Technique* chooseTechnique(osg::RenderInfo* renderInfo); | |||
virtual void resizeGLObjectBuffers(unsigned int maxSize); | virtual void resizeGLObjectBuffers(unsigned int maxSize); | |||
virtual void releaseGLObjects(osg::State* state = 0) const; | virtual void releaseGLObjects(osg::State* state = 0) const; | |||
/** | /** | |||
* Build the techniques from the effect properties. | * Build the techniques from the effect properties. | |||
*/ | */ | |||
bool realizeTechniques(const SGReaderWriterOptions* options = 0); | bool realizeTechniques(const SGReaderWriterOptions* options = 0); | |||
/** | void addDeferredPropertyListener(DeferredPropertyListener* listener); | |||
* Updaters that should be derefed when the effect is | ||||
* deleted. Updaters arrange to be run by listening on properties | ||||
* or something. | ||||
*/ | ||||
struct Updater : public virtual SGReferenced | ||||
{ | ||||
virtual ~Updater() {} | ||||
}; | ||||
void addUpdater(Updater* data) { _extraData.push_back(data); } | ||||
// Callback that is added to the effect geode to initialize the | // Callback that is added to the effect geode to initialize the | |||
// effect. | // effect. | |||
friend struct InitializeCallback; | friend struct InitializeCallback; | |||
struct InitializeCallback : public UpdateOnceCallback | struct InitializeCallback : public UpdateOnceCallback | |||
{ | { | |||
void doUpdate(osg::Node* node, osg::NodeVisitor* nv); | void doUpdate(osg::Node* node, osg::NodeVisitor* nv); | |||
}; | }; | |||
protected: | protected: | |||
std::vector<SGSharedPtr<Updater> > _extraData; | ||||
~Effect(); | ~Effect(); | |||
// Support for a cache of effects that inherit from this one, so | // Support for a cache of effects that inherit from this one, so | |||
// Effect objects with the same parameters and techniques can be | // Effect objects with the same parameters and techniques can be | |||
// shared. | // shared. | |||
struct Key | struct Key | |||
{ | { | |||
Key() {} | Key() {} | |||
Key(SGPropertyNode* unmerged_, const osgDB::FilePathList& paths_) | Key(SGPropertyNode* unmerged_, const osgDB::FilePathList& paths_) | |||
: unmerged(unmerged_), paths(paths_) | : unmerged(unmerged_), paths(paths_) | |||
{ | { | |||
End of changes. 4 change blocks. | ||||
28 lines changed or deleted | 4 lines changed or added | |||
EffectBuilder.hxx | EffectBuilder.hxx | |||
---|---|---|---|---|
skipping to change at line 497 | skipping to change at line 497 | |||
template<typename OSGParam, typename Obj> | template<typename OSGParam, typename Obj> | |||
OSGFunctor<OSGParam, Obj, void (Obj::*const)(const OSGParam&)> | OSGFunctor<OSGParam, Obj, void (Obj::*const)(const OSGParam&)> | |||
make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&)) | make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&)) | |||
{ | { | |||
return OSGFunctor<OSGParam, Obj, | return OSGFunctor<OSGParam, Obj, | |||
void (Obj::* const)(const OSGParam&)>(obj, func); | void (Obj::* const)(const OSGParam&)>(obj, func); | |||
} | } | |||
template<typename OSGParamType, typename ObjType, typename F> | template<typename OSGParamType, typename ObjType, typename F> | |||
class ScalarChangeListener | class ScalarChangeListener | |||
: public SGPropertyChangeListener, public InitializeWhenAdded, | : public SGPropertyChangeListener, public DeferredPropertyListener | |||
public Effect::Updater | ||||
{ | { | |||
public: | public: | |||
ScalarChangeListener(ObjType* obj, const F& setter, | ScalarChangeListener(ObjType* obj, const F& setter, | |||
const std::string& propName) | const std::string& propName) | |||
: _obj(obj), _setter(setter) | : _obj(obj), _setter(setter) | |||
{ | { | |||
_propName = new std::string(propName); | _propName = new std::string(propName); | |||
SG_LOG(SG_GL,SG_DEBUG,"Creating ScalarChangeListener for " << *_prop Name ); | ||||
} | } | |||
virtual ~ScalarChangeListener() | virtual ~ScalarChangeListener() | |||
{ | { | |||
delete _propName; | delete _propName; | |||
_propName = 0; | _propName = 0; | |||
} | } | |||
void valueChanged(SGPropertyNode* node) | void valueChanged(SGPropertyNode* node) | |||
{ | { | |||
_setter(_obj.get(), node->getValue<OSGParamType>()); | _setter(_obj.get(), node->getValue<OSGParamType>()); | |||
} | } | |||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) | void activate(SGPropertyNode* propRoot) | |||
{ | { | |||
SG_LOG(SG_GL,SG_DEBUG,"Adding change listener to " << *_propName ); | ||||
SGPropertyNode* listenProp = makeNode(propRoot, *_propName); | SGPropertyNode* listenProp = makeNode(propRoot, *_propName); | |||
delete _propName; | delete _propName; | |||
_propName = 0; | _propName = 0; | |||
if (listenProp) | if (listenProp) | |||
listenProp->addChangeListener(this, true); | listenProp->addChangeListener(this, true); | |||
} | } | |||
private: | private: | |||
osg::ref_ptr<ObjType> _obj; | osg::ref_ptr<ObjType> _obj; | |||
F _setter; | F _setter; | |||
std::string* _propName; | std::string* _propName; | |||
}; | }; | |||
template<typename T, typename Func> | template<typename T, typename Func> | |||
class EffectExtendedPropListener : public InitializeWhenAdded, | class EffectExtendedPropListener : public DeferredPropertyListener | |||
public Effect::Updater | ||||
{ | { | |||
public: | public: | |||
template<typename Itr> | template<typename Itr> | |||
EffectExtendedPropListener(const Func& func, | EffectExtendedPropListener(const Func& func, | |||
const std::string* propName, Itr childNamesB egin, | const std::string* propName, Itr childNamesB egin, | |||
Itr childNamesEnd) | Itr childNamesEnd) | |||
: _propName(0), _func(func) | : _propName(0), _func(func) | |||
{ | { | |||
if (propName) | if (propName) | |||
_propName = new std::string(*propName); | _propName = new std::string(*propName); | |||
_childNames = new std::vector<std::string>(childNamesBegin, | _childNames = new std::vector<std::string>(childNamesBegin, | |||
childNamesEnd); | childNamesEnd); | |||
} | } | |||
virtual ~EffectExtendedPropListener() | virtual ~EffectExtendedPropListener() | |||
{ | { | |||
delete _propName; | delete _propName; | |||
delete _childNames; | delete _childNames; | |||
} | } | |||
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) | void activate(SGPropertyNode* propRoot) | |||
{ | { | |||
SGPropertyNode* parent = 0; | SGPropertyNode* parent = 0; | |||
if (_propName) | if (_propName) | |||
parent = propRoot->getNode(*_propName, true); | parent = propRoot->getNode(*_propName, true); | |||
else | else | |||
parent = propRoot; | parent = propRoot; | |||
_propListener | _propListener | |||
= new ExtendedPropListener<T, Func>(parent, _childNames->begin( ), | = new ExtendedPropListener<T, Func>(parent, _childNames->begin( ), | |||
_childNames->end(), | _childNames->end(), | |||
_func, true); | _func, true); | |||
skipping to change at line 575 | skipping to change at line 575 | |||
_childNames = 0; | _childNames = 0; | |||
} | } | |||
private: | private: | |||
std::string* _propName; | std::string* _propName; | |||
std::vector<std::string>* _childNames; | std::vector<std::string>* _childNames; | |||
SGSharedPtr<ExtendedPropListener<T, Func> > _propListener; | SGSharedPtr<ExtendedPropListener<T, Func> > _propListener; | |||
Func _func; | Func _func; | |||
}; | }; | |||
template<typename T, typename Func, typename Itr> | template<typename T, typename Func, typename Itr> | |||
Effect::Updater* | DeferredPropertyListener* | |||
new_EEPropListener(const Func& func, const std::string* propName, | new_EEPropListener(const Func& func, const std::string* propName, | |||
const Itr& namesBegin, const Itr& namesEnd) | const Itr& namesBegin, const Itr& namesEnd) | |||
{ | { | |||
return new EffectExtendedPropListener<T, Func> | return new EffectExtendedPropListener<T, Func> | |||
(func, 0, namesBegin, namesEnd); | (func, 0, namesBegin, namesEnd); | |||
} | } | |||
/** | /** | |||
* Set DYNAMIC data variance on an osg::Object. | * Set DYNAMIC data variance on an osg::Object. | |||
*/ | */ | |||
skipping to change at line 624 | skipping to change at line 624 | |||
if (!valProp) | if (!valProp) | |||
return; | return; | |||
if (valProp->nChildren() == 0) { | if (valProp->nChildren() == 0) { | |||
setter(obj, valProp->getValue<OSGParamType>()); | setter(obj, valProp->getValue<OSGParamType>()); | |||
} else { | } else { | |||
setDynamicVariance(obj); | setDynamicVariance(obj); | |||
std::string propName = getGlobalProperty(valProp, options); | std::string propName = getGlobalProperty(valProp, options); | |||
ScalarChangeListener<OSGParamType, ObjType, F>* listener | ScalarChangeListener<OSGParamType, ObjType, F>* listener | |||
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, sette r, | = new ScalarChangeListener<OSGParamType, ObjType, F>(obj, sette r, | |||
propName); | propName); | |||
effect->addUpdater(listener); | effect->addDeferredPropertyListener(listener); | |||
} | } | |||
return; | ||||
} | } | |||
template<typename OSGParamType, typename ObjType, typename SetterReturn> | template<typename OSGParamType, typename ObjType, typename SetterReturn> | |||
inline void | inline void | |||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj , | initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj , | |||
SetterReturn (ObjType::*setter)(const OSGParamType), | SetterReturn (ObjType::*setter)(const OSGParamType), | |||
const SGReaderWriterOptions* options) | const SGReaderWriterOptions* options) | |||
{ | { | |||
initFromParameters<OSGParamType>(effect, prop, obj, | initFromParameters<OSGParamType>(effect, prop, obj, | |||
boost::bind(setter, _1, _2), options); | boost::bind(setter, _1, _2), options); | |||
} | } | |||
/* | /* | |||
* Initialize vector parameters from individual properties. | * Initialize vector parameters from individual properties. | |||
* The parameter may be updated at runtime. | * The parameter may be updated at runtime. | |||
* | * | |||
* If the value is specified directly, set it. Otherwise, use the | * If the value is specified directly, set it. Otherwise, use the | |||
* <use> tag to look at the parameters. Again, if there is a value | * <use> tag to look at the parameters. Again, if there is a value | |||
* there set it directly. Otherwise, the parameter contains one or several | * there set it directly. Otherwise, the parameter contains one or several | |||
skipping to change at line 678 | skipping to change at line 679 | |||
return; | return; | |||
if (valProp->nChildren() == 0) { // Has <use>? | if (valProp->nChildren() == 0) { // Has <use>? | |||
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()) ); | setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()) ); | |||
} else { | } else { | |||
setDynamicVariance(obj); | setDynamicVariance(obj); | |||
std::vector<std::string> paramNames | std::vector<std::string> paramNames | |||
= getVectorProperties(valProp, options,numComponents, nameItr); | = getVectorProperties(valProp, options,numComponents, nameItr); | |||
if (paramNames.empty()) | if (paramNames.empty()) | |||
throw BuilderException(); | throw BuilderException(); | |||
std::vector<std::string>::const_iterator pitr = paramNames.begin(); | std::vector<std::string>::const_iterator pitr = paramNames.begin(); | |||
Effect::Updater* listener | DeferredPropertyListener* listener | |||
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType> | = new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType> | |||
(obj, setter), | (obj, setter), | |||
0, pitr, pitr + numComponents); | 0, pitr, pitr + numComponents); | |||
effect->addUpdater(listener); | effect->addDeferredPropertyListener(listener); | |||
} | } | |||
return; | ||||
} | } | |||
template<typename OSGParamType, typename ObjType, typename NameItrType, | template<typename OSGParamType, typename ObjType, typename NameItrType, | |||
typename SetterReturn> | typename SetterReturn> | |||
inline void | inline void | |||
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj , | initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj , | |||
SetterReturn (ObjType::*setter)(const OSGParamType&), | SetterReturn (ObjType::*setter)(const OSGParamType&), | |||
NameItrType nameItr, const SGReaderWriterOptions* option s) | NameItrType nameItr, const SGReaderWriterOptions* option s) | |||
{ | { | |||
initFromParameters<OSGParamType>(effect, prop, obj, | initFromParameters<OSGParamType>(effect, prop, obj, | |||
End of changes. 13 change blocks. | ||||
11 lines changed or deleted | 13 lines changed or added | |||
Ghost.hxx | Ghost.hxx | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_NASAL_GHOST_HXX_ | #ifndef SG_NASAL_GHOST_HXX_ | |||
#define SG_NASAL_GHOST_HXX_ | #define SG_NASAL_GHOST_HXX_ | |||
#include "NasalCallContext.hxx" | #include "NasalCallContext.hxx" | |||
#include "NasalObjectHolder.hxx" | #include "NasalObjectHolder.hxx" | |||
#include <simgear/debug/logstream.hxx> | #include <simgear/debug/logstream.hxx> | |||
#include <simgear/structure/SGWeakReferenced.hxx> | ||||
#include <simgear/structure/SGWeakPtr.hxx> | ||||
#include <boost/bind.hpp> | #include <boost/bind.hpp> | |||
#include <boost/call_traits.hpp> | #include <boost/call_traits.hpp> | |||
#include <boost/function.hpp> | #include <boost/function.hpp> | |||
#include <boost/lambda/lambda.hpp> | #include <boost/lambda/lambda.hpp> | |||
#include <boost/mpl/has_xxx.hpp> | #include <boost/mpl/has_xxx.hpp> | |||
#include <boost/preprocessor/iteration/iterate.hpp> | #include <boost/preprocessor/iteration/iterate.hpp> | |||
#include <boost/shared_ptr.hpp> | #include <boost/shared_ptr.hpp> | |||
#include <boost/utility/enable_if.hpp> | #include <boost/utility/enable_if.hpp> | |||
#include <map> | #include <map> | |||
template<class T> | template<class T> | |||
inline T* get_pointer(boost::weak_ptr<T> const& p) | inline T* get_pointer(boost::weak_ptr<T> const& p) | |||
{ | { | |||
return p.lock().get(); | return p.lock().get(); | |||
} | } | |||
template<class T> | ||||
inline T* get_pointer(SGWeakPtr<T> const& p) | ||||
{ | ||||
return p.lock().get(); | ||||
} | ||||
namespace osg | ||||
{ | ||||
template<class T> | ||||
inline T* get_pointer(observer_ptr<T> const& p) | ||||
{ | ||||
ref_ptr<T> ref; | ||||
p.lock(ref); | ||||
return ref.get(); | ||||
} | ||||
} | ||||
template<class T> | ||||
inline typename boost::enable_if< | ||||
boost::is_pointer<T>, | ||||
T | ||||
>::type | ||||
get_pointer(T ptr) | ||||
{ | ||||
return ptr; | ||||
} | ||||
// Both ways of retrieving the address of a static member function | ||||
// should be legal but not all compilers know this. | ||||
// g++-4.4.7+ has been tested to work with both versions | ||||
#if defined(SG_GCC_VERSION) && SG_GCC_VERSION < 40407 | ||||
// The old version of g++ used on Jenkins (16.11.2012) only compiles | ||||
// this version. | ||||
# define SG_GET_TEMPLATE_MEMBER(type, member) &member | ||||
// With old g++ on Jenkins (21.07.2014), ADL for static_pointer_cast does | ||||
not | ||||
// work. | ||||
using boost::static_pointer_cast; | ||||
using osg::static_pointer_cast; | ||||
#else | ||||
// VS (2008, 2010, ... ?) only allow this version. | ||||
# define SG_GET_TEMPLATE_MEMBER(type, member) &type::template member | ||||
#endif | ||||
/** | /** | |||
* Bindings between C++ and the Nasal scripting language | * Bindings between C++ and the Nasal scripting language | |||
*/ | */ | |||
namespace nasal | namespace nasal | |||
{ | { | |||
namespace internal | namespace internal | |||
{ | { | |||
/** | /** | |||
* Metadata for Ghost object types | * Metadata for Ghost object types | |||
*/ | */ | |||
class GhostMetadata | class GhostMetadata | |||
{ | { | |||
public: | public: | |||
typedef void(*Deleter)(void*); | ||||
typedef std::vector<std::pair<Deleter, void*> > DestroyList; | ||||
static DestroyList _destroy_list; | ||||
/** | /** | |||
* Add a nasal base class to the ghost. Will be available in the gh osts | * Add a nasal base class to the ghost. Will be available in the gh osts | |||
* parents array. | * parents array. | |||
*/ | */ | |||
void addNasalBase(const naRef& parent) | void addNasalBase(const naRef& parent); | |||
{ | ||||
assert( naIsHash(parent) ); | ||||
_parents.push_back(parent); | ||||
} | ||||
bool isBaseOf(naGhostType* ghost_type) const | ||||
{ | ||||
if( ghost_type == _ghost_type_ptr ) | ||||
return true; | ||||
for( DerivedList::const_iterator derived = _derived_classes.begin | bool isInstance(naGhostType* ghost_type, bool& is_weak) const; | |||
(); | ||||
derived != _derived_classes.end( | ||||
); | ||||
++derived ) | ||||
{ | ||||
if( (*derived)->isBaseOf(ghost_type) ) | ||||
return true; | ||||
} | ||||
return false; | ||||
} | ||||
protected: | protected: | |||
typedef std::vector<const GhostMetadata*> DerivedList; | const std::string _name_strong, | |||
_name_weak; | ||||
const std::string _name; | const naGhostType *_ghost_type_strong_ptr, | |||
const naGhostType *_ghost_type_ptr; | *_ghost_type_weak_ptr; | |||
DerivedList _derived_classes; | ||||
std::vector<naRef> _parents; | std::vector<naRef> _parents; | |||
GhostMetadata( const std::string& name, | GhostMetadata( const std::string& name, | |||
const naGhostType* ghost_type ): | const naGhostType* ghost_type_strong, | |||
_name(name), | const naGhostType* ghost_type_weak ); | |||
_ghost_type_ptr(ghost_type) | ||||
{ | ||||
} | ||||
void addDerived(const GhostMetadata* derived) | ||||
{ | ||||
assert(derived); | ||||
_derived_classes.push_back(derived); | ||||
SG_LOG | void addDerived(const GhostMetadata* derived); | |||
( | ||||
SG_NASAL, | ||||
SG_INFO, | ||||
"Ghost::addDerived: " << _name << " -> " << derived->_name | ||||
); | ||||
} | ||||
naRef getParents(naContext c) | naRef getParents(naContext c); | |||
{ | ||||
return nasal::to_nasal(c, _parents); | ||||
} | ||||
}; | }; | |||
/** | /** | |||
* Hold callable method and convert to Nasal function if required. | * Hold callable method and convert to Nasal function if required. | |||
*/ | */ | |||
class MethodHolder | class MethodHolder: | |||
public SGWeakReferenced | ||||
{ | { | |||
public: | public: | |||
virtual ~MethodHolder() {} | virtual ~MethodHolder() {} | |||
naRef get_naRef(naContext c) | naRef get_naRef(naContext c) | |||
{ | { | |||
if( !_obj ) | if( !_obj.valid() ) | |||
_obj = ObjectHolder::makeShared(createNasalObject(c)); | _obj.reset(createNasalObject(c)); | |||
return _obj->get_naRef(); | return _obj.get_naRef(); | |||
} | } | |||
protected: | protected: | |||
ObjectHolderRef _obj; | ObjectHolder<> _obj; | |||
virtual naRef createNasalObject(naContext c) = 0; | virtual naRef createNasalObject(naContext c) = 0; | |||
}; | }; | |||
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) | BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type) | |||
template<class T> | template<class T> | |||
struct reduced_type | struct reduced_type | |||
{ | { | |||
typedef typename boost::remove_cv< | typedef typename boost::remove_cv< | |||
typename boost::remove_reference<T>::type | typename boost::remove_reference<T>::type | |||
>::type type; | >::type type; | |||
}; | }; | |||
template<class T1, class T2> | template<class T1, class T2> | |||
struct reduced_is_same: | struct reduced_is_same: | |||
public boost::is_same<typename reduced_type<T1>::type, T2> | public boost::is_same<typename reduced_type<T1>::type, T2> | |||
{}; | {}; | |||
} | } | |||
/** @brief Destroy all ghost queued for deletion. | ||||
* | ||||
* This needs can not be done directly during garbage collection, as | ||||
* destructors may execute Nasal code which requires creating new Nasal | ||||
* contexts. Creating a Nasal context during garbage collection is not | ||||
* possible and leads to a dead lock. | ||||
*/ | ||||
void ghostProcessDestroyList(); | ||||
typedef SGSharedPtr<internal::MethodHolder> MethodHolderPtr; | ||||
typedef SGWeakPtr<internal::MethodHolder> MethodHolderWeakPtr; | ||||
// Dummy template to create shorter and easy to understand compile errors | ||||
if | ||||
// trying to wrap the wrong type as a Ghost. | ||||
template<class T, class Enable = void> | ||||
class Ghost | ||||
{ | ||||
public: | ||||
BOOST_STATIC_ASSERT(("Ghost can only wrap shared pointer!" | ||||
&& is_strong_ref<T>::value | ||||
)); | ||||
static Ghost& init(const std::string& name); | ||||
static bool isInit(); | ||||
}; | ||||
/** | /** | |||
* Class for exposing C++ objects to Nasal | * Class for exposing C++ objects to Nasal | |||
* | * | |||
* @code{cpp} | * @code{cpp} | |||
* // Example class to be exposed to Nasal | * // Example class to be exposed to Nasal | |||
* class MyClass | * class MyClass | |||
* { | * { | |||
* public: | * public: | |||
* void setX(int x); | * void setX(int x); | |||
* int getX() const; | * int getX() const; | |||
skipping to change at line 198 | skipping to change at line 238 | |||
* // Methods can be nearly anything callable and accepting a referen ce | * // Methods can be nearly anything callable and accepting a referen ce | |||
* // to an instance of the class type. (member functions, free funct ions | * // to an instance of the class type. (member functions, free funct ions | |||
* // and anything else bindable using boost::function and boost::bin d) | * // and anything else bindable using boost::function and boost::bin d) | |||
* .method("myMember", &MyClass::myMember) | * .method("myMember", &MyClass::myMember) | |||
* .method("doSomething", &MyClass::doSomethingElse) | * .method("doSomething", &MyClass::doSomethingElse) | |||
* .method("other", &myOtherFreeMember); | * .method("other", &myOtherFreeMember); | |||
* } | * } | |||
* @endcode | * @endcode | |||
*/ | */ | |||
template<class T> | template<class T> | |||
class Ghost: | class Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type>: | |||
public internal::GhostMetadata | public internal::GhostMetadata | |||
{ | { | |||
BOOST_STATIC_ASSERT( internal::has_element_type<T>::value ); | // Shared pointer required for Ghost (no weak pointer!) | |||
BOOST_STATIC_ASSERT((is_strong_ref<T>::value)); | ||||
public: | public: | |||
typedef typename T::element_type raw_typ e; | typedef typename T::element_type raw_typ e; | |||
typedef T pointer | typedef typename shared_ptr_traits<T>::strong_ref strong_ | |||
; | ref; | |||
typedef typename shared_ptr_traits<T>::weak_ref weak_re | ||||
f; | ||||
typedef naRef (raw_type::*member_func_t)(const CallContext&); | typedef naRef (raw_type::*member_func_t)(const CallContext&); | |||
typedef naRef (*free_func_t)(raw_type&, const CallContext&); | typedef naRef (*free_func_t)(raw_type&, const CallContext&); | |||
typedef boost::function<naRef(naContext, raw_type&)> getter_ | typedef boost::function<naRef(raw_type&, naContext)> getter_ | |||
t; | t; | |||
typedef boost::function<void(naContext, raw_type&, naRef)> setter_ | typedef boost::function<void( raw_type&, naContext, naRef)> setter_ | |||
t; | t; | |||
typedef boost::function<naRef(raw_type&, const CallContext&)> method_ t; | typedef boost::function<naRef(raw_type&, const CallContext&)> method_ t; | |||
typedef boost::shared_ptr<internal::MethodHolder> MethodHolderPtr; | typedef boost::function<bool( raw_type&, | |||
naContext, | ||||
const std::string&, | ||||
naRef& )> fallback_getter_ | ||||
t; | ||||
typedef boost::function<bool( raw_type&, | ||||
naContext, | ||||
const std::string&, | ||||
naRef )> fallback_setter_ | ||||
t; | ||||
class MethodHolder: | class MethodHolder: | |||
public internal::MethodHolder | public internal::MethodHolder | |||
{ | { | |||
public: | public: | |||
explicit MethodHolder(const method_t& method): | explicit MethodHolder(const method_t& method): | |||
_method(method) | _method(method) | |||
{} | {} | |||
protected: | protected: | |||
typedef SGSharedPtr<MethodHolder> SharedPtr; | ||||
typedef SGWeakPtr<MethodHolder> WeakPtr; | ||||
method_t _method; | method_t _method; | |||
virtual naRef createNasalObject(naContext c) | virtual naRef createNasalObject(naContext c) | |||
{ | { | |||
return naNewFunc(c, naNewCCodeU(c, &MethodHolder::call, this)); | return naNewFunc | |||
( | ||||
c, | ||||
naNewCCodeUD( c, | ||||
&MethodHolder::call, | ||||
new WeakPtr(this), | ||||
&destroyHolder ) | ||||
); | ||||
} | ||||
static void destroyHolder(void* user_data) | ||||
{ | ||||
delete static_cast<WeakPtr*>(user_data); | ||||
} | } | |||
static naRef call( naContext c, | static naRef call( naContext c, | |||
naRef me, | naRef me, | |||
int argc, | int argc, | |||
naRef* args, | naRef* args, | |||
void* user_data ) | void* user_data ) | |||
{ | { | |||
MethodHolder* holder = static_cast<MethodHolder*>(user_data); | WeakPtr* holder_weak = static_cast<WeakPtr*>(user_data); | |||
if( !holder ) | if( !holder_weak ) | |||
naRuntimeError(c, "invalid method holder!"); | naRuntimeError(c, "invalid method holder!"); | |||
try | try | |||
{ | { | |||
SharedPtr holder = holder_weak->lock(); | ||||
if( !holder ) | ||||
throw std::runtime_error("holder has expired"); | ||||
// Keep reference for duration of call to prevent expiring | ||||
// TODO not needed for strong referenced ghost | ||||
strong_ref ref = fromNasal(c, me); | ||||
if( !ref ) | ||||
{ | ||||
naGhostType* ghost_type = naGhost_type(me); | ||||
naRuntimeError | ||||
( | ||||
c, | ||||
"method called on object of wrong type: " | ||||
"is '%s' expected '%s'", | ||||
naIsNil(me) ? "nil" | ||||
: (ghost_type ? ghost_type->name : "unknown") | ||||
, | ||||
_ghost_type_strong.name | ||||
); | ||||
} | ||||
return holder->_method | return holder->_method | |||
( | ( | |||
requireObject(c, me), | *get_pointer(ref), | |||
CallContext(c, argc, args) | CallContext(c, argc, args) | |||
); | ); | |||
} | } | |||
catch(const std::exception& ex) | catch(const std::exception& ex) | |||
{ | { | |||
naRuntimeError(c, "Fatal error in method call: %s", ex.what() ); | naRuntimeError(c, "Fatal error in method call: %s", ex.what() ); | |||
} | } | |||
catch(...) | catch(...) | |||
{ | { | |||
naRuntimeError(c, "Unknown exception in method call."); | naRuntimeError(c, "Unknown exception in method call."); | |||
skipping to change at line 335 | skipping to change at line 421 | |||
boost::is_base_of<GhostMetadata, BaseGhost>, | boost::is_base_of<GhostMetadata, BaseGhost>, | |||
Ghost | Ghost | |||
>::type& | >::type& | |||
bases() | bases() | |||
{ | { | |||
BOOST_STATIC_ASSERT | BOOST_STATIC_ASSERT | |||
(( | (( | |||
boost::is_base_of<typename BaseGhost::raw_type, raw_type>::value | boost::is_base_of<typename BaseGhost::raw_type, raw_type>::value | |||
)); | )); | |||
typedef typename BaseGhost::strong_ref base_ref; | ||||
BaseGhost* base = BaseGhost::getSingletonPtr(); | BaseGhost* base = BaseGhost::getSingletonPtr(); | |||
base->addDerived | base->addDerived( | |||
( | ||||
this, | this, | |||
// Both ways of retrieving the address of a static member functio | SG_GET_TEMPLATE_MEMBER(Ghost, toNasal<BaseGhost>), | |||
n | SG_GET_TEMPLATE_MEMBER(Ghost, fromNasalWithCast<base_ref>) | |||
// should be legal but not all compilers know this. | ||||
// g++-4.4.7+ has been tested to work with both versions | ||||
#if defined(SG_GCC_VERSION) && SG_GCC_VERSION < 40407 | ||||
// The old version of g++ used on Jenkins (16.11.2012) only compi | ||||
les | ||||
// this version. | ||||
&getTypeFor<BaseGhost> | ||||
#else | ||||
// VS (2008, 2010, ... ?) only allow this version. | ||||
&Ghost::getTypeFor<BaseGhost> | ||||
#endif | ||||
); | ); | |||
// Replace any getter that is not available in the current class. | // Replace any getter that is not available in the current class. | |||
// TODO check if this is the correct behavior of function overridin g | // TODO check if this is the correct behavior of function overridin g | |||
for( typename BaseGhost::MemberMap::const_iterator member = | for( typename BaseGhost::MemberMap::const_iterator member = | |||
base->_members.begin(); | base->_members.begin(); | |||
member != base->_members.end(); | member != base->_members.end(); | |||
++member ) | ++member ) | |||
{ | { | |||
if( _members.find(member->first) == _members.end() ) | if( _members.find(member->first) == _members.end() ) | |||
_members[member->first] = member_t | _members[member->first] = member_t | |||
( | ( | |||
member->second.getter, | member->second.getter, | |||
member->second.setter, | member->second.setter, | |||
member->second.func | member->second.func | |||
); | ); | |||
} | } | |||
if( !_fallback_setter ) | ||||
_fallback_setter = base->_fallback_setter; | ||||
if( !_fallback_getter ) | ||||
_fallback_getter = base->_fallback_getter; | ||||
return *this; | return *this; | |||
} | } | |||
/** | /** | |||
* Register a base class for this ghost. The base class needs to be | * Register a base class for this ghost. The base class needs to be | |||
* registers on its own before it can be used as base class. | * registers on its own before it can be used as base class. | |||
* | * | |||
* @tparam Base Type of base class (Base as used in Ghost<BasePtr>) | * @tparam Base Type of base class (Base as used in Ghost<BasePtr>) | |||
* | * | |||
* @code{cpp} | * @code{cpp} | |||
skipping to change at line 426 | skipping to change at line 509 | |||
* | * | |||
*/ | */ | |||
template<class Ret, class Param> | template<class Ret, class Param> | |||
Ghost& member( const std::string& field, | Ghost& member( const std::string& field, | |||
Ret (raw_type::*getter)() const, | Ret (raw_type::*getter)() const, | |||
void (raw_type::*setter)(Param) ) | void (raw_type::*setter)(Param) ) | |||
{ | { | |||
return member(field, to_getter(getter), to_setter(setter)); | return member(field, to_getter(getter), to_setter(setter)); | |||
} | } | |||
template<class Param> | ||||
Ghost& member( const std::string& field, | ||||
const getter_t& getter, | ||||
void (raw_type::*setter)(Param) ) | ||||
{ | ||||
return member(field, getter, to_setter(setter)); | ||||
} | ||||
template<class Ret> | ||||
Ghost& member( const std::string& field, | ||||
Ret (raw_type::*getter)() const, | ||||
const setter_t& setter ) | ||||
{ | ||||
return member(field, to_getter(getter), setter); | ||||
} | ||||
/** | /** | |||
* Register a read only member variable. | * Register a read only member variable. | |||
* | * | |||
* @param field Name of member | * @param field Name of member | |||
* @param getter Getter for variable | * @param getter Getter for variable | |||
*/ | */ | |||
template<class Ret> | template<class Ret> | |||
Ghost& member( const std::string& field, | Ghost& member( const std::string& field, | |||
Ret (raw_type::*getter)() const ) | Ret (raw_type::*getter)() const ) | |||
{ | { | |||
return member(field, to_getter(getter), setter_t()); | return member(field, to_getter(getter), setter_t()); | |||
} | } | |||
Ghost& member( const std::string& field, | ||||
naRef (*getter)(const raw_type&, naContext) ) | ||||
{ | ||||
return member(field, getter_t(getter), setter_t()); | ||||
} | ||||
Ghost& member( const std::string& field, | ||||
naRef (*getter)(raw_type&, naContext) ) | ||||
{ | ||||
return member(field, getter_t(getter), setter_t()); | ||||
} | ||||
/** | /** | |||
* Register a write only member variable. | * Register a write only member variable. | |||
* | * | |||
* @param field Name of member | * @param field Name of member | |||
* @param setter Setter for variable | * @param setter Setter for variable | |||
*/ | */ | |||
template<class Var> | template<class Var> | |||
Ghost& member( const std::string& field, | Ghost& member( const std::string& field, | |||
void (raw_type::*setter)(Var) ) | void (raw_type::*setter)(Var) ) | |||
{ | { | |||
return member(field, getter_t(), to_setter(setter)); | return member(field, getter_t(), to_setter(setter)); | |||
} | } | |||
Ghost& member( const std::string& field, | ||||
void (*setter)(raw_type&, naContext, naRef) ) | ||||
{ | ||||
return member(field, getter_t(), setter_t(setter)); | ||||
} | ||||
Ghost& member( const std::string& field, | ||||
const setter_t& setter ) | ||||
{ | ||||
return member(field, getter_t(), setter); | ||||
} | ||||
/** | /** | |||
* Register a member variable by passing a getter and/or setter metho d. | * Register a member variable by passing a getter and/or setter metho d. | |||
* | * | |||
* @param field Name of member | * @param field Name of member | |||
* @param getter Getter for variable | * @param getter Getter for variable | |||
* @param setter Setter for variable (Pass empty to prevent write ac cess) | * @param setter Setter for variable (Pass empty to prevent write ac cess) | |||
* | * | |||
*/ | */ | |||
Ghost& member( const std::string& field, | Ghost& member( const std::string& field, | |||
const getter_t& getter, | const getter_t& getter, | |||
skipping to change at line 477 | skipping to change at line 600 | |||
SG_LOG | SG_LOG | |||
( | ( | |||
SG_NASAL, | SG_NASAL, | |||
SG_WARN, | SG_WARN, | |||
"Member '" << field << "' requires a getter or setter" | "Member '" << field << "' requires a getter or setter" | |||
); | ); | |||
return *this; | return *this; | |||
} | } | |||
/** | /** | |||
* Register a function which is called upon retrieving an unknown mem | ||||
ber | ||||
* of this ghost. | ||||
*/ | ||||
Ghost& _get(const fallback_getter_t& getter) | ||||
{ | ||||
_fallback_getter = getter; | ||||
return *this; | ||||
} | ||||
/** | ||||
* Register a function which is called upon retrieving an unknown mem | ||||
ber | ||||
* of this ghost, and convert it to the given @a Param type. | ||||
*/ | ||||
template<class Param> | ||||
Ghost& _get( const boost::function<bool ( raw_type&, | ||||
const std::string&, | ||||
Param& )>& getter ) | ||||
{ | ||||
return _get(boost::bind( | ||||
convert_param_invoker<Param>, getter, _1, _2, _3, _4 | ||||
)); | ||||
} | ||||
/** | ||||
* Register a method which is called upon retrieving an unknown membe | ||||
r of | ||||
* this ghost. | ||||
* | ||||
* @code{cpp} | ||||
* class MyClass | ||||
* { | ||||
* public: | ||||
* bool getMember( const std::string& key, | ||||
* std::string& value_out ) const; | ||||
* } | ||||
* | ||||
* Ghost<MyClassPtr>::init("Test") | ||||
* ._get(&MyClass::getMember); | ||||
* @endcode | ||||
*/ | ||||
template<class Param> | ||||
Ghost& _get(bool (raw_type::*getter)(const std::string&, Param&) cons | ||||
t) | ||||
{ | ||||
return _get( | ||||
boost::function<bool (raw_type&, const std::string&, Param&)>(get | ||||
ter) | ||||
); | ||||
} | ||||
/** | ||||
* Register a method which is called upon retrieving an unknown membe | ||||
r of | ||||
* this ghost. | ||||
* | ||||
* @code{cpp} | ||||
* class MyClass | ||||
* { | ||||
* public: | ||||
* bool getMember( naContext c, | ||||
* const std::string& key, | ||||
* naRef& value_out ); | ||||
* } | ||||
* | ||||
* Ghost<MyClassPtr>::init("Test") | ||||
* ._get(&MyClass::getMember); | ||||
* @endcode | ||||
*/ | ||||
Ghost& _get(bool (raw_type::*getter)( naContext, | ||||
const std::string&, | ||||
naRef& ) const) | ||||
{ | ||||
return _get( fallback_getter_t(getter) ); | ||||
} | ||||
/** | ||||
* Register a function which is called upon setting an unknown member | ||||
of | ||||
* this ghost. | ||||
*/ | ||||
Ghost& _set(const fallback_setter_t& setter) | ||||
{ | ||||
_fallback_setter = setter; | ||||
return *this; | ||||
} | ||||
/** | ||||
* Register a function which is called upon setting an unknown member | ||||
of | ||||
* this ghost, and convert it to the given @a Param type. | ||||
*/ | ||||
template<class Param> | ||||
Ghost& _set(const boost::function<bool ( raw_type&, | ||||
const std::string&, | ||||
Param )>& setter) | ||||
{ | ||||
// Setter signature: bool( raw_type&, | ||||
// naContext, | ||||
// const std::string&, | ||||
// naRef ) | ||||
return _set(boost::bind( | ||||
setter, | ||||
_1, | ||||
_3, | ||||
boost::bind(from_nasal_ptr<Param>::get(), _2, _4) | ||||
)); | ||||
} | ||||
/** | ||||
* Register a method which is called upon setting an unknown member o | ||||
f | ||||
* this ghost. | ||||
* | ||||
* @code{cpp} | ||||
* class MyClass | ||||
* { | ||||
* public: | ||||
* bool setMember( const std::string& key, | ||||
* const std::string& value ); | ||||
* } | ||||
* | ||||
* Ghost<MyClassPtr>::init("Test") | ||||
* ._set(&MyClass::setMember); | ||||
* @endcode | ||||
*/ | ||||
template<class Param> | ||||
Ghost& _set(bool (raw_type::*setter)(const std::string&, Param)) | ||||
{ | ||||
return _set( | ||||
boost::function<bool (raw_type&, const std::string&, Param)>(sett | ||||
er) | ||||
); | ||||
} | ||||
/** | ||||
* Register a method which is called upon setting an unknown member o | ||||
f | ||||
* this ghost. | ||||
* | ||||
* @code{cpp} | ||||
* class MyClass | ||||
* { | ||||
* public: | ||||
* bool setMember( naContext c, | ||||
* const std::string& key, | ||||
* naRef value ); | ||||
* } | ||||
* | ||||
* Ghost<MyClassPtr>::init("Test") | ||||
* ._set(&MyClass::setMember); | ||||
* @endcode | ||||
*/ | ||||
Ghost& _set(bool (raw_type::*setter)( naContext, | ||||
const std::string&, | ||||
naRef )) | ||||
{ | ||||
return _set( fallback_setter_t(setter) ); | ||||
} | ||||
/** | ||||
* Register anything that accepts an object instance and a | * Register anything that accepts an object instance and a | |||
* nasal::CallContext and returns naRef as method. | * nasal::CallContext and returns naRef as method. | |||
* | * | |||
* @code{cpp} | * @code{cpp} | |||
* class MyClass | * class MyClass | |||
* { | * { | |||
* public: | * public: | |||
* naRef myMethod(const nasal::CallContext& ctx); | * naRef myMethod(const nasal::CallContext& ctx); | |||
* } | * } | |||
* | * | |||
* Ghost<MyClassPtr>::init("Test") | * Ghost<MyClassPtr>::init("Test") | |||
* .method("myMethod", &MyClass::myMethod); | * .method("myMethod", &MyClass::myMethod); | |||
* @endcode | * @endcode | |||
*/ | */ | |||
Ghost& method(const std::string& name, const method_t& func) | Ghost& method(const std::string& name, const method_t& func) | |||
{ | { | |||
_members[name].func.reset( new MethodHolder(func) ); | _members[name].func = new MethodHolder(func); | |||
return *this; | return *this; | |||
} | } | |||
/** | /** | |||
* Register anything that accepts an object instance and a | * Register anything that accepts an object instance and a | |||
* nasal::CallContext whith automatic conversion of the return type t o | * nasal::CallContext whith automatic conversion of the return type t o | |||
* Nasal. | * Nasal. | |||
* | * | |||
* @code{cpp} | * @code{cpp} | |||
* class MyClass; | * class MyClass; | |||
skipping to change at line 520 | skipping to change at line 794 | |||
template<class Ret> | template<class Ret> | |||
Ghost& method | Ghost& method | |||
( | ( | |||
const std::string& name, | const std::string& name, | |||
const boost::function<Ret (raw_type&, const CallContext&)>& func | const boost::function<Ret (raw_type&, const CallContext&)>& func | |||
) | ) | |||
{ | { | |||
return method(name, boost::bind(method_invoker<Ret>, func, _1, _2)) ; | return method(name, boost::bind(method_invoker<Ret>, func, _1, _2)) ; | |||
} | } | |||
// Build dependency for CMake, gcc, etc. | ||||
#define SG_DONT_DO_ANYTHING | ||||
# include <simgear/nasal/cppbind/detail/functor_templates.hxx> | ||||
#undef SG_DONT_DO_ANYTHING | ||||
#define BOOST_PP_ITERATION_LIMITS (0, 9) | #define BOOST_PP_ITERATION_LIMITS (0, 9) | |||
#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/functor_templates .hxx> | #define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/functor_templates .hxx> | |||
#include BOOST_PP_ITERATE() | #include BOOST_PP_ITERATE() | |||
// TODO use variadic template when supporting C++11 | ||||
// TODO check if default constructor exists | ||||
// static naRef create( naContext c ) | ||||
// { | ||||
// return makeGhost(c, createInstance()); | ||||
// } | ||||
/** | /** | |||
* Create a Nasal instance of this ghost. | * Create a shared pointer on the heap to handle the reference counti | |||
* | ng | |||
* @param c Active Nasal context | * for the passed shared pointer while it is used in Nasal space. | |||
* @param a1 Parameter used for creating new instance | ||||
*/ | ||||
template<class A1> | ||||
static naRef create( naContext c, const A1& a1 ) | ||||
{ | ||||
return makeGhost(c, createInstance(a1)); | ||||
} | ||||
/** | ||||
* Nasal callback for creating a new instance of this ghost. | ||||
*/ | */ | |||
static naRef f_create(naContext c, naRef me, int argc, naRef* args) | template<class RefType> | |||
{ | static | |||
return create(c); | typename boost::enable_if_c< | |||
} | boost::is_same<RefType, strong_ref>::value | |||
|| boost::is_same<RefType, weak_ref>::value, | ||||
static bool isBaseOf(naGhostType* ghost_type) | naRef | |||
{ | >::type | |||
if( !ghost_type ) | makeGhost(naContext c, RefType const& ref_ptr) | |||
return false; | ||||
return getSingletonPtr()->GhostMetadata::isBaseOf(ghost_type); | ||||
} | ||||
static bool isBaseOf(naRef obj) | ||||
{ | { | |||
return isBaseOf( naGhost_type(obj) ); | strong_ref ref(ref_ptr); | |||
raw_type* ptr = get_pointer(ref); | ||||
if( !ptr ) | ||||
return naNil(); | ||||
// We are wrapping shared pointers to already existing objects whic | ||||
h | ||||
// will then be hold be a new shared pointer. We therefore have to | ||||
// check for the dynamic type of the object as it might differ from | ||||
// the passed static type. | ||||
return toNasal<Ghost>( | ||||
c, | ||||
ref, | ||||
shared_ptr_traits<RefType>::is_strong::value | ||||
); | ||||
} | } | |||
/** | /** | |||
* Convert Nasal object to C++ object. To get a valid object the pass ed | * Convert Nasal object to C++ object. To get a valid object the pass ed | |||
* Nasal objects has to be derived class of the target class (Either | * Nasal objects has to be derived class of the target class (Either | |||
* derived in C++ or in Nasal using a 'parents' vector) | * derived in C++ or in Nasal using a 'parents' vector) | |||
*/ | */ | |||
static pointer fromNasal(naContext c, naRef me) | static strong_ref fromNasal(naContext c, naRef me) | |||
{ | { | |||
// Check if it's a ghost and if it can be converted | naGhostType* ghost_type = naGhost_type(me); | |||
if( isBaseOf( naGhost_type(me) ) ) | if( ghost_type ) | |||
return getPtr( naGhost_ptr(me) ); | { | |||
// Check if we got an instance of this class | ||||
bool is_weak = false; | ||||
if( isInstance(ghost_type, is_weak) ) | ||||
{ | ||||
return is_weak ? getPtr<strong_ref, true>(naGhost_ptr(me)) | ||||
: getPtr<strong_ref, false>(naGhost_ptr(me)); | ||||
} | ||||
// Now if it is derived from a ghost (hash with ghost in parent vec | // otherwise try the derived classes | |||
tor) | for( typename DerivedList::reverse_iterator | |||
derived = getSingletonPtr()->_derived_types.rbegin(); | ||||
derived != getSingletonPtr()->_derived_types.rend(); | ||||
++derived ) | ||||
{ | ||||
strong_ref ref = (derived->from_nasal)(c, me); | ||||
if( get_pointer(ref) ) | ||||
return ref; | ||||
} | ||||
} | ||||
else if( naIsHash(me) ) | else if( naIsHash(me) ) | |||
{ | { | |||
naRef na_parents = naHash_cget(me, const_cast<char*>("parents")); | naRef na_parents = naHash_cget(me, const_cast<char*>("parents")); | |||
if( !naIsVector(na_parents) ) | if( !naIsVector(na_parents) ) | |||
{ | return strong_ref(); | |||
SG_LOG(SG_NASAL, SG_DEBUG, "Missing 'parents' vector for ghost" | ||||
); | ||||
return pointer(); | ||||
} | ||||
typedef std::vector<naRef> naRefs; | typedef std::vector<naRef> naRefs; | |||
naRefs parents = from_nasal<naRefs>(c, na_parents); | naRefs parents = from_nasal<naRefs>(c, na_parents); | |||
for( naRefs::const_iterator parent = parents.begin(); | for( naRefs::const_iterator parent = parents.begin(); | |||
parent != parents.end(); | parent != parents.end(); | |||
++parent ) | ++parent ) | |||
{ | { | |||
pointer ptr = fromNasal(c, *parent); | strong_ref ref = fromNasal(c, *parent); | |||
if( get_pointer(ptr) ) | if( get_pointer(ref) ) | |||
return ptr; | return ref; | |||
} | } | |||
} | } | |||
return pointer(); | return strong_ref(); | |||
} | } | |||
private: | private: | |||
template<class> | template<class, class> | |||
friend class Ghost; | friend class Ghost; | |||
static naGhostType _ghost_type; | static naGhostType _ghost_type_strong, //!< Stored as shared pointer | |||
_ghost_type_weak; //!< Stored as weak shared poi | ||||
nter | ||||
typedef naGhostType* (*type_checker_t)(const raw_type*); | typedef naRef (*to_nasal_t)(naContext, const strong_ref&, bool); | |||
typedef std::vector<type_checker_t> DerivedList; | typedef strong_ref (*from_nasal_t)(naContext, naRef); | |||
struct DerivedInfo | ||||
{ | ||||
to_nasal_t to_nasal; | ||||
from_nasal_t from_nasal; | ||||
DerivedInfo( to_nasal_t to_nasal_func, | ||||
from_nasal_t from_nasal_func ): | ||||
to_nasal(to_nasal_func), | ||||
from_nasal(from_nasal_func) | ||||
{} | ||||
}; | ||||
typedef std::vector<DerivedInfo> DerivedList; | ||||
DerivedList _derived_types; | DerivedList _derived_types; | |||
/** | static bool isInstance(naGhostType* ghost_type, bool& is_weak) | |||
* Create a shared pointer on the heap to handle the reference counti | ||||
ng | ||||
* for the passed shared pointer while it is used in Nasal space. | ||||
*/ | ||||
static pointer* createInstance(const pointer& ptr) | ||||
{ | { | |||
return get_pointer(ptr) ? new pointer(ptr) : 0; | if( !ghost_type || !getSingletonPtr() ) | |||
return false; | ||||
return getSingletonPtr()->GhostMetadata::isInstance( ghost_type, | ||||
is_weak ); | ||||
} | } | |||
static pointer getPtr(void* ptr) | template<class RefPtr, bool is_weak> | |||
static | ||||
typename boost::enable_if_c< | ||||
!is_weak, | ||||
RefPtr | ||||
>::type | ||||
getPtr(void* ptr) | ||||
{ | { | |||
typedef shared_ptr_storage<strong_ref> storage_type; | ||||
if( ptr ) | if( ptr ) | |||
return *static_cast<pointer*>(ptr); | return storage_type::template get<RefPtr>( | |||
static_cast<typename storage_type::storage_type*>(ptr) | ||||
); | ||||
else | else | |||
return pointer(); | return RefPtr(); | |||
} | } | |||
static raw_type* getRawPtr(void* ptr) | template<class RefPtr, bool is_weak> | |||
static | ||||
typename boost::enable_if_c< | ||||
is_weak && supports_weak_ref<T>::value, | ||||
RefPtr | ||||
>::type | ||||
getPtr(void* ptr) | ||||
{ | { | |||
typedef shared_ptr_storage<weak_ref> storage_type; | ||||
if( ptr ) | if( ptr ) | |||
return get_pointer(*static_cast<pointer*>(ptr)); | return storage_type::template get<RefPtr>( | |||
static_cast<typename storage_type::storage_type*>(ptr) | ||||
); | ||||
else | else | |||
return 0; | return RefPtr(); | |||
} | } | |||
static raw_type* getRawPtr(const pointer& ptr) | template<class RefPtr, bool is_weak> | |||
static | ||||
typename boost::enable_if_c< | ||||
is_weak && !supports_weak_ref<T>::value, | ||||
RefPtr | ||||
>::type | ||||
getPtr(void* ptr) | ||||
{ | { | |||
return get_pointer(ptr); | return RefPtr(); | |||
} | } | |||
void addDerived( const internal::GhostMetadata* derived_meta, | void addDerived( const internal::GhostMetadata* derived_meta, | |||
const type_checker_t& derived_info ) | to_nasal_t to_nasal_func, | |||
from_nasal_t from_nasal_func ) | ||||
{ | { | |||
GhostMetadata::addDerived(derived_meta); | GhostMetadata::addDerived(derived_meta); | |||
_derived_types.push_back(derived_info); | _derived_types.push_back(DerivedInfo(to_nasal_func, from_nasal_func )); | |||
} | } | |||
template<class BaseGhost> | template<class BaseGhost> | |||
static | static | |||
typename boost::enable_if | typename boost::enable_if | |||
< boost::is_polymorphic<typename BaseGhost::raw_type>, | < boost::is_polymorphic<typename BaseGhost::raw_type>, | |||
naGhostType* | naRef | |||
>::type | >::type | |||
getTypeFor(const typename BaseGhost::raw_type* base) | toNasal( naContext c, | |||
const typename BaseGhost::strong_ref& base_ref, | ||||
bool strong ) | ||||
{ | { | |||
typename BaseGhost::raw_type* ptr = get_pointer(base_ref); | ||||
// Check first if passed pointer can by converted to instance of cl ass | // Check first if passed pointer can by converted to instance of cl ass | |||
// this ghost wraps. | // this ghost wraps. | |||
if( !boost::is_same | if( !boost::is_same | |||
< typename BaseGhost::raw_type, | < typename BaseGhost::raw_type, | |||
typename Ghost::raw_type | typename Ghost::raw_type | |||
>::value | >::value | |||
&& dynamic_cast<const typename Ghost::raw_type*>(base) != base | && dynamic_cast<const typename Ghost::raw_type*>(ptr) != ptr ) | |||
) | return naNil(); | |||
return 0; | ||||
if( !getSingletonPtr() ) | ||||
{ | ||||
SG_LOG | ||||
( | ||||
SG_NASAL, | ||||
SG_INFO, | ||||
"Ghost::getTypeFor: can not get type for unregistered ghost" | ||||
); | ||||
return naNil(); | ||||
} | ||||
strong_ref ref = | ||||
static_pointer_cast<typename Ghost::raw_type>(base_ref); | ||||
// Now check if we can further downcast to one of our derived class es. | // Now check if we can further downcast to one of our derived class es. | |||
for( typename DerivedList::reverse_iterator | for( typename DerivedList::reverse_iterator | |||
derived = getSingletonPtr()->_derived_types.rbegin(); | derived = getSingletonPtr()->_derived_types.rbegin(); | |||
derived != getSingletonPtr()->_derived_types.rend(); | derived != getSingletonPtr()->_derived_types.rend(); | |||
++derived ) | ++derived ) | |||
{ | { | |||
naGhostType* ghost_type = | naRef ghost = (derived->to_nasal)(c, ref, strong); | |||
(*derived)( static_cast<const typename Ghost::raw_type*>(base) | ||||
); | if( !naIsNil(ghost) ) | |||
if( ghost_type ) | return ghost; | |||
return ghost_type; | ||||
} | } | |||
// If base is not an instance of any derived class, this class has to | // If base is not an instance of any derived class, this class has to | |||
// be the dynamic type. | // be the dynamic type. | |||
return &_ghost_type; | return strong | |||
? create<false>(c, ref) | ||||
: create<true>(c, ref); | ||||
} | } | |||
template<class BaseGhost> | template<class BaseGhost> | |||
static | static | |||
typename boost::disable_if | typename boost::disable_if | |||
< boost::is_polymorphic<typename BaseGhost::raw_type>, | < boost::is_polymorphic<typename BaseGhost::raw_type>, | |||
naGhostType* | naRef | |||
>::type | >::type | |||
getTypeFor(const typename BaseGhost::raw_type* base) | toNasal( naContext c, | |||
const typename BaseGhost::strong_ref& ref, | ||||
bool strong ) | ||||
{ | { | |||
// For non polymorphic classes there is no possibility to get the a ctual | // For non polymorphic classes there is no possibility to get the a ctual | |||
// dynamic type, therefore we can only use its static type. | // dynamic type, therefore we can only use its static type. | |||
return &BaseGhost::_ghost_type; | return strong | |||
? create<false>(c, ref) | ||||
: create<true>(c, ref); | ||||
} | } | |||
static Ghost* getSingletonPtr() | template<class Type> | |||
static Type fromNasalWithCast(naContext c, naRef me) | ||||
{ | { | |||
return getSingletonHolder().get(); | return Type(fromNasal(c, me)); | |||
} | } | |||
static raw_type& requireObject(naContext c, naRef me) | static Ghost* getSingletonPtr() | |||
{ | { | |||
raw_type* obj = getRawPtr( fromNasal(c, me) ); | return getSingletonHolder().get(); | |||
naGhostType* ghost_type = naGhost_type(me); | ||||
if( !obj ) | ||||
naRuntimeError | ||||
( | ||||
c, | ||||
"method called on object of wrong type: is '%s' expected '%s'", | ||||
ghost_type ? ghost_type->name : "unknown", | ||||
_ghost_type.name | ||||
); | ||||
return *obj; | ||||
} | } | |||
template<class Ret> | template<class Ret> | |||
getter_t to_getter(Ret (raw_type::*getter)() const) | getter_t to_getter(Ret (raw_type::*getter)() const) | |||
{ | { | |||
typedef typename boost::call_traits<Ret>::param_type param_type; | typedef typename boost::call_traits<Ret>::param_type param_type; | |||
naRef(*to_nasal_)(naContext, param_type) = &to_nasal; | naRef(*to_nasal_)(naContext, param_type) = &to_nasal; | |||
// Getter signature: naRef(naContext, raw_type&) | // Getter signature: naRef(raw_type&, naContext) | |||
return boost::bind | return boost::bind | |||
( | ( | |||
to_nasal_, | to_nasal_, | |||
_1, | _2, | |||
boost::bind(getter, _2) | boost::bind(getter, _1) | |||
); | ); | |||
} | } | |||
template<class Param> | template<class Param> | |||
setter_t to_setter(void (raw_type::*setter)(Param)) | setter_t to_setter(void (raw_type::*setter)(Param)) | |||
{ | { | |||
// Setter signature: void(naContext, raw_type&, naRef) | // Setter signature: void(raw_type&, naContext, naRef) | |||
return boost::bind | return boost::bind | |||
( | ( | |||
setter, | setter, | |||
_2, | _1, | |||
boost::bind(from_nasal_ptr<Param>::get(), _1, _3) | boost::bind(from_nasal_ptr<Param>::get(), _2, _3) | |||
); | ); | |||
} | } | |||
/** | /** | |||
* Invoke a method which writes the converted parameter to a referenc | ||||
e | ||||
*/ | ||||
template<class Param> | ||||
static | ||||
bool convert_param_invoker | ||||
( | ||||
const boost::function<bool ( raw_type&, | ||||
const std::string&, | ||||
Param& )>& func, | ||||
raw_type& obj, | ||||
naContext c, | ||||
const std::string& key, | ||||
naRef& out | ||||
) | ||||
{ | ||||
Param p; | ||||
if( !func(obj, key, p) ) | ||||
return false; | ||||
out = to_nasal(c, p); | ||||
return true; | ||||
}; | ||||
/** | ||||
* Invoke a method which returns a value and convert it to Nasal. | * Invoke a method which returns a value and convert it to Nasal. | |||
*/ | */ | |||
template<class Ret> | template<class Ret> | |||
static | static | |||
typename boost::disable_if<boost::is_void<Ret>, naRef>::type | typename boost::disable_if<boost::is_void<Ret>, naRef>::type | |||
method_invoker | method_invoker | |||
( | ( | |||
const boost::function<Ret (raw_type&, const CallContext&)>& func, | const boost::function<Ret (raw_type&, const CallContext&)>& func, | |||
raw_type& obj, | raw_type& obj, | |||
const CallContext& ctx | const CallContext& ctx | |||
skipping to change at line 810 | skipping to change at line 1169 | |||
>::type | >::type | |||
arg_from_nasal(const CallContext& ctx, size_t) | arg_from_nasal(const CallContext& ctx, size_t) | |||
{ | { | |||
// Either const CallContext& or CallContext, non-const reference | // Either const CallContext& or CallContext, non-const reference | |||
// does not make sense. | // does not make sense. | |||
BOOST_STATIC_ASSERT( (!boost::is_same<Arg, CallContext&>::value) ); | BOOST_STATIC_ASSERT( (!boost::is_same<Arg, CallContext&>::value) ); | |||
return ctx; | return ctx; | |||
}; | }; | |||
typedef std::auto_ptr<Ghost> GhostPtr; | typedef std::auto_ptr<Ghost> GhostPtr; | |||
MemberMap _members; | MemberMap _members; | |||
fallback_getter_t _fallback_getter; | ||||
fallback_setter_t _fallback_setter; | ||||
explicit Ghost(const std::string& name): | explicit Ghost(const std::string& name): | |||
GhostMetadata(name, &_ghost_type) | GhostMetadata( name, | |||
{ | &_ghost_type_strong, | |||
_ghost_type.destroy = &destroyGhost; | supports_weak_ref<T>::value ? &_ghost_type_weak : NU | |||
_ghost_type.name = _name.c_str(); | LL ) | |||
_ghost_type.get_member = &getMember; | { | |||
_ghost_type.set_member = &setMember; | _ghost_type_strong.destroy = | |||
SG_GET_TEMPLATE_MEMBER(Ghost, queueDestroy<strong_ref>); | ||||
_ghost_type_strong.name = _name_strong.c_str(); | ||||
_ghost_type_strong.get_member = &Ghost::getMemberStrong; | ||||
_ghost_type_strong.set_member = &Ghost::setMemberStrong; | ||||
_ghost_type_weak.destroy = | ||||
SG_GET_TEMPLATE_MEMBER(Ghost, queueDestroy<weak_ref>); | ||||
_ghost_type_weak.name = _name_weak.c_str(); | ||||
if( supports_weak_ref<T>::value ) | ||||
{ | ||||
_ghost_type_weak.get_member = &Ghost::getMemberWeak; | ||||
_ghost_type_weak.set_member = &Ghost::setMemberWeak; | ||||
} | ||||
else | ||||
{ | ||||
_ghost_type_weak.get_member = 0; | ||||
_ghost_type_weak.set_member = 0; | ||||
} | ||||
} | } | |||
static GhostPtr& getSingletonHolder() | static GhostPtr& getSingletonHolder() | |||
{ | { | |||
static GhostPtr instance; | static GhostPtr instance; | |||
return instance; | return instance; | |||
} | } | |||
static naRef makeGhost(naContext c, void *ptr) | template<bool is_weak> | |||
static | ||||
typename boost::enable_if_c< | ||||
!is_weak, | ||||
naRef | ||||
>::type | ||||
create(naContext c, const strong_ref& ref_ptr) | ||||
{ | { | |||
if( getRawPtr(ptr) ) | typedef shared_ptr_storage<strong_ref> storage_type; | |||
{ | return naNewGhost2( c, | |||
// We are wrapping shared pointers to already existing objects wh | &Ghost::_ghost_type_strong, | |||
ich | storage_type::ref(ref_ptr) ); | |||
// will then be hold be a new shared pointer. We therefore have t | } | |||
o | ||||
// check for the dynamic type of the object as it might differ fr | ||||
om | ||||
// the passed static type. | ||||
naGhostType* ghost_type = getTypeFor<Ghost>( getRawPtr(ptr) ); | ||||
if( ghost_type ) | template<bool is_weak> | |||
return naNewGhost2(c, ghost_type, ptr); | static | |||
} | typename boost::enable_if_c< | |||
is_weak && supports_weak_ref<T>::value, | ||||
naRef | ||||
>::type | ||||
create(naContext c, const strong_ref& ref_ptr) | ||||
{ | ||||
typedef shared_ptr_storage<weak_ref> storage_type; | ||||
return naNewGhost2( c, | ||||
&Ghost::_ghost_type_weak, | ||||
storage_type::ref(ref_ptr) ); | ||||
} | ||||
destroyGhost(ptr); | template<bool is_weak> | |||
static | ||||
typename boost::enable_if_c< | ||||
is_weak && !supports_weak_ref<T>::value, | ||||
naRef | ||||
>::type | ||||
create(naContext, const strong_ref&) | ||||
{ | ||||
return naNil(); | return naNil(); | |||
} | } | |||
static void destroyGhost(void *ptr) | template<class Type> | |||
static void destroy(void *ptr) | ||||
{ | ||||
typedef shared_ptr_storage<Type> storage_type; | ||||
storage_type::unref( | ||||
static_cast<typename storage_type::storage_type*>(ptr) | ||||
); | ||||
} | ||||
template<class Type> | ||||
static void queueDestroy(void *ptr) | ||||
{ | ||||
_destroy_list.push_back( DestroyList::value_type(&destroy<Type>, pt | ||||
r) ); | ||||
} | ||||
static void raiseErrorExpired(naContext c, const char* str) | ||||
{ | { | |||
delete static_cast<pointer*>(ptr); | Ghost* ghost_info = getSingletonPtr(); | |||
naRuntimeError( | ||||
c, | ||||
"Ghost::%s: ghost has expired '%s'", | ||||
str, | ||||
ghost_info ? ghost_info->_name_strong.c_str() : "unknown" | ||||
); | ||||
} | } | |||
/** | /** | |||
* Callback for retrieving a ghost member. | * Callback for retrieving a ghost member. | |||
*/ | */ | |||
static const char* getMember(naContext c, void* g, naRef key, naRef* | static const char* getMemberImpl( naContext c, | |||
out) | raw_type& obj, | |||
naRef key, | ||||
naRef* out ) | ||||
{ | { | |||
const std::string key_str = nasal::from_nasal<std::string>(c, key); | const std::string key_str = nasal::from_nasal<std::string>(c, key); | |||
if( key_str == "parents" ) | // TODO merge instance parents with static class parents | |||
{ | // if( key_str == "parents" ) | |||
if( getSingletonPtr()->_parents.empty() ) | // { | |||
return 0; | // if( getSingletonPtr()->_parents.empty() ) | |||
// return 0; | ||||
*out = getSingletonPtr()->getParents(c); | // | |||
return ""; | // *out = getSingletonPtr()->getParents(c); | |||
} | // return ""; | |||
// } | ||||
typename MemberMap::iterator member = | typename MemberMap::iterator member = | |||
getSingletonPtr()->_members.find(key_str); | getSingletonPtr()->_members.find(key_str); | |||
if( member == getSingletonPtr()->_members.end() ) | if( member == getSingletonPtr()->_members.end() ) | |||
return 0; | { | |||
fallback_getter_t fallback_get = getSingletonPtr()->_fallback_get | ||||
if( member->second.func ) | ter; | |||
if( !fallback_get | ||||
|| !fallback_get(obj, c, key_str, *out) ) | ||||
return 0; | ||||
} | ||||
else if( member->second.func ) | ||||
*out = member->second.func->get_naRef(c); | *out = member->second.func->get_naRef(c); | |||
else if( !member->second.getter.empty() ) | else if( !member->second.getter.empty() ) | |||
*out = member->second.getter(c, *getRawPtr(g)); | *out = member->second.getter(obj, c); | |||
else | else | |||
return "Read-protected member"; | return "Read-protected member"; | |||
return ""; | return ""; | |||
} | } | |||
static const char* | ||||
getMemberWeak(naContext c, void* ghost, naRef key, naRef* out) | ||||
{ | ||||
// Keep a strong reference while retrieving member, to prevent dele | ||||
ting | ||||
// object in between. | ||||
strong_ref ref = getPtr<strong_ref, true>(ghost); | ||||
if( !ref ) | ||||
raiseErrorExpired(c, "getMember"); | ||||
return getMemberImpl(c, *get_pointer(ref), key, out); | ||||
} | ||||
static const char* | ||||
getMemberStrong(naContext c, void* ghost, naRef key, naRef* out) | ||||
{ | ||||
// Just get a raw pointer as we are keeping a strong reference as g | ||||
host | ||||
// anyhow. | ||||
raw_type* ptr = getPtr<raw_type*, false>(ghost); | ||||
return getMemberImpl(c, *ptr, key, out); | ||||
} | ||||
/** | /** | |||
* Callback for writing to a ghost member. | * Callback for writing to a ghost member. | |||
*/ | */ | |||
static void setMember(naContext c, void* g, naRef field, naRef val) | static void setMemberImpl( naContext c, | |||
raw_type& obj, | ||||
naRef field, | ||||
naRef val ) | ||||
{ | { | |||
const std::string key = nasal::from_nasal<std::string>(c, field); | const std::string key = nasal::from_nasal<std::string>(c, field); | |||
typename MemberMap::iterator member = | const MemberMap& members = getSingletonPtr()->_members; | |||
getSingletonPtr()->_members.find(key); | ||||
if( member == getSingletonPtr()->_members.end() ) | typename MemberMap::const_iterator member = members.find(key); | |||
naRuntimeError(c, "ghost: No such member: %s", key.c_str()); | if( member == members.end() ) | |||
{ | ||||
fallback_setter_t fallback_set = getSingletonPtr()->_fallback_set | ||||
ter; | ||||
if( !fallback_set ) | ||||
naRuntimeError(c, "ghost: No such member: %s", key.c_str()); | ||||
else if( !fallback_set(obj, c, key, val) ) | ||||
naRuntimeError(c, "ghost: Failed to write (_set: %s)", key.c_st | ||||
r()); | ||||
} | ||||
else if( member->second.setter.empty() ) | else if( member->second.setter.empty() ) | |||
naRuntimeError(c, "ghost: Write protected member: %s", key.c_str( )); | naRuntimeError(c, "ghost: Write protected member: %s", key.c_str( )); | |||
else if( member->second.func ) | else if( member->second.func ) | |||
naRuntimeError(c, "ghost: Write to function: %s", key.c_str()); | naRuntimeError(c, "ghost: Write to function: %s", key.c_str()); | |||
else | ||||
member->second.setter(obj, c, val); | ||||
} | ||||
static void | ||||
setMemberWeak(naContext c, void* ghost, naRef field, naRef val) | ||||
{ | ||||
// Keep a strong reference while retrieving member, to prevent dele | ||||
ting | ||||
// object in between. | ||||
strong_ref ref = getPtr<strong_ref, true>(ghost); | ||||
if( !ref ) | ||||
raiseErrorExpired(c, "setMember"); | ||||
member->second.setter(c, *getRawPtr(g), val); | setMemberImpl(c, *get_pointer(ref), field, val); | |||
} | ||||
static void | ||||
setMemberStrong(naContext c, void* ghost, naRef field, naRef val) | ||||
{ | ||||
// Just get a raw pointer as we are keeping a strong reference as g | ||||
host | ||||
// anyhow. | ||||
raw_type* ptr = getPtr<raw_type*, false>(ghost); | ||||
setMemberImpl(c, *ptr, field, val); | ||||
} | } | |||
}; | }; | |||
template<class T> | template<class T> | |||
naGhostType Ghost<T>::_ghost_type; | naGhostType | |||
Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type> | ||||
::_ghost_type_strong; | ||||
template<class T> | ||||
naGhostType | ||||
Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type> | ||||
::_ghost_type_weak; | ||||
} // namespace nasal | } // namespace nasal | |||
// Needs to be outside any namespace to make ADL work | // Needs to be outside any namespace to make ADL work | |||
/** | /** | |||
* Convert every shared pointer to a ghost. | * Convert every shared pointer to a ghost. | |||
*/ | */ | |||
template<class T> | template<class T> | |||
typename boost::enable_if< | typename boost::enable_if< | |||
nasal::internal::has_element_type< | nasal::internal::has_element_type< | |||
typename nasal::internal::reduced_type<T>::type | typename nasal::internal::reduced_type<T>::type | |||
>, | >, | |||
naRef | naRef | |||
>::type | >::type | |||
to_nasal_helper(naContext c, T ptr) | to_nasal_helper(naContext c, T ptr) | |||
{ | { | |||
return nasal::Ghost<T>::create(c, ptr); | typedef typename nasal::shared_ptr_traits<T>::strong_ref strong_ref; | |||
return nasal::Ghost<strong_ref>::makeGhost(c, ptr); | ||||
} | } | |||
/** | /** | |||
* Convert nasal ghosts/hashes to shared pointer (of a ghost). | * Convert nasal ghosts/hashes to shared pointer (of a ghost). | |||
*/ | */ | |||
template<class T> | template<class T> | |||
typename boost::enable_if< | typename boost::enable_if< | |||
nasal::internal::has_element_type< | nasal::internal::has_element_type< | |||
typename nasal::internal::reduced_type<T>::type | typename nasal::internal::reduced_type<T>::type | |||
>, | >, | |||
T | T | |||
>::type | >::type | |||
from_nasal_helper(naContext c, naRef ref, const T*) | from_nasal_helper(naContext c, naRef ref, const T*) | |||
{ | { | |||
return nasal::Ghost<T>::fromNasal(c, ref); | typedef typename nasal::shared_ptr_traits<T>::strong_ref strong_ref; | |||
return T(nasal::Ghost<strong_ref>::fromNasal(c, ref)); | ||||
} | } | |||
/** | /** | |||
* Convert any pointer to a SGReference based object to a ghost. | * Convert any pointer to a SGReferenced based object to a ghost. | |||
*/ | */ | |||
template<class T> | template<class T> | |||
typename boost::enable_if<boost::is_base_of<SGReferenced, T>, naRef>::type | typename boost::enable_if_c< | |||
boost::is_base_of<SGReferenced, T>::value | ||||
|| boost::is_base_of<SGWeakReferenced, T>::value, | ||||
naRef | ||||
>::type | ||||
to_nasal_helper(naContext c, T* ptr) | to_nasal_helper(naContext c, T* ptr) | |||
{ | { | |||
return nasal::Ghost<SGSharedPtr<T> >::create(c, SGSharedPtr<T>(ptr)); | return nasal::Ghost<SGSharedPtr<T> >::makeGhost(c, SGSharedPtr<T>(ptr)); | |||
} | } | |||
/** | /** | |||
* Convert nasal ghosts/hashes to pointer (of a SGReference based ghost). | * Convert nasal ghosts/hashes to pointer (of a SGReferenced based ghost). | |||
*/ | */ | |||
template<class T> | template<class T> | |||
typename boost::enable_if< | typename boost::enable_if_c< | |||
boost::is_base_of<SGReferenced, typename boost::remove_pointer<T>::type>, | boost::is_base_of< | |||
SGReferenced, | ||||
typename boost::remove_pointer<T>::type | ||||
>::value | ||||
|| boost::is_base_of< | ||||
SGWeakReferenced, | ||||
typename boost::remove_pointer<T>::type | ||||
>::value, | ||||
T | T | |||
>::type | >::type | |||
from_nasal_helper(naContext c, naRef ref, const T*) | from_nasal_helper(naContext c, naRef ref, const T*) | |||
{ | { | |||
typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef; | typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef; | |||
return nasal::Ghost<TypeRef>::fromNasal(c, ref).release(); | return T(nasal::Ghost<TypeRef>::fromNasal(c, ref)); | |||
} | ||||
/** | ||||
* Convert any pointer to a osg::Referenced based object to a ghost. | ||||
*/ | ||||
template<class T> | ||||
typename boost::enable_if< | ||||
boost::is_base_of<osg::Referenced, T>, | ||||
naRef | ||||
>::type | ||||
to_nasal_helper(naContext c, T* ptr) | ||||
{ | ||||
return nasal::Ghost<osg::ref_ptr<T> >::makeGhost(c, osg::ref_ptr<T>(ptr)) | ||||
; | ||||
} | ||||
/** | ||||
* Convert nasal ghosts/hashes to pointer (of a osg::Referenced based ghost | ||||
). | ||||
*/ | ||||
template<class T> | ||||
typename boost::enable_if< | ||||
boost::is_base_of<osg::Referenced, typename boost::remove_pointer<T>::typ | ||||
e>, | ||||
T | ||||
>::type | ||||
from_nasal_helper(naContext c, naRef ref, const T*) | ||||
{ | ||||
typedef osg::ref_ptr<typename boost::remove_pointer<T>::type> TypeRef; | ||||
return T(nasal::Ghost<TypeRef>::fromNasal(c, ref)); | ||||
} | } | |||
#endif /* SG_NASAL_GHOST_HXX_ */ | #endif /* SG_NASAL_GHOST_HXX_ */ | |||
End of changes. 106 change blocks. | ||||
245 lines changed or deleted | 792 lines changed or added | |||
HTTPRequest.hxx | HTTPRequest.hxx | |||
---|---|---|---|---|
#ifndef SG_HTTP_REQUEST_HXX | #ifndef SG_HTTP_REQUEST_HXX | |||
#define SG_HTTP_REQUEST_HXX | #define SG_HTTP_REQUEST_HXX | |||
#include <map> | #include <map> | |||
#include <simgear/structure/function_list.hxx> | ||||
#include <simgear/structure/map.hxx> | #include <simgear/structure/map.hxx> | |||
#include <simgear/structure/SGReferenced.hxx> | #include <simgear/structure/SGReferenced.hxx> | |||
#include <simgear/structure/SGSharedPtr.hxx> | #include <simgear/structure/SGSharedPtr.hxx> | |||
#include <simgear/math/sg_types.hxx> | #include <simgear/math/sg_types.hxx> | |||
#include <boost/function.hpp> | #include <boost/bind.hpp> | |||
class SGPropertyNode; | class SGPropertyNode; | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace HTTP | namespace HTTP | |||
{ | { | |||
class Request: | class Request: | |||
public SGReferenced | public SGReferenced | |||
skipping to change at line 49 | skipping to change at line 50 | |||
* | * | |||
*/ | */ | |||
StringMap& requestHeaders() { return _request_headers; } | StringMap& requestHeaders() { return _request_headers; } | |||
const StringMap& requestHeaders() const { return _request_headers; } | const StringMap& requestHeaders() const { return _request_headers; } | |||
std::string& requestHeader(const std::string& key) | std::string& requestHeader(const std::string& key) | |||
{ return _request_headers[key]; } | { return _request_headers[key]; } | |||
const std::string requestHeader(const std::string& key) const | const std::string requestHeader(const std::string& key) const | |||
{ return _request_headers.get(k ey); } | { return _request_headers.get(k ey); } | |||
/** | /** | |||
* Set the handler to be called when the request successfully completes . | * Add a handler to be called when the request successfully completes. | |||
* | * | |||
* @note If the request is already complete, the handler is called | * @note If the request is already complete, the handler is called | |||
* immediately. | * immediately. | |||
*/ | */ | |||
Request* done(const Callback& cb); | Request* done(const Callback& cb); | |||
template<class C> | ||||
Request* done(C* instance, void (C::*mem_func)(Request*)) | ||||
{ | ||||
return done(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | /** | |||
* Set the handler to be called when the request completes or aborts wi th an | * Add a handler to be called when the request completes or aborts with an | |||
* error. | * error. | |||
* | * | |||
* @note If the request has already failed, the handler is called | * @note If the request has already failed, the handler is called | |||
* immediately. | * immediately. | |||
*/ | */ | |||
Request* fail(const Callback& cb); | Request* fail(const Callback& cb); | |||
template<class C> | ||||
Request* fail(C* instance, void (C::*mem_func)(Request*)) | ||||
{ | ||||
return fail(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | /** | |||
* Set the handler to be called when the request either successfully | * Add a handler to be called when the request either successfully comp | |||
* completes or fails. | letes | |||
* or fails. | ||||
* | * | |||
* @note If the request is already complete or has already failed, the | * @note If the request is already complete or has already failed, the | |||
* handler is called immediately. | * handler is called immediately. | |||
*/ | */ | |||
Request* always(const Callback& cb); | Request* always(const Callback& cb); | |||
template<class C> | ||||
Request* always(C* instance, void (C::*mem_func)(Request*)) | ||||
{ | ||||
return always(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | /** | |||
* Set the data for the body of the request. The request is automatical ly | * Set the data for the body of the request. The request is automatical ly | |||
* send using the POST method. | * send using the POST method. | |||
* | * | |||
* @param data Body data | * @param data Body data | |||
* @param type Media Type (aka MIME) of the body data | * @param type Media Type (aka MIME) of the body data | |||
*/ | */ | |||
void setBodyData( const std::string& data, | void setBodyData( const std::string& data, | |||
const std::string& type = "text/plain" ); | const std::string& type = "text/plain" ); | |||
void setBodyData( const SGPropertyNode* data ); | void setBodyData( const SGPropertyNode* data ); | |||
skipping to change at line 102 | skipping to change at line 121 | |||
virtual std::string scheme() const; | virtual std::string scheme() const; | |||
virtual std::string path() const; | virtual std::string path() const; | |||
virtual std::string host() const; | virtual std::string host() const; | |||
virtual std::string hostAndPort() const; | virtual std::string hostAndPort() const; | |||
virtual unsigned short port() const; | virtual unsigned short port() const; | |||
virtual std::string query() const; | virtual std::string query() const; | |||
StringMap const& responseHeaders() const | StringMap const& responseHeaders() const | |||
{ return _responseHeaders; } | { return _responseHeaders; } | |||
std::string responseMime() const; | ||||
virtual int responseCode() const | virtual int responseCode() const | |||
{ return _responseStatus; } | { return _responseStatus; } | |||
virtual std::string responseReason() const | virtual std::string responseReason() const | |||
{ return _responseReason; } | { return _responseReason; } | |||
void setResponseLength(unsigned int l); | void setResponseLength(unsigned int l); | |||
virtual unsigned int responseLength() const; | virtual unsigned int responseLength() const; | |||
/** | /** | |||
skipping to change at line 206 | skipping to change at line 227 | |||
std::string _request_data; | std::string _request_data; | |||
std::string _request_media_type; | std::string _request_media_type; | |||
HTTPVersion _responseVersion; | HTTPVersion _responseVersion; | |||
int _responseStatus; | int _responseStatus; | |||
std::string _responseReason; | std::string _responseReason; | |||
StringMap _responseHeaders; | StringMap _responseHeaders; | |||
unsigned int _responseLength; | unsigned int _responseLength; | |||
unsigned int _receivedBodyBytes; | unsigned int _receivedBodyBytes; | |||
Callback _cb_done, | function_list<Callback> _cb_done, | |||
_cb_fail, | _cb_fail, | |||
_cb_always; | _cb_always; | |||
ReadyState _ready_state; | ReadyState _ready_state; | |||
bool _willClose; | bool _willClose; | |||
}; | }; | |||
typedef SGSharedPtr<Request> Request_ptr; | typedef SGSharedPtr<Request> Request_ptr; | |||
} // of namespace HTTP | } // of namespace HTTP | |||
} // of namespace simgear | } // of namespace simgear | |||
End of changes. 10 change blocks. | ||||
8 lines changed or deleted | 30 lines changed or added | |||
Install.hxx | Install.hxx | |||
---|---|---|---|---|
skipping to change at line 26 | skipping to change at line 26 | |||
// | // | |||
#ifndef SG_PACKAGE_INSTALL_HXX | #ifndef SG_PACKAGE_INSTALL_HXX | |||
#define SG_PACKAGE_INSTALL_HXX | #define SG_PACKAGE_INSTALL_HXX | |||
#include <vector> | #include <vector> | |||
#include <simgear/misc/sg_path.hxx> | #include <simgear/misc/sg_path.hxx> | |||
#include <simgear/package/Delegate.hxx> | #include <simgear/package/Delegate.hxx> | |||
#include <simgear/structure/function_list.hxx> | ||||
#include <simgear/structure/SGReferenced.hxx> | ||||
#include <simgear/structure/SGSharedPtr.hxx> | ||||
#include <boost/bind.hpp> | ||||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace pkg | namespace pkg | |||
{ | { | |||
// forward decls | // forward decls | |||
class Package; | class Package; | |||
class Catalog; | class Catalog; | |||
class Install; | ||||
typedef SGSharedPtr<Package> PackageRef; | ||||
typedef SGSharedPtr<Catalog> CatalogRef; | ||||
typedef SGSharedPtr<Install> InstallRef; | ||||
/** | /** | |||
* | * | |||
*/ | */ | |||
class Install | class Install : public SGReferenced | |||
{ | { | |||
public: | public: | |||
virtual ~Install(); | ||||
typedef boost::function<void(Install*)> Callback; | ||||
typedef boost::function<void(Install*, unsigned int, unsigned int)> | ||||
ProgressCallback; | ||||
/** | /** | |||
* create from a directory on disk, or fail. | * create from a directory on disk, or fail. | |||
*/ | */ | |||
static Install* createFromPath(const SGPath& aPath, Catalog* aCat); | static InstallRef createFromPath(const SGPath& aPath, CatalogRef aCat); | |||
unsigned int revsion() const | unsigned int revsion() const | |||
{ return m_revision; } | { return m_revision; } | |||
Package* package() const | PackageRef package() const | |||
{ return m_package; } | { return m_package; } | |||
SGPath path() const | SGPath path() const | |||
{ return m_path; } | { return m_path; } | |||
bool hasUpdate() const; | bool hasUpdate() const; | |||
void startUpdate(); | void startUpdate(); | |||
void uninstall(); | void uninstall(); | |||
// boost signals time? | /** | |||
// failure | * Set the handler to be called when the installation successfully | |||
// progress | * completes. | |||
// completed | * | |||
* @note If the installation is already complete, the handler is called | ||||
* immediately. | ||||
*/ | ||||
Install* done(const Callback& cb); | ||||
template<class C> | ||||
Install* done(C* instance, void (C::*mem_func)(Install*)) | ||||
{ | ||||
return done(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | ||||
* Set the handler to be called when the installation fails or is abort | ||||
ed. | ||||
* | ||||
* @note If the installation has already failed, the handler is called | ||||
* immediately. | ||||
*/ | ||||
Install* fail(const Callback& cb); | ||||
template<class C> | ||||
Install* fail(C* instance, void (C::*mem_func)(Install*)) | ||||
{ | ||||
return fail(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | ||||
* Set the handler to be called when the installation either successful | ||||
ly | ||||
* completes or fails. | ||||
* | ||||
* @note If the installation is already complete or has already failed, | ||||
the | ||||
* handler is called immediately. | ||||
*/ | ||||
Install* always(const Callback& cb); | ||||
template<class C> | ||||
Install* always(C* instance, void (C::*mem_func)(Install*)) | ||||
{ | ||||
return always(boost::bind(mem_func, instance, _1)); | ||||
} | ||||
/** | ||||
* Set the handler to be called during downloading the installation fil | ||||
e | ||||
* indicating the progress of the download. | ||||
* | ||||
*/ | ||||
Install* progress(const ProgressCallback& cb); | ||||
template<class C> | ||||
Install* progress(C* instance, | ||||
void (C::*mem_func)(Install*, unsigned int, unsigned | ||||
int)) | ||||
{ | ||||
return progress(boost::bind(mem_func, instance, _1, _2, _3)); | ||||
} | ||||
private: | private: | |||
friend class Package; | friend class Package; | |||
class PackageArchiveDownloader; | class PackageArchiveDownloader; | |||
friend class PackageArchiveDownloader; | friend class PackageArchiveDownloader; | |||
Install(Package* aPkg, const SGPath& aPath); | Install(PackageRef aPkg, const SGPath& aPath); | |||
void parseRevision(); | void parseRevision(); | |||
void writeRevisionFile(); | void writeRevisionFile(); | |||
void installResult(Delegate::FailureCode aReason); | void installResult(Delegate::FailureCode aReason); | |||
void installProgress(unsigned int aBytes, unsigned int aTotal); | void installProgress(unsigned int aBytes, unsigned int aTotal); | |||
Package* m_package; | PackageRef m_package; | |||
unsigned int m_revision; ///< revision on disk | unsigned int m_revision; ///< revision on disk | |||
SGPath m_path; ///< installation point on disk | SGPath m_path; ///< installation point on disk | |||
PackageArchiveDownloader* m_download; | PackageArchiveDownloader* m_download; | |||
Delegate::FailureCode _status; | ||||
function_list<Callback> _cb_done, | ||||
_cb_fail, | ||||
_cb_always; | ||||
function_list<ProgressCallback> _cb_progress; | ||||
}; | }; | |||
} // of namespace pkg | } // of namespace pkg | |||
} // of namespace simgear | } // of namespace simgear | |||
#endif // of SG_PACKAGE_CATALOG_HXX | #endif // of SG_PACKAGE_CATALOG_HXX | |||
End of changes. 10 change blocks. | ||||
9 lines changed or deleted | 91 lines changed or added | |||
MouseEvent.hxx | MouseEvent.hxx | |||
---|---|---|---|---|
// Mouse event | ///@file Mouse event | |||
// | // | |||
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> | |||
// | // | |||
// This library is free software; you can redistribute it and/or | // This library is free software; you can redistribute it and/or | |||
// modify it under the terms of the GNU Library General Public | // modify it under the terms of the GNU Library General Public | |||
// License as published by the Free Software Foundation; either | // License as published by the Free Software Foundation; either | |||
// version 2 of the License, or (at your option) any later version. | // version 2 of the License, or (at your option) any later version. | |||
// | // | |||
// This library is distributed in the hope that it will be useful, | // This library is distributed in the hope that it will be useful, | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef CANVAS_MOUSE_EVENT_HXX_ | #ifndef CANVAS_MOUSE_EVENT_HXX_ | |||
#define CANVAS_MOUSE_EVENT_HXX_ | #define CANVAS_MOUSE_EVENT_HXX_ | |||
#include "CanvasEvent.hxx" | #include <simgear/canvas/CanvasEvent.hxx> | |||
#include <osgGA/GUIEventAdapter> | #include <osgGA/GUIEventAdapter> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
class MouseEvent: | class MouseEvent: | |||
public Event | public Event | |||
{ | { | |||
public: | public: | |||
MouseEvent(): | MouseEvent(); | |||
button(-1), | MouseEvent(const osgGA::GUIEventAdapter& ea); | |||
state(-1), | ||||
mod(-1), | virtual bool canBubble() const; | |||
click_count(0) | ||||
{} | ||||
MouseEvent(const osgGA::GUIEventAdapter& ea): | ||||
button(ea.getButton()), | ||||
state(ea.getButtonMask()), | ||||
mod(ea.getModKeyMask()), | ||||
click_count(0) | ||||
{ | ||||
time = ea.getTime(); | ||||
} | ||||
osg::Vec2f getScreenPos() const { return screen_pos; } | osg::Vec2f getScreenPos() const { return screen_pos; } | |||
osg::Vec2f getClientPos() const { return client_pos; } | osg::Vec2f getClientPos() const { return client_pos; } | |||
osg::Vec2f getLocalPos() const { return local_pos; } | osg::Vec2f getLocalPos() const { return local_pos; } | |||
osg::Vec2f getDelta() const { return delta; } | osg::Vec2f getDelta() const { return delta; } | |||
float getScreenX() const { return screen_pos.x(); } | float getScreenX() const { return screen_pos.x(); } | |||
float getScreenY() const { return screen_pos.y(); } | float getScreenY() const { return screen_pos.y(); } | |||
float getClientX() const { return client_pos.x(); } | float getClientX() const { return client_pos.x(); } | |||
float getClientY() const { return client_pos.y(); } | float getClientY() const { return client_pos.y(); } | |||
float getLocalX() const { return local_pos.x(); } | float getLocalX() const { return local_pos.x(); } | |||
float getLocalY() const { return local_pos.y(); } | float getLocalY() const { return local_pos.y(); } | |||
float getDeltaX() const { return delta.x(); } | float getDeltaX() const { return delta.x(); } | |||
float getDeltaY() const { return delta.y(); } | float getDeltaY() const { return delta.y(); } | |||
int getButton() const { return button; } | ||||
int getButtonMask() const { return buttons; } | ||||
int getModifiers() const { return modifiers; } | ||||
int getCurrentClickCount() const { return click_count; } | int getCurrentClickCount() const { return click_count; } | |||
osg::Vec2f screen_pos, //<! Position in screen coordinates | osg::Vec2f screen_pos, //<! Position in screen coordinates | |||
client_pos, //<! Position in window/canvas coordinates | client_pos, //<! Position in window/canvas coordinates | |||
local_pos, //<! Position in local/element coordinates | local_pos, //<! Position in local/element coordinates | |||
delta; | delta; | |||
int button, //<! Button for this event | int button, //<! Button for this event | |||
state, //<! Current button state | buttons, //<! Current button state | |||
mod, //<! Keyboard modifier state | modifiers, //<! Keyboard modifier state | |||
click_count; //<! Current click count | click_count; //<! Current click count | |||
}; | }; | |||
} // namespace canvas | } // namespace canvas | |||
} // namespace simgear | } // namespace simgear | |||
#endif /* CANVAS_MOUSE_EVENT_HXX_ */ | #endif /* CANVAS_MOUSE_EVENT_HXX_ */ | |||
End of changes. 5 change blocks. | ||||
19 lines changed or deleted | 12 lines changed or added | |||
NasalCallContext.hxx | NasalCallContext.hxx | |||
---|---|---|---|---|
skipping to change at line 41 | skipping to change at line 41 | |||
*/ | */ | |||
class CallContext | class CallContext | |||
{ | { | |||
public: | public: | |||
CallContext(naContext c, size_t argc, naRef* args): | CallContext(naContext c, size_t argc, naRef* args): | |||
c(c), | c(c), | |||
argc(argc), | argc(argc), | |||
args(args) | args(args) | |||
{} | {} | |||
bool isNumeric(size_t index) const | #define SG_CTX_CHECK_ARG(name, check)\ | |||
{ | bool is##name(size_t index) const\ | |||
return (index < argc && naIsNum(args[index])); | {\ | |||
} | return (index < argc && naIs##check(args[index]));\ | |||
} | ||||
SG_CTX_CHECK_ARG(Code, Code) | ||||
SG_CTX_CHECK_ARG(CCode, CCode) | ||||
SG_CTX_CHECK_ARG(Func, Func) | ||||
SG_CTX_CHECK_ARG(Ghost, Ghost) | ||||
SG_CTX_CHECK_ARG(Hash, Hash) | ||||
SG_CTX_CHECK_ARG(Nil, Nil) | ||||
SG_CTX_CHECK_ARG(Numeric, Num) | ||||
SG_CTX_CHECK_ARG(Scalar, Scalar) | ||||
SG_CTX_CHECK_ARG(String, String) | ||||
SG_CTX_CHECK_ARG(Vector, Vector) | ||||
bool isString(size_t index) const | #undef SG_CTX_CHECK_ARG | |||
{ | ||||
return (index < argc && naIsString(args[index])); | ||||
} | ||||
bool isHash(size_t index) const | ||||
{ | ||||
return (index < argc && naIsHash(args[index])); | ||||
} | ||||
bool isVector(size_t index) const | ||||
{ | ||||
return (index < argc && naIsVector(args[index])); | ||||
} | ||||
bool isGhost(size_t index) const | ||||
{ | ||||
return (index < argc && naIsGhost(args[index])); | ||||
} | ||||
void popFront(size_t num = 1) | void popFront(size_t num = 1) | |||
{ | { | |||
if( argc < num ) | if( argc < num ) | |||
return; | return; | |||
args += num; | args += num; | |||
argc -= num; | argc -= num; | |||
} | } | |||
End of changes. 2 change blocks. | ||||
23 lines changed or deleted | 17 lines changed or added | |||
NasalHash.hxx | NasalHash.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_NASAL_HASH_HXX_ | #ifndef SG_NASAL_HASH_HXX_ | |||
#define SG_NASAL_HASH_HXX_ | #define SG_NASAL_HASH_HXX_ | |||
#include "from_nasal.hxx" | #include "from_nasal.hxx" | |||
#include "to_nasal.hxx" | #include "to_nasal.hxx" | |||
#include <simgear/structure/map.hxx> | ||||
#include <boost/iterator/iterator_facade.hpp> | ||||
namespace nasal | namespace nasal | |||
{ | { | |||
/** | /** | |||
* A Nasal Hash | * A Nasal Hash | |||
*/ | */ | |||
class Hash | class Hash | |||
{ | { | |||
public: | public: | |||
template<bool> class Entry; | ||||
template<bool> class Iterator; | ||||
typedef Entry<false> reference; | ||||
typedef Entry<true> const_reference; | ||||
typedef Iterator<false> iterator; | ||||
typedef Iterator<true> const_iterator; | ||||
/** | /** | |||
* Create a new Nasal Hash | * Create a new Nasal Hash | |||
* | * | |||
* @param c Nasal context for creating the hash | * @param c Nasal context for creating the hash | |||
*/ | */ | |||
Hash(naContext c); | explicit Hash(naContext c); | |||
/** | /** | |||
* Initialize from an existing Nasal Hash | * Initialize from an existing Nasal Hash | |||
* | * | |||
* @param hash Existing Nasal Hash | * @param hash Existing Nasal Hash | |||
* @param c Nasal context for creating new Nasal objects | * @param c Nasal context for creating new Nasal objects | |||
*/ | */ | |||
Hash(naRef hash, naContext c); | Hash(naRef hash, naContext c); | |||
iterator begin(); | ||||
iterator end(); | ||||
const_iterator begin() const; | ||||
const_iterator end() const; | ||||
/** | /** | |||
* Set member | * Set member | |||
* | * | |||
* @param name Member name | * @param name Member name | |||
* @param ref Reference to Nasal object (naRef) | * @param ref Reference to Nasal object (naRef) | |||
*/ | */ | |||
void set(const std::string& name, naRef ref); | void set(const std::string& name, naRef ref); | |||
/** | /** | |||
* Set member to anything convertible using to_nasal | * Set member to anything convertible using to_nasal | |||
skipping to change at line 73 | skipping to change at line 89 | |||
*/ | */ | |||
template<class T> | template<class T> | |||
void set(const std::string& name, const T& val) | void set(const std::string& name, const T& val) | |||
{ | { | |||
set(name, to_nasal(_context, val)); | set(name, to_nasal(_context, val)); | |||
} | } | |||
/** | /** | |||
* Get member | * Get member | |||
* | * | |||
* @param key Member key | ||||
*/ | ||||
naRef get(naRef key) const; | ||||
/** | ||||
* Get member | ||||
* | ||||
* @param name Member name | * @param name Member name | |||
*/ | */ | |||
naRef get(const std::string& name); | naRef get(const std::string& name) const; | |||
/** | /** | |||
* Get member converted to given type | * Get member converted to given type | |||
* | * | |||
* @tparam T Type to convert to (using from_nasal) | * @tparam T Type to convert to (using from_nasal) | |||
* @param name Member name | * @param name Member name | |||
*/ | */ | |||
template<class T> | template<class T, class Key> | |||
T get(const std::string& name) | T get(const Key& name) const | |||
{ | { | |||
BOOST_STATIC_ASSERT(( boost::is_convertible<Key, naRef>::value | ||||
|| boost::is_convertible<Key, std::string>::valu | ||||
e | ||||
)); | ||||
return from_nasal<T>(_context, get(name)); | return from_nasal<T>(_context, get(name)); | |||
} | } | |||
/** | /** | |||
* Get member converted to callable object | * Get member converted to callable object | |||
* | * | |||
* @tparam Sig Function signature | * @tparam Sig Function signature | |||
* @param name Member name | * @param name Member name | |||
* @param key Member key | ||||
*/ | */ | |||
template<class Sig> | template<class Sig, class Key> | |||
typename boost::enable_if< boost::is_function<Sig>, | typename boost::enable_if< boost::is_function<Sig>, | |||
boost::function<Sig> | boost::function<Sig> | |||
>::type | >::type | |||
get(const std::string& name) | get(const Key& name) const | |||
{ | { | |||
BOOST_STATIC_ASSERT(( boost::is_convertible<Key, naRef>::value | ||||
|| boost::is_convertible<Key, std::string>::valu | ||||
e | ||||
)); | ||||
return from_nasal_helper(_context, get(name), static_cast<Sig*>(0)) ; | return from_nasal_helper(_context, get(name), static_cast<Sig*>(0)) ; | |||
} | } | |||
/** | /** | |||
* Returns the number of entries in the hash | ||||
*/ | ||||
int size() const; | ||||
/** | ||||
* Get a list of all keys | ||||
*/ | ||||
std::vector<std::string> keys() const; | ||||
/** | ||||
* Create a new child hash (module) | * Create a new child hash (module) | |||
* | * | |||
* @param name Name of the new hash inside this hash | * @param name Name of the new hash inside this hash | |||
*/ | */ | |||
Hash createHash(const std::string& name); | Hash createHash(const std::string& name); | |||
/** | /** | |||
* Set a new Nasal context. Eg. in FlightGear the context changes eve ry | * Set a new Nasal context. Eg. in FlightGear the context changes eve ry | |||
* frame, so if using the same Hash instance for multiple frames you have | * frame, so if using the same Hash instance for multiple frames you have | |||
* to update the context before using the Hash object. | * to update the context before using the Hash object. | |||
*/ | */ | |||
void setContext(naContext context); | void setContext(naContext context); | |||
/** | /** | |||
* Get Nasal representation of Hash | * Get Nasal representation of Hash | |||
*/ | */ | |||
const naRef get_naRef() const; | naRef get_naRef() const; | |||
/** | ||||
* Get Nasal vector of keys | ||||
*/ | ||||
naRef get_naRefKeys() const; | ||||
/// Hash entry | ||||
template<bool is_const> | ||||
class Entry | ||||
{ | ||||
public: | ||||
typedef typename boost::mpl::if_c< | ||||
is_const, | ||||
Hash const*, | ||||
Hash* | ||||
>::type HashPtr; | ||||
Entry(HashPtr hash, naRef key): | ||||
_hash(hash), | ||||
_key(key) | ||||
{ | ||||
assert(hash); | ||||
assert(naIsScalar(key)); | ||||
} | ||||
std::string getKey() const | ||||
{ | ||||
if( !_hash || naIsNil(_key) ) | ||||
return std::string(); | ||||
return from_nasal<std::string>(_hash->_context, _key); | ||||
} | ||||
template<class T> | ||||
T getValue() const | ||||
{ | ||||
if( !_hash || naIsNil(_key) ) | ||||
return T(); | ||||
return _hash->template get<T>(_key); | ||||
} | ||||
private: | ||||
HashPtr _hash; | ||||
naRef _key; | ||||
}; | ||||
/// Hash iterator | ||||
template<bool is_const> | ||||
class Iterator: | ||||
public boost::iterator_facade< | ||||
Iterator<is_const>, | ||||
Entry<is_const>, | ||||
boost::bidirectional_traversal_tag, | ||||
Entry<is_const> | ||||
> | ||||
{ | ||||
public: | ||||
typedef typename Entry<is_const>::HashPtr HashPtr; | ||||
typedef Entry<is_const> value_type; | ||||
Iterator(): | ||||
_hash(NULL), | ||||
_index(0) | ||||
{} | ||||
Iterator(HashPtr hash, int index): | ||||
_hash(hash), | ||||
_index(index) | ||||
{} | ||||
/** | ||||
* Convert from iterator to const_iterator or copy within same ty | ||||
pe | ||||
*/ | ||||
template<bool is_other_const> | ||||
Iterator( Iterator<is_other_const> const& other, | ||||
typename boost::enable_if_c< is_const || !is_other_cons | ||||
t, | ||||
void* | ||||
>::type = NULL ): | ||||
_hash(other._hash), | ||||
_index(other._index) | ||||
{} | ||||
private: | ||||
friend class boost::iterator_core_access; | ||||
template <bool> friend class Iterator; | ||||
HashPtr _hash; | ||||
int _index; | ||||
template<bool is_other_const> | ||||
bool equal(Iterator<is_other_const> const& other) const | ||||
{ | ||||
return _hash == other._hash | ||||
&& _index == other._index; | ||||
} | ||||
void increment() { ++_index; } | ||||
void decrement() { --_index; } | ||||
value_type dereference() const | ||||
{ | ||||
return value_type(_hash, naVec_get(_hash->get_naRefKeys(), _ind | ||||
ex)); | ||||
} | ||||
}; | ||||
protected: | protected: | |||
naRef _hash; | naRef _hash; | |||
naContext _context; | naContext _context; | |||
mutable naRef _keys; //< Store vector of keys (for iterators) | ||||
}; | }; | |||
} // namespace nasal | } // namespace nasal | |||
template<class Value> | ||||
simgear::Map<std::string, Value> | ||||
from_nasal_helper( naContext c, | ||||
naRef ref, | ||||
const simgear::Map<std::string, Value>* ) | ||||
{ | ||||
nasal::Hash hash = from_nasal_helper(c, ref, static_cast<nasal::Hash*>(0) | ||||
); | ||||
simgear::Map<std::string, Value> map; | ||||
for(nasal::Hash::const_iterator it = hash.begin(); it != hash.end(); ++it | ||||
) | ||||
map[ it->getKey() ] = it->getValue<Value>(); | ||||
return map; | ||||
} | ||||
#endif /* SG_NASAL_HASH_HXX_ */ | #endif /* SG_NASAL_HASH_HXX_ */ | |||
End of changes. 16 change blocks. | ||||
7 lines changed or deleted | 179 lines changed or added | |||
NasalObjectHolder.hxx | NasalObjectHolder.hxx | |||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_NASAL_OBJECT_HOLDER_HXX_ | #ifndef SG_NASAL_OBJECT_HOLDER_HXX_ | |||
#define SG_NASAL_OBJECT_HOLDER_HXX_ | #define SG_NASAL_OBJECT_HOLDER_HXX_ | |||
#include <simgear/nasal/naref.h> | #include <simgear/nasal/nasal.h> | |||
#include <simgear/structure/SGSharedPtr.hxx> | #include <simgear/structure/SGSharedPtr.hxx> | |||
namespace nasal | namespace nasal | |||
{ | { | |||
class ObjectHolder; | /** | |||
typedef SGSharedPtr<ObjectHolder> ObjectHolderRef; | * Usable for example as empty base class if a base class is required.(Eg | |||
. as | ||||
* parameter for a mixin class). | ||||
*/ | ||||
struct empty_class {}; | ||||
/** | /** | |||
* Prevent a Nasal object from being destroyed by the garbage collector d uring | * Prevent a Nasal object from being destroyed by the garbage collector d uring | |||
* the lifetime of this object. | * the lifetime of this object. | |||
*/ | */ | |||
template<class Base = empty_class> | ||||
class ObjectHolder: | class ObjectHolder: | |||
public SGReferenced | public Base | |||
{ | { | |||
public: | public: | |||
/** | /** | |||
* @param obj Object to save | ||||
*/ | ||||
explicit ObjectHolder(naRef obj); | ||||
/** | ||||
* | ||||
*/ | ||||
ObjectHolder(); | ||||
/** | ||||
* | * | |||
*/ | */ | |||
~ObjectHolder(); | ~ObjectHolder(); | |||
/** | /** | |||
* Get captured Nasal object | * Get captured Nasal object | |||
*/ | */ | |||
naRef get_naRef() const; | naRef get_naRef() const; | |||
/** | /** | |||
* Release the managed object | ||||
*/ | ||||
void reset(); | ||||
/** | ||||
* Replaces the managed object (the old object is released) | ||||
* | ||||
* @param obj New object to save | ||||
*/ | ||||
void reset(naRef obj); | ||||
/** | ||||
* Check if there is a managed object | ||||
*/ | ||||
bool valid() const; | ||||
/** | ||||
* Save the given object as long as the returned holder exists. | * Save the given object as long as the returned holder exists. | |||
* | * | |||
* @param obj Object to save | * @param obj Object to save | |||
*/ | */ | |||
static ObjectHolderRef makeShared(naRef obj); | static SGSharedPtr<ObjectHolder<Base> > makeShared(naRef obj); | |||
protected: | protected: | |||
naRef _ref; | naRef _ref; | |||
int _gc_key; | int _gc_key; | |||
/** | ||||
* @param obj Object to save | ||||
*/ | ||||
ObjectHolder(naRef obj); | ||||
}; | }; | |||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
ObjectHolder<Base>::~ObjectHolder() | ||||
{ | ||||
if( !naIsNil(_ref) ) | ||||
naGCRelease(_gc_key); | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
naRef ObjectHolder<Base>::get_naRef() const | ||||
{ | ||||
return _ref; | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
void ObjectHolder<Base>::reset() | ||||
{ | ||||
if( !naIsNil(_ref) ) | ||||
naGCRelease(_gc_key); | ||||
_ref = naNil(); | ||||
_gc_key = 0; | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
void ObjectHolder<Base>::reset(naRef obj) | ||||
{ | ||||
if( !naIsNil(_ref) ) | ||||
naGCRelease(_gc_key); | ||||
_ref = obj; | ||||
_gc_key = naGCSave(obj); | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
bool ObjectHolder<Base>::valid() const | ||||
{ | ||||
return !naIsNil(_ref); | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
ObjectHolder<Base>::ObjectHolder(naRef obj): | ||||
_ref(obj), | ||||
_gc_key(0) | ||||
{ | ||||
if( !naIsNil(obj) ) | ||||
naGCSave(obj); | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
ObjectHolder<Base>::ObjectHolder(): | ||||
_ref(naNil()), | ||||
_gc_key(0) | ||||
{ | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Base> | ||||
SGSharedPtr<ObjectHolder<Base> > | ||||
ObjectHolder<Base>::makeShared(naRef obj) | ||||
{ | ||||
return SGSharedPtr<ObjectHolder<Base> >( new ObjectHolder<SGReferenced> | ||||
(obj) ); | ||||
} | ||||
} // namespace nasal | } // namespace nasal | |||
#endif /* SG_NASAL_OBJECT_HOLDER_HXX_ */ | #endif /* SG_NASAL_OBJECT_HOLDER_HXX_ */ | |||
End of changes. 9 change blocks. | ||||
10 lines changed or deleted | 117 lines changed or added | |||
Package.hxx | Package.hxx | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
#ifndef SG_PACKAGE_PACKAGE_HXX | #ifndef SG_PACKAGE_PACKAGE_HXX | |||
#define SG_PACKAGE_PACKAGE_HXX | #define SG_PACKAGE_PACKAGE_HXX | |||
#include <set> | #include <set> | |||
#include <vector> | #include <vector> | |||
#include <simgear/props/props.hxx> | #include <simgear/props/props.hxx> | |||
#include <simgear/misc/strutils.hxx> | #include <simgear/misc/strutils.hxx> | |||
#include <simgear/structure/function_list.hxx> | ||||
#include <simgear/structure/SGReferenced.hxx> | ||||
#include <simgear/structure/SGSharedPtr.hxx> | ||||
typedef std::set<std::string> string_set; | typedef std::set<std::string> string_set; | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace pkg | namespace pkg | |||
{ | { | |||
// forward decls | // forward decls | |||
class Install; | class Install; | |||
class Catalog; | class Catalog; | |||
class Package; | class Package; | |||
typedef std::vector<Package*> PackageList; | typedef SGSharedPtr<Package> PackageRef; | |||
typedef SGSharedPtr<Catalog> CatalogRef; | ||||
typedef SGSharedPtr<Install> InstallRef; | ||||
typedef std::vector<PackageRef> PackageList; | ||||
class Package | class Package : public SGReferenced | |||
{ | { | |||
public: | public: | |||
typedef boost::function<void(Package*, Install*)> InstallCallback; | ||||
/** | /** | |||
* get or create an install for the package | * get or create an install for the package | |||
*/ | */ | |||
Install* install(); | InstallRef install(); | |||
InstallRef | ||||
existingInstall(const InstallCallback& cb = InstallCallback()) const; | ||||
bool isInstalled() const; | bool isInstalled() const; | |||
std::string id() const; | std::string id() const; | |||
/** | /** | |||
* Variant IDs. Note the primary ID will always be included as | ||||
* variants()[0], to simplify enumerating all variants | ||||
*/ | ||||
string_list variants() const; | ||||
/** | ||||
* Fully-qualified ID, including our catalog'd ID | ||||
*/ | ||||
std::string qualifiedId() const; | ||||
/** | ||||
* human-readable name - note this is probably not localised, | * human-readable name - note this is probably not localised, | |||
* although this is not ruled out for the future. | * although this is not ruled out for the future. | |||
*/ | */ | |||
std::string name() const; | std::string name() const; | |||
/** | /** | |||
* Human readable name of a variant | ||||
*/ | ||||
std::string nameForVariant(const std::string& vid) const; | ||||
/** | ||||
* syntactic sugar to get the localised description | * syntactic sugar to get the localised description | |||
*/ | */ | |||
std::string description() const; | std::string description() const; | |||
/** | /** | |||
* access the raw property data in the package | * access the raw property data in the package | |||
*/ | */ | |||
SGPropertyNode* properties() const; | SGPropertyNode* properties() const; | |||
/** | /** | |||
* hex-encoded MD5 sum of the download files | * hex-encoded MD5 sum of the download files | |||
*/ | */ | |||
std::string md5() const; | std::string md5() const; | |||
std::string getLocalisedProp(const std::string& aName) const; | std::string getLocalisedProp(const std::string& aName) const; | |||
unsigned int revision() const; | unsigned int revision() const; | |||
Catalog* catalog() const | size_t fileSizeBytes() const; | |||
CatalogRef catalog() const | ||||
{ return m_catalog; } | { return m_catalog; } | |||
bool matches(const SGPropertyNode* aFilter) const; | bool matches(const SGPropertyNode* aFilter) const; | |||
/** | /** | |||
* download URLs for the package | * download URLs for the package | |||
*/ | */ | |||
string_list downloadUrls() const; | string_list downloadUrls() const; | |||
string_list thumbnailUrls() const; | string_list thumbnailUrls() const; | |||
/** | /** | |||
* Packages we depend upon. | * Packages we depend upon. | |||
* If the dependency list cannot be satisifed for some reason, | * If the dependency list cannot be satisifed for some reason, | |||
* this will raise an sg_exception. | * this will raise an sg_exception. | |||
*/ | */ | |||
PackageList dependencies() const; | PackageList dependencies() const; | |||
private: | private: | |||
SGPath pathOnDisk() const; | ||||
friend class Catalog; | friend class Catalog; | |||
Package(const SGPropertyNode* aProps, Catalog* aCatalog); | Package(const SGPropertyNode* aProps, CatalogRef aCatalog); | |||
void initWithProps(const SGPropertyNode* aProps); | void initWithProps(const SGPropertyNode* aProps); | |||
void updateFromProps(const SGPropertyNode* aProps); | ||||
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; | std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; | |||
SGPropertyNode_ptr m_props; | SGPropertyNode_ptr m_props; | |||
std::string m_id; | ||||
string_set m_tags; | string_set m_tags; | |||
Catalog* m_catalog; | CatalogRef m_catalog; | |||
mutable function_list<InstallCallback> _install_cb; | ||||
}; | }; | |||
} // of namespace pkg | } // of namespace pkg | |||
} // of namespace simgear | } // of namespace simgear | |||
#endif // of SG_PACKAGE_PACKAGE_HXX | #endif // of SG_PACKAGE_PACKAGE_HXX | |||
End of changes. 13 change blocks. | ||||
6 lines changed or deleted | 45 lines changed or added | |||
PropertyBasedElement.hxx | PropertyBasedElement.hxx | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_PROPERTY_BASED_ELEMENT_HXX_ | #ifndef SG_PROPERTY_BASED_ELEMENT_HXX_ | |||
#define SG_PROPERTY_BASED_ELEMENT_HXX_ | #define SG_PROPERTY_BASED_ELEMENT_HXX_ | |||
#include <simgear/props/props.hxx> | #include <simgear/props/props.hxx> | |||
#include <simgear/structure/SGWeakReferenced.hxx> | ||||
#include <boost/call_traits.hpp> | ||||
#include <boost/shared_ptr.hpp> | ||||
#include <boost/weak_ptr.hpp> | ||||
namespace simgear | namespace simgear | |||
{ | { | |||
class PropertyBasedElement; | ||||
typedef boost::shared_ptr<PropertyBasedElement> PropertyBasedElementPtr; | ||||
typedef boost::weak_ptr<PropertyBasedElement> PropertyBasedElementWeakPtr | ||||
; | ||||
/** | /** | |||
* Base class for a property controlled element | * Base class for a property controlled element | |||
*/ | */ | |||
class PropertyBasedElement: | class PropertyBasedElement: | |||
public SGPropertyChangeListener | public SGPropertyChangeListener, | |||
public virtual SGVirtualWeakReferenced | ||||
{ | { | |||
public: | public: | |||
PropertyBasedElement(SGPropertyNode* node); | PropertyBasedElement(SGPropertyNode* node); | |||
virtual ~PropertyBasedElement(); | virtual ~PropertyBasedElement(); | |||
/** | /** | |||
* Remove the property listener of the element. | * Remove the property listener of the element. | |||
* | * | |||
* You will need to call the appropriate methods (#childAdded, | * You will need to call the appropriate methods (#childAdded, | |||
* #childRemoved, #valueChanged) yourself to ensure the element still | * #childRemoved, #valueChanged) yourself to ensure the element still | |||
skipping to change at line 66 | skipping to change at line 60 | |||
*/ | */ | |||
void destroy(); | void destroy(); | |||
virtual void update(double delta_time_sec) = 0; | virtual void update(double delta_time_sec) = 0; | |||
SGConstPropertyNode_ptr getProps() const; | SGConstPropertyNode_ptr getProps() const; | |||
SGPropertyNode_ptr getProps(); | SGPropertyNode_ptr getProps(); | |||
template<class T> | template<class T> | |||
void set( const std::string& name, | void set( const std::string& name, | |||
typename boost::call_traits<T>::param_type val ) | const T& val ) | |||
{ | { | |||
setValue(_node->getNode(name, true), val); | setValue(_node->getNode(name, true), val); | |||
} | } | |||
template<class T> | template<class T> | |||
T get( const std::string& name, | T get( const std::string& name, | |||
typename boost::call_traits<T>::param_type def = T() ) | const T& def = T() ) | |||
{ | { | |||
SGPropertyNode const* child = _node->getNode(name); | SGPropertyNode const* child = _node->getNode(name); | |||
if( !child ) | if( !child ) | |||
return def; | return def; | |||
return getValue<T>(child); | return getValue<T>(child); | |||
} | } | |||
virtual void setSelf(const PropertyBasedElementPtr& self); | // Unshadow what we have just hidden... | |||
using SGWeakReferenced::get; | ||||
/** @brief Set a HTML5 like data property on this element. | ||||
* | ||||
* Set data-* properties on this element. A camel-case @a name will b | ||||
e | ||||
* converted to a hyphenated name with 'data-' prefixed. Setting a va | ||||
lue | ||||
* with this method does not trigger an update of the canvas and is m | ||||
eant | ||||
* to store data related to this element (used eg. inside scripts). | ||||
* | ||||
* @code{cpp} | ||||
* // Set value | ||||
* my_element->setDataProp("mySpecialInt", 3); | ||||
* | ||||
* // Get value (with default value) | ||||
* int val = my_element->getDataProp<int>("mySpecialInt"); // val = | ||||
= 3 | ||||
* val = my_element->getDataProp<int>("notExisting", 5); // val = | ||||
= 5 | ||||
* | ||||
* // Check if value exists | ||||
* SGPropertyNode* node = | ||||
* my_element->getDataProp<SGPropertyNode*>("mySpecialInt"); | ||||
* if( node ) | ||||
* val = node->getIntValue(); // node != NULL, val == 3 | ||||
* | ||||
* node = my_element->getDataProp<SGPropertyNode*>("notExisting"); | ||||
* // node == NULL | ||||
* @endcode | ||||
*/ | ||||
template<class T> | ||||
void setDataProp( const std::string& name, | ||||
const T& val ) | ||||
{ | ||||
const std::string& attr = dataPropToAttrName(name); | ||||
if( !attr.empty() ) | ||||
set<T>(attr, val); | ||||
else | ||||
SG_LOG(SG_GENERAL, SG_WARN, "Invalid data-prop name: " << name); | ||||
} | ||||
/** @brief Get a HTML5 like data property on this element. | ||||
* | ||||
* Get value or default value. | ||||
* | ||||
* @see setDataProp | ||||
*/ | ||||
template<class T> | ||||
typename boost::disable_if< | ||||
boost::is_same<T, SGPropertyNode*>, | ||||
T | ||||
>::type getDataProp( const std::string& name, | ||||
const T& def = T() ) const | ||||
{ | ||||
SGPropertyNode* node = getDataProp<SGPropertyNode*>(name); | ||||
if( node ) | ||||
return getValue<T>(node); | ||||
return def; | ||||
} | ||||
/** @brief Get a HTML5 like data property on this element. | ||||
* | ||||
* Use this variant to check if a property exists. | ||||
* | ||||
* @see setDataProp | ||||
*/ | ||||
template<class T> | ||||
typename boost::enable_if< | ||||
boost::is_same<T, SGPropertyNode*>, | ||||
T | ||||
>::type getDataProp( const std::string& name, | ||||
SGPropertyNode* = NULL ) const | ||||
{ | ||||
const std::string& attr = dataPropToAttrName(name); | ||||
if( attr.empty() ) | ||||
{ | ||||
SG_LOG(SG_GENERAL, SG_WARN, "Invalid data-prop name: " << name); | ||||
return NULL; | ||||
} | ||||
return _node->getNode(attr); | ||||
} | ||||
/** @brief Check whether a HTML5 like data property exists on this | ||||
* element. | ||||
* | ||||
*/ | ||||
bool hasDataProp(const std::string& name) const; | ||||
/** @brief Remove a HTML5 like data property (if it exists). | ||||
* | ||||
*/ | ||||
void removeDataProp(const std::string& name); | ||||
virtual void onDestroy() {}; | virtual void onDestroy() {}; | |||
static std::string dataPropToAttrName(const std::string& name); | ||||
static std::string attrToDataPropName(const std::string& name); | ||||
protected: | protected: | |||
SGPropertyNode_ptr _node; | SGPropertyNode_ptr _node; | |||
PropertyBasedElementWeakPtr _self; | ||||
}; | }; | |||
typedef SGSharedPtr<PropertyBasedElement> PropertyBasedElementPtr; | ||||
typedef SGWeakPtr<PropertyBasedElement> PropertyBasedElementWeakPtr; | ||||
} // namespace simgear | } // namespace simgear | |||
#endif /* SG_PROPERTY_BASED_ELEMENT_HXX_ */ | #endif /* SG_PROPERTY_BASED_ELEMENT_HXX_ */ | |||
End of changes. 9 change blocks. | ||||
14 lines changed or deleted | 110 lines changed or added | |||
PropertyBasedMgr.hxx | PropertyBasedMgr.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_PROPERTY_BASED_MGR_HXX_ | #ifndef SG_PROPERTY_BASED_MGR_HXX_ | |||
#define SG_PROPERTY_BASED_MGR_HXX_ | #define SG_PROPERTY_BASED_MGR_HXX_ | |||
#include "PropertyBasedElement.hxx" | #include "PropertyBasedElement.hxx" | |||
#include <simgear/structure/subsystem_mgr.hxx> | #include <simgear/structure/subsystem_mgr.hxx> | |||
#include <boost/shared_ptr.hpp> | ||||
#include <boost/function.hpp> | #include <boost/function.hpp> | |||
#include <vector> | #include <vector> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
class PropertyBasedMgr: | class PropertyBasedMgr: | |||
public SGSubsystem, | public SGSubsystem, | |||
public SGPropertyChangeListener | public SGPropertyChangeListener | |||
{ | { | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 0 lines changed or added | |||
Root.hxx | Root.hxx | |||
---|---|---|---|---|
skipping to change at line 27 | skipping to change at line 27 | |||
#ifndef SG_PACKAGE_ROOT_HXX | #ifndef SG_PACKAGE_ROOT_HXX | |||
#define SG_PACKAGE_ROOT_HXX | #define SG_PACKAGE_ROOT_HXX | |||
#include <vector> | #include <vector> | |||
#include <memory> // for auto_ptr | #include <memory> // for auto_ptr | |||
#include <simgear/misc/sg_path.hxx> | #include <simgear/misc/sg_path.hxx> | |||
#include <simgear/package/Delegate.hxx> | #include <simgear/package/Delegate.hxx> | |||
#include <simgear/structure/SGReferenced.hxx> | ||||
#include <simgear/structure/SGSharedPtr.hxx> | ||||
class SGPropertyNode; | class SGPropertyNode; | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace HTTP { | namespace HTTP { | |||
class Client; | class Client; | |||
class Request; | class Request; | |||
} | } | |||
namespace pkg | namespace pkg | |||
{ | { | |||
// forward decls | // forward decls | |||
class Package; | class Package; | |||
class Catalog; | class Catalog; | |||
class Install; | class Install; | |||
typedef std::vector<Package*> PackageList; | typedef SGSharedPtr<Package> PackageRef; | |||
typedef std::vector<Catalog*> CatalogList; | typedef SGSharedPtr<Catalog> CatalogRef; | |||
typedef SGSharedPtr<Install> InstallRef; | ||||
typedef std::vector<PackageRef> PackageList; | ||||
typedef std::vector<CatalogRef> CatalogList; | ||||
class Root | class Root : public SGReferenced | |||
{ | { | |||
public: | public: | |||
Root(const SGPath& aPath, const std::string& aVersion); | Root(const SGPath& aPath, const std::string& aVersion); | |||
virtual ~Root(); | virtual ~Root(); | |||
SGPath path() const; | SGPath path() const; | |||
void setLocale(const std::string& aLocale); | void setLocale(const std::string& aLocale); | |||
void setDelegate(Delegate* aDelegate); | void setDelegate(Delegate* aDelegate); | |||
skipping to change at line 100 | skipping to change at line 107 | |||
* filter consists of required / minimum values, AND-ed together. | * filter consists of required / minimum values, AND-ed together. | |||
*/ | */ | |||
PackageList packagesMatching(const SGPropertyNode* aFilter) const; | PackageList packagesMatching(const SGPropertyNode* aFilter) const; | |||
/** | /** | |||
* retrieve all the packages which are installed | * retrieve all the packages which are installed | |||
* and have a pending update | * and have a pending update | |||
*/ | */ | |||
PackageList packagesNeedingUpdate() const; | PackageList packagesNeedingUpdate() const; | |||
Package* getPackageById(const std::string& aId) const; | PackageRef getPackageById(const std::string& aId) const; | |||
Catalog* getCatalogById(const std::string& aId) const; | CatalogRef getCatalogById(const std::string& aId) const; | |||
void scheduleToUpdate(Install* aInstall); | void scheduleToUpdate(InstallRef aInstall); | |||
private: | private: | |||
friend class Install; | friend class Install; | |||
friend class Catalog; | friend class Catalog; | |||
void catalogRefreshBegin(Catalog* aCat); | void catalogRefreshBegin(CatalogRef aCat); | |||
void catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReaso | void catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aRea | |||
n); | son); | |||
void startNext(Install* aCurrent); | void startNext(InstallRef aCurrent); | |||
void startInstall(Install* aInstall); | void startInstall(InstallRef aInstall); | |||
void installProgress(Install* aInstall, unsigned int aBytes, unsigned i | void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned | |||
nt aTotal); | int aTotal); | |||
void finishInstall(Install* aInstall); | void finishInstall(InstallRef aInstall); | |||
void failedInstall(Install* aInstall, Delegate::FailureCode aReason); | void failedInstall(InstallRef aInstall, Delegate::FailureCode aReason); | |||
class RootPrivate; | class RootPrivate; | |||
std::auto_ptr<RootPrivate> d; | std::auto_ptr<RootPrivate> d; | |||
}; | }; | |||
typedef SGSharedPtr<Root> RootRef; | ||||
} // of namespace pkg | } // of namespace pkg | |||
} // of namespace simgear | } // of namespace simgear | |||
#endif // of SG_PACKAGE_ROOT_HXX | #endif // of SG_PACKAGE_ROOT_HXX | |||
End of changes. 10 change blocks. | ||||
15 lines changed or deleted | 24 lines changed or added | |||
SGBuildingBin.hxx | SGBuildingBin.hxx | |||
---|---|---|---|---|
skipping to change at line 170 | skipping to change at line 170 | |||
}; | }; | |||
// Information for an instance of a building - position and orientation | // Information for an instance of a building - position and orientation | |||
typedef std::vector<BuildingInstance> BuildingInstanceList; | typedef std::vector<BuildingInstance> BuildingInstanceList; | |||
BuildingInstanceList smallBuildingLocations; | BuildingInstanceList smallBuildingLocations; | |||
BuildingInstanceList mediumBuildingLocations; | BuildingInstanceList mediumBuildingLocations; | |||
BuildingInstanceList largeBuildingLocations; | BuildingInstanceList largeBuildingLocations; | |||
public: | public: | |||
SGBuildingBin(const SGMaterial *mat); | SGBuildingBin(const SGMaterial *mat, bool useVBOs); | |||
~SGBuildingBin() { | ~SGBuildingBin() { | |||
smallBuildings.clear(); | smallBuildings.clear(); | |||
mediumBuildings.clear(); | mediumBuildings.clear(); | |||
largeBuildings.clear(); | largeBuildings.clear(); | |||
smallBuildingLocations.clear(); | smallBuildingLocations.clear(); | |||
mediumBuildingLocations.clear(); | mediumBuildingLocations.clear(); | |||
largeBuildingLocations.clear(); | largeBuildingLocations.clear(); | |||
} | } | |||
skipping to change at line 235 | skipping to change at line 235 | |||
float _range; | float _range; | |||
ref_ptr<Effect> _effect; | ref_ptr<Effect> _effect; | |||
bool _fade_out; | bool _fade_out; | |||
}; | }; | |||
struct AddBuildingLeafObject | struct AddBuildingLeafObject | |||
{ | { | |||
Geometry* createNewBuildingGeometryInstance(const BuildingInstance& b uilding) const | Geometry* createNewBuildingGeometryInstance(const BuildingInstance& b uilding) const | |||
{ | { | |||
Geometry* geom = simgear::clone(building.sharedGeometry.get(), Copy Op::SHALLOW_COPY); | Geometry* geom = simgear::clone(building.sharedGeometry.get(), Copy Op::SHALLOW_COPY); | |||
geom->setColorArray(new Vec4Array); | geom->setColorArray(new Vec4Array, Array::BIND_PER_VERTEX); | |||
geom->setColorBinding(Geometry::BIND_PER_VERTEX); | ||||
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS) ); | geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS) ); | |||
return geom; | return geom; | |||
} | } | |||
void operator() (LOD* lod, const BuildingInstance& building) const | void operator() (LOD* lod, const BuildingInstance& building) const | |||
{ | { | |||
Geode* geode = static_cast<Geode*>(lod->getChild(int(building.pos ition.x() * 10.0f) % lod->getNumChildren())); | Geode* geode = static_cast<Geode*>(lod->getChild(int(building.pos ition.x() * 10.0f) % lod->getNumChildren())); | |||
unsigned int numDrawables = geode->getNumDrawables(); | unsigned int numDrawables = geode->getNumDrawables(); | |||
// Get the last geometry of to be added and check if there is spa ce for | // Get the last geometry of to be added and check if there is spa ce for | |||
End of changes. 2 change blocks. | ||||
3 lines changed or deleted | 2 lines changed or added | |||
SGRect.hxx | SGRect.hxx | |||
---|---|---|---|---|
skipping to change at line 37 | skipping to change at line 37 | |||
{ | { | |||
public: | public: | |||
SGRect(): | SGRect(): | |||
_min(SGLimits<T>::max(), SGLimits<T>::max()), | _min(SGLimits<T>::max(), SGLimits<T>::max()), | |||
_max(-SGLimits<T>::max(), -SGLimits<T>::max()) | _max(-SGLimits<T>::max(), -SGLimits<T>::max()) | |||
{ | { | |||
} | } | |||
SGRect(const SGVec2<T>& pt): | explicit SGRect(const SGVec2<T>& pt): | |||
_min(pt), | _min(pt), | |||
_max(pt) | _max(pt) | |||
{ | { | |||
} | } | |||
SGRect(T x, T y): | SGRect(T x, T y): | |||
_min(x, y), | _min(x, y), | |||
_max(x, y) | _max(x, y) | |||
{ | { | |||
skipping to change at line 91 | skipping to change at line 91 | |||
_min.x() = x; | _min.x() = x; | |||
_min.y() = y; | _min.y() = y; | |||
_max.x() = x + w; | _max.x() = x + w; | |||
_max.y() = y + h; | _max.y() = y + h; | |||
} | } | |||
T x() const { return _min.x(); } | T x() const { return _min.x(); } | |||
T y() const { return _min.y(); } | T y() const { return _min.y(); } | |||
T width() const { return _max.x() - _min.x(); } | T width() const { return _max.x() - _min.x(); } | |||
T height() const { return _max.y() - _min.y(); } | T height() const { return _max.y() - _min.y(); } | |||
SGVec2<T> const& pos() const { return _min; } | ||||
SGVec2<T> size() const { return SGVec2<T>(width(), height()); } | ||||
void setX(T x) { T w = width(); _min.x() = x; _max.x() = x + w; } | void setX(T x) { T w = width(); _min.x() = x; _max.x() = x + w; } | |||
void setY(T y) { T h = height(); _min.y() = y; _max.y() = y + h; } | void setY(T y) { T h = height(); _min.y() = y; _max.y() = y + h; } | |||
void setWidth(T w) { _max.x() = _min.x() + w; } | void setWidth(T w) { _max.x() = _min.x() + w; } | |||
void setHeight(T h) { _max.y() = _min.y() + h; } | void setHeight(T h) { _max.y() = _min.y() + h; } | |||
void setPos(const SGVec2<T>& p) { setX(p.x()); setY(p.y()); } | ||||
void setSize(const SGVec2<T>& s) { setWidth(s.x()); setHeight(s.y()); } | ||||
T l() const { return _min.x(); } | T l() const { return _min.x(); } | |||
T r() const { return _max.x(); } | T r() const { return _max.x(); } | |||
T t() const { return _min.y(); } | T t() const { return _min.y(); } | |||
T b() const { return _max.y(); } | T b() const { return _max.y(); } | |||
T& l() { return _min.x(); } | T& l() { return _min.x(); } | |||
T& r() { return _max.x(); } | T& r() { return _max.x(); } | |||
T& t() { return _min.y(); } | T& t() { return _min.y(); } | |||
T& b() { return _max.y(); } | T& b() { return _max.y(); } | |||
void setLeft(T l) { _min.x() = l; } | void setLeft(T l) { _min.x() = l; } | |||
void setRight(T r) { _max.x() = r; } | void setRight(T r) { _max.x() = r; } | |||
void setTop(T t) { _min.y() = t; } | void setTop(T t) { _min.y() = t; } | |||
void setBottom(T b) { _max.y() = b; } | void setBottom(T b) { _max.y() = b; } | |||
/** | /** | |||
* Expand rectangle to include the given position | ||||
*/ | ||||
void expandBy(T x, T y) | ||||
{ | ||||
if( x < _min.x() ) _min.x() = x; | ||||
if( x > _max.x() ) _max.x() = x; | ||||
if( y < _min.y() ) _min.y() = y; | ||||
if( y > _max.y() ) _max.y() = y; | ||||
} | ||||
/** | ||||
* Move rect by vector | * Move rect by vector | |||
*/ | */ | |||
SGRect& operator+=(const SGVec2<T>& offset) | SGRect& operator+=(const SGVec2<T>& offset) | |||
{ | { | |||
_min += offset; | _min += offset; | |||
_max += offset; | _max += offset; | |||
return *this; | return *this; | |||
} | } | |||
/** | /** | |||
* Move rect by vector in inverse direction | * Move rect by vector in inverse direction | |||
*/ | */ | |||
SGRect& operator-=(const SGVec2<T>& offset) | SGRect& operator-=(const SGVec2<T>& offset) | |||
{ | { | |||
_min -= offset; | _min -= offset; | |||
_max -= offset; | _max -= offset; | |||
return *this; | return *this; | |||
} | } | |||
bool operator==(const SGRect<T>& rhs) const | ||||
{ | ||||
return _min == rhs._min | ||||
&& _max == rhs._max; | ||||
} | ||||
bool operator!=(const SGRect<T>& rhs) const | ||||
{ | ||||
return !(*this == rhs); | ||||
} | ||||
bool contains(T x, T y) const | bool contains(T x, T y) const | |||
{ | { | |||
return _min.x() <= x && x <= _max.x() | return _min.x() <= x && x <= _max.x() | |||
&& _min.y() <= y && y <= _max.y(); | && _min.y() <= y && y <= _max.y(); | |||
} | } | |||
bool contains(T x, T y, T margin) const | bool contains(T x, T y, T margin) const | |||
{ | { | |||
return (_min.x() - margin) <= x && x <= (_max.x() + margin) | return (_min.x() - margin) <= x && x <= (_max.x() + margin) | |||
&& (_min.y() - margin) <= y && y <= (_max.y() + margin); | && (_min.y() - margin) <= y && y <= (_max.y() + margin); | |||
skipping to change at line 179 | skipping to change at line 206 | |||
{ | { | |||
return rect -= offset; | return rect -= offset; | |||
} | } | |||
template<typename char_type, typename traits_type, typename T> | template<typename char_type, typename traits_type, typename T> | |||
inline | inline | |||
std::basic_ostream<char_type, traits_type>& | std::basic_ostream<char_type, traits_type>& | |||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGRect<T>& rect) | operator<<(std::basic_ostream<char_type, traits_type>& s, const SGRect<T>& rect) | |||
{ return s << "min = " << rect.getMin() << ", max = " << rect.getMax(); } | { return s << "min = " << rect.getMin() << ", max = " << rect.getMax(); } | |||
typedef SGRect<int> SGRecti; | ||||
typedef SGRect<float> SGRectf; | ||||
typedef SGRect<double> SGRectd; | ||||
#endif /* SG_RECT_HXX_ */ | #endif /* SG_RECT_HXX_ */ | |||
End of changes. 6 change blocks. | ||||
1 lines changed or deleted | 32 lines changed or added | |||
SGReferenced.hxx | SGReferenced.hxx | |||
---|---|---|---|---|
skipping to change at line 29 | skipping to change at line 29 | |||
*/ | */ | |||
#ifndef SGReferenced_HXX | #ifndef SGReferenced_HXX | |||
#define SGReferenced_HXX | #define SGReferenced_HXX | |||
#include "SGAtomic.hxx" | #include "SGAtomic.hxx" | |||
/// Base class for all reference counted SimGear objects | /// Base class for all reference counted SimGear objects | |||
/// Classes derived from this one are meant to be managed with | /// Classes derived from this one are meant to be managed with | |||
/// the SGSharedPtr class. | /// the SGSharedPtr class. | |||
/// For more info see @SGSharedPtr. | /// | |||
/// For more info see SGSharedPtr. For using weak references see | ||||
/// SGWeakReferenced. | ||||
class SGReferenced { | class SGReferenced { | |||
public: | public: | |||
SGReferenced(void) : _refcount(0u) | SGReferenced(void) : _refcount(0u) | |||
{} | {} | |||
/// Do not copy reference counts. Each new object has it's own counter | /// Do not copy reference counts. Each new object has it's own counter | |||
SGReferenced(const SGReferenced&) : _refcount(0u) | SGReferenced(const SGReferenced&) : _refcount(0u) | |||
{} | {} | |||
/// Do not copy reference counts. Each object has it's own counter | /// Do not copy reference counts. Each object has it's own counter | |||
SGReferenced& operator=(const SGReferenced&) | SGReferenced& operator=(const SGReferenced&) | |||
{ return *this; } | { return *this; } | |||
static unsigned get(const SGReferenced* ref) | static unsigned get(const SGReferenced* ref) | |||
{ if (ref) return ++(ref->_refcount); else return ~0u; } | { if (ref) return ++(ref->_refcount); else return 0; } | |||
static unsigned put(const SGReferenced* ref) | static unsigned put(const SGReferenced* ref) | |||
{ if (ref) return --(ref->_refcount); else return ~0u; } | { if (ref) return --(ref->_refcount); else return 0; } | |||
static unsigned count(const SGReferenced* ref) | static unsigned count(const SGReferenced* ref) | |||
{ if (ref) return ref->_refcount; else return ~0u; } | { if (ref) return ref->_refcount; else return 0; } | |||
static bool shared(const SGReferenced* ref) | static bool shared(const SGReferenced* ref) | |||
{ if (ref) return 1u < ref->_refcount; else return false; } | { if (ref) return 1u < ref->_refcount; else return false; } | |||
private: | private: | |||
mutable SGAtomic _refcount; | mutable SGAtomic _refcount; | |||
}; | }; | |||
#endif | #endif | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 6 lines changed or added | |||
SGSharedPtr.hxx | SGSharedPtr.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
* You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | |||
* along with this program; if not, write to the Free Software | * along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | |||
* | * | |||
*/ | */ | |||
#ifndef SGSharedPtr_HXX | #ifndef SGSharedPtr_HXX | |||
#define SGSharedPtr_HXX | #define SGSharedPtr_HXX | |||
#include "SGReferenced.hxx" | #include "SGReferenced.hxx" | |||
#include <algorithm> | ||||
template<typename T> | ||||
class SGWeakPtr; | ||||
/// This class is a pointer proxy doing reference counting on the object | /// This class is a pointer proxy doing reference counting on the object | |||
/// it is pointing to. | /// it is pointing to. | |||
/// The SGSharedPtr class handles reference counting and possible | /// The SGSharedPtr class handles reference counting and possible | |||
/// destruction if no nore references are in use automatically. | /// destruction if no nore references are in use automatically. | |||
/// Classes derived from @SGReferenced can be handled with SGSharedPtr. | /// Classes derived from @SGReferenced can be handled with SGSharedPtr. | |||
/// Once you have a SGSharedPtr available you can use it just like | /// Once you have a SGSharedPtr available you can use it just like | |||
/// a usual pointer with the exception that you don't need to delete it. | /// a usual pointer with the exception that you don't need to delete it. | |||
/// Such a reference is initialized by zero if not initialized with a | /// Such a reference is initialized by zero if not initialized with a | |||
/// class pointer. | /// class pointer. | |||
skipping to change at line 46 | skipping to change at line 50 | |||
/// As long as such a cyclic loop exists the reference count never drops | /// As long as such a cyclic loop exists the reference count never drops | |||
/// to zero and consequently the objects will never be destroyed. | /// to zero and consequently the objects will never be destroyed. | |||
/// Always try to use directed graphs where the references away from the | /// Always try to use directed graphs where the references away from the | |||
/// top node are made with SGSharedPtr's and the back references are done w ith | /// top node are made with SGSharedPtr's and the back references are done w ith | |||
/// ordinary pointers or SGWeakPtr's. | /// ordinary pointers or SGWeakPtr's. | |||
/// There is a very good description of OpenSceneGraphs ref_ptr which is | /// There is a very good description of OpenSceneGraphs ref_ptr which is | |||
/// pretty much the same than this one at | /// pretty much the same than this one at | |||
/// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html | /// http://dburns.dhs.org/OSG/Articles/RefPointers/RefPointers.html | |||
template<typename T> | template<typename T> | |||
class SGWeakPtr; | ||||
template<typename T> | ||||
class SGSharedPtr { | class SGSharedPtr { | |||
public: | public: | |||
typedef T element_type; | typedef T element_type; | |||
SGSharedPtr(void) : _ptr(0) | SGSharedPtr(void) : _ptr(0) | |||
{} | {} | |||
SGSharedPtr(T* ptr) : _ptr(ptr) | SGSharedPtr(T* ptr) : _ptr(ptr) | |||
{ get(_ptr); } | { get(_ptr); } | |||
SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get()) | SGSharedPtr(const SGSharedPtr& p) : _ptr(p.get()) | |||
{ get(_ptr); } | { get(_ptr); } | |||
template<typename U> | template<typename U> | |||
SGSharedPtr(const SGSharedPtr<U>& p) : _ptr(p.get()) | SGSharedPtr(const SGSharedPtr<U>& p) : _ptr(p.get()) | |||
{ get(_ptr); } | { get(_ptr); } | |||
template<typename U> | ||||
explicit SGSharedPtr(const SGWeakPtr<U>& p): _ptr(0) | ||||
{ reset(p.lock().get()); } | ||||
~SGSharedPtr(void) | ~SGSharedPtr(void) | |||
{ put(); } | { reset(); } | |||
SGSharedPtr& operator=(const SGSharedPtr& p) | SGSharedPtr& operator=(const SGSharedPtr& p) | |||
{ assign(p.get()); return *this; } | { reset(p.get()); return *this; } | |||
template<typename U> | template<typename U> | |||
SGSharedPtr& operator=(const SGSharedPtr<U>& p) | SGSharedPtr& operator=(const SGSharedPtr<U>& p) | |||
{ assign(p.get()); return *this; } | { reset(p.get()); return *this; } | |||
template<typename U> | template<typename U> | |||
SGSharedPtr& operator=(U* p) | SGSharedPtr& operator=(U* p) | |||
{ assign(p); return *this; } | { reset(p); return *this; } | |||
T* operator->(void) const | T* operator->(void) const | |||
{ return _ptr; } | { return _ptr; } | |||
T& operator*(void) const | T& operator*(void) const | |||
{ return *_ptr; } | { return *_ptr; } | |||
operator T*(void) const | operator T*(void) const | |||
{ return _ptr; } | { return _ptr; } | |||
T* ptr(void) const | T* ptr(void) const | |||
{ return _ptr; } | { return _ptr; } | |||
T* get(void) const | T* get(void) const | |||
{ return _ptr; } | { return _ptr; } | |||
T* release() | T* release() | |||
{ T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; } | { T* tmp = _ptr; _ptr = 0; T::put(tmp); return tmp; } | |||
void reset() | ||||
{ if (!T::put(_ptr)) delete _ptr; _ptr = 0; } | ||||
void reset(T* p) | ||||
{ SGSharedPtr(p).swap(*this); } | ||||
bool isShared(void) const | bool isShared(void) const | |||
{ return T::shared(_ptr); } | { return T::shared(_ptr); } | |||
unsigned getNumRefs(void) const | unsigned getNumRefs(void) const | |||
{ return T::count(_ptr); } | { return T::count(_ptr); } | |||
bool valid(void) const | bool valid(void) const | |||
{ return _ptr != (T*)0; } | { return _ptr != (T*)0; } | |||
void clear() | void clear() | |||
{ put(); } | { reset(); } | |||
void swap(SGSharedPtr& sharedPtr) | void swap(SGSharedPtr& other) | |||
{ T* tmp = _ptr; _ptr = sharedPtr._ptr; sharedPtr._ptr = tmp; } | { std::swap(_ptr, other._ptr); } | |||
private: | private: | |||
void assign(T* p) | ||||
{ get(p); put(); _ptr = p; } | ||||
void assignNonRef(T* p) | void assignNonRef(T* p) | |||
{ put(); _ptr = p; } | { reset(); _ptr = p; } | |||
void get(const T* p) const | void get(const T* p) const | |||
{ T::get(p); } | { T::get(p); } | |||
void put(void) | ||||
{ if (!T::put(_ptr)) delete _ptr; _ptr = 0; } | ||||
// The reference itself. | // The reference itself. | |||
T* _ptr; | T* _ptr; | |||
template<typename U> | template<typename U> | |||
friend class SGWeakPtr; | friend class SGWeakPtr; | |||
}; | }; | |||
/** | /** | |||
* Support for boost::mem_fn | * Support for boost::mem_fn | |||
End of changes. 12 change blocks. | ||||
15 lines changed or deleted | 19 lines changed or added | |||
SGTexturedTriangleBin.hxx | SGTexturedTriangleBin.hxx | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
#include <osg/Geometry> | #include <osg/Geometry> | |||
#include <osg/PrimitiveSet> | #include <osg/PrimitiveSet> | |||
#include <osg/Texture2D> | #include <osg/Texture2D> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include <simgear/math/sg_random.h> | #include <simgear/math/sg_random.h> | |||
#include <simgear/scene/util/OsgMath.hxx> | #include <simgear/scene/util/OsgMath.hxx> | |||
#include "SGTriangleBin.hxx" | #include "SGTriangleBin.hxx" | |||
struct SGVertNormTex { | struct SGVertNormTex { | |||
SGVertNormTex() | SGVertNormTex() { | |||
{ } | tc_mask = 0; | |||
SGVertNormTex(const SGVec3f& v, const SGVec3f& n, const SGVec2f& t) : | } | |||
vertex(v), normal(n), texCoord(t) | ||||
{ } | ||||
struct less | struct less | |||
{ | { | |||
inline bool tc_is_less ( const SGVertNormTex& l, | ||||
const SGVertNormTex& r, | ||||
int idx ) const | ||||
{ | ||||
if ( r.tc_mask & 1<<idx ) { | ||||
if ( l.tc_mask & 1<<idx ) { | ||||
if (l.texCoord[idx] < r.texCoord[idx]) { | ||||
return true; | ||||
} | ||||
} | ||||
} | ||||
return false; | ||||
}; | ||||
inline bool operator() (const SGVertNormTex& l, | inline bool operator() (const SGVertNormTex& l, | |||
const SGVertNormTex& r) const | const SGVertNormTex& r) const | |||
{ | { | |||
if (l.vertex < r.vertex) return true; | if (l.vertex < r.vertex) return true; | |||
else if (r.vertex < l.vertex) return false; | else if (r.vertex < l.vertex) return false; | |||
else if (l.normal < r.normal) return true; | else if (l.normal < r.normal) return true; | |||
else if (r.normal < l.normal) return false; | else if (r.normal < l.normal) return false; | |||
else return l.texCoord < r.texCoord; | else if ( tc_is_less( l, r, 0 ) ) return true; | |||
else if ( tc_is_less( r, l, 0 ) ) return false; | ||||
else if ( tc_is_less( l, r, 1 ) ) return true; | ||||
else if ( tc_is_less( r, l, 1 ) ) return false; | ||||
else if ( tc_is_less( l, r, 2 ) ) return true; | ||||
else if ( tc_is_less( r, l, 2 ) ) return false; | ||||
else if ( tc_is_less( l, r, 3 ) ) return true; | ||||
else return false; | ||||
} | } | |||
}; | }; | |||
void SetVertex( const SGVec3f& v ) { vertex = v; } | ||||
const SGVec3f& GetVertex( void ) const { return vertex; } | ||||
void SetNormal( const SGVec3f& n ) { normal = n; } | ||||
const SGVec3f& GetNormal( void ) const { return normal; } | ||||
void SetTexCoord( unsigned idx, const SGVec2f& tc ) { | ||||
texCoord[idx] = tc; | ||||
tc_mask |= 1 << idx; | ||||
} | ||||
const SGVec2f& GetTexCoord( unsigned idx ) const { return texCoord[idx]; | ||||
} | ||||
private: | ||||
SGVec3f vertex; | SGVec3f vertex; | |||
SGVec3f normal; | SGVec3f normal; | |||
SGVec2f texCoord; | SGVec2f texCoord[4]; | |||
unsigned tc_mask; | ||||
}; | }; | |||
// Use a DrawElementsUShort if there are few enough vertices, | // Use a DrawElementsUShort if there are few enough vertices, | |||
// otherwise fallback to DrawElementsUInt. Hide the differences | // otherwise fallback to DrawElementsUInt. Hide the differences | |||
// between the two from the rest of the code. | // between the two from the rest of the code. | |||
// | // | |||
// We don't bother with DrawElementsUByte because that is generally | // We don't bother with DrawElementsUByte because that is generally | |||
// not an advantage on modern hardware. | // not an advantage on modern hardware. | |||
class DrawElementsFacade { | class DrawElementsFacade { | |||
public: | public: | |||
skipping to change at line 102 | skipping to change at line 138 | |||
protected: | protected: | |||
osg::DrawElementsUShort* _ushortElements; | osg::DrawElementsUShort* _ushortElements; | |||
osg::DrawElementsUInt* _uintElements; | osg::DrawElementsUInt* _uintElements; | |||
}; | }; | |||
class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> { | class SGTexturedTriangleBin : public SGTriangleBin<SGVertNormTex> { | |||
public: | public: | |||
SGTexturedTriangleBin() | SGTexturedTriangleBin() | |||
{ | { | |||
mt_init(&seed, 123); | mt_init(&seed, 123); | |||
has_sec_tcs = false; | ||||
} | } | |||
// Computes and adds random surface points to the points list. | // Computes and adds random surface points to the points list. | |||
// The random points are computed with a density of (coverage points)/1 | // The random points are computed with a density of (coverage points)/1 | |||
// The points are offsetted away from the triangles in | // The points are offsetted away from the triangles in | |||
// offset * positive normal direction. | // offset * positive normal direction. | |||
void addRandomSurfacePoints(float coverage, float offset, | void addRandomSurfacePoints(float coverage, float offset, | |||
osg::Texture2D* object_mask, | osg::Texture2D* object_mask, | |||
std::vector<SGVec3f>& points) | std::vector<SGVec3f>& points) | |||
{ | { | |||
unsigned num = getNumTriangles(); | unsigned num = getNumTriangles(); | |||
for (unsigned i = 0; i < num; ++i) { | for (unsigned i = 0; i < num; ++i) { | |||
triangle_ref triangleRef = getTriangleRef(i); | triangle_ref triangleRef = getTriangleRef(i); | |||
SGVec3f v0 = getVertex(triangleRef[0]).vertex; | SGVec3f v0 = getVertex(triangleRef[0]).GetVertex(); | |||
SGVec3f v1 = getVertex(triangleRef[1]).vertex; | SGVec3f v1 = getVertex(triangleRef[1]).GetVertex(); | |||
SGVec3f v2 = getVertex(triangleRef[2]).vertex; | SGVec3f v2 = getVertex(triangleRef[2]).GetVertex(); | |||
SGVec2f t0 = getVertex(triangleRef[0]).texCoord; | SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0); | |||
SGVec2f t1 = getVertex(triangleRef[1]).texCoord; | SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0); | |||
SGVec2f t2 = getVertex(triangleRef[2]).texCoord; | SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0); | |||
SGVec3f normal = cross(v1 - v0, v2 - v0); | SGVec3f normal = cross(v1 - v0, v2 - v0); | |||
// Compute the area | // Compute the area | |||
float area = 0.5f*length(normal); | float area = 0.5f*length(normal); | |||
if (area <= SGLimitsf::min()) | if (area <= SGLimitsf::min()) | |||
continue; | continue; | |||
// For partial units of area, use a zombie door method to | // For partial units of area, use a zombie door method to | |||
// create the proper random chance of a light being created | // create the proper random chance of a light being created | |||
// for this triangle | // for this triangle | |||
skipping to change at line 181 | skipping to change at line 218 | |||
void addRandomTreePoints(float wood_coverage, | void addRandomTreePoints(float wood_coverage, | |||
osg::Texture2D* object_mask, | osg::Texture2D* object_mask, | |||
float vegetation_density, | float vegetation_density, | |||
float cos_max_density_angle, | float cos_max_density_angle, | |||
float cos_zero_density_angle, | float cos_zero_density_angle, | |||
std::vector<SGVec3f>& points) | std::vector<SGVec3f>& points) | |||
{ | { | |||
unsigned num = getNumTriangles(); | unsigned num = getNumTriangles(); | |||
for (unsigned i = 0; i < num; ++i) { | for (unsigned i = 0; i < num; ++i) { | |||
triangle_ref triangleRef = getTriangleRef(i); | triangle_ref triangleRef = getTriangleRef(i); | |||
SGVec3f v0 = getVertex(triangleRef[0]).vertex; | SGVec3f v0 = getVertex(triangleRef[0]).GetVertex(); | |||
SGVec3f v1 = getVertex(triangleRef[1]).vertex; | SGVec3f v1 = getVertex(triangleRef[1]).GetVertex(); | |||
SGVec3f v2 = getVertex(triangleRef[2]).vertex; | SGVec3f v2 = getVertex(triangleRef[2]).GetVertex(); | |||
SGVec2f t0 = getVertex(triangleRef[0]).texCoord; | SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0); | |||
SGVec2f t1 = getVertex(triangleRef[1]).texCoord; | SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0); | |||
SGVec2f t2 = getVertex(triangleRef[2]).texCoord; | SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0); | |||
SGVec3f normal = cross(v1 - v0, v2 - v0); | SGVec3f normal = cross(v1 - v0, v2 - v0); | |||
// Ensure the slope isn't too steep by checking the | // Ensure the slope isn't too steep by checking the | |||
// cos of the angle between the slope normal and the | // cos of the angle between the slope normal and the | |||
// vertical (conveniently the z-component of the normalized | // vertical (conveniently the z-component of the normalized | |||
// normal) and values passed in. | // normal) and values passed in. | |||
float alpha = normalize(normal).z(); | float alpha = normalize(normal).z(); | |||
float slope_density = 1.0; | float slope_density = 1.0; | |||
if (alpha < cos_zero_density_angle) | if (alpha < cos_zero_density_angle) | |||
skipping to change at line 258 | skipping to change at line 295 | |||
} | } | |||
void addRandomPoints(double coverage, | void addRandomPoints(double coverage, | |||
double spacing, | double spacing, | |||
osg::Texture2D* object_mask, | osg::Texture2D* object_mask, | |||
std::vector<std::pair<SGVec3f, float> >& points) | std::vector<std::pair<SGVec3f, float> >& points) | |||
{ | { | |||
unsigned num = getNumTriangles(); | unsigned num = getNumTriangles(); | |||
for (unsigned i = 0; i < num; ++i) { | for (unsigned i = 0; i < num; ++i) { | |||
triangle_ref triangleRef = getTriangleRef(i); | triangle_ref triangleRef = getTriangleRef(i); | |||
SGVec3f v0 = getVertex(triangleRef[0]).vertex; | SGVec3f v0 = getVertex(triangleRef[0]).GetVertex(); | |||
SGVec3f v1 = getVertex(triangleRef[1]).vertex; | SGVec3f v1 = getVertex(triangleRef[1]).GetVertex(); | |||
SGVec3f v2 = getVertex(triangleRef[2]).vertex; | SGVec3f v2 = getVertex(triangleRef[2]).GetVertex(); | |||
SGVec2f t0 = getVertex(triangleRef[0]).texCoord; | SGVec2f t0 = getVertex(triangleRef[0]).GetTexCoord(0); | |||
SGVec2f t1 = getVertex(triangleRef[1]).texCoord; | SGVec2f t1 = getVertex(triangleRef[1]).GetTexCoord(0); | |||
SGVec2f t2 = getVertex(triangleRef[2]).texCoord; | SGVec2f t2 = getVertex(triangleRef[2]).GetTexCoord(0); | |||
SGVec3f normal = cross(v1 - v0, v2 - v0); | SGVec3f normal = cross(v1 - v0, v2 - v0); | |||
// Compute the area | // Compute the area | |||
float area = 0.5f*length(normal); | float area = 0.5f*length(normal); | |||
if (area <= SGLimitsf::min()) | if (area <= SGLimitsf::min()) | |||
continue; | continue; | |||
// for partial units of area, use a zombie door method to | // for partial units of area, use a zombie door method to | |||
// create the proper random chance of an object being created | // create the proper random chance of an object being created | |||
// for this triangle. | // for this triangle. | |||
skipping to change at line 316 | skipping to change at line 353 | |||
} | } | |||
} else { | } else { | |||
points.push_back(std::make_pair(randomPoint, static_cast<float> (mt_rand(&seed)))); | points.push_back(std::make_pair(randomPoint, static_cast<float> (mt_rand(&seed)))); | |||
} | } | |||
} | } | |||
num -= 1.0; | num -= 1.0; | |||
} | } | |||
} | } | |||
} | } | |||
osg::Geometry* buildGeometry(const TriangleVector& triangles) const | osg::Geometry* buildGeometry(const TriangleVector& triangles, bool useVBO s) const | |||
{ | { | |||
// Do not build anything if there is nothing in here ... | // Do not build anything if there is nothing in here ... | |||
if (empty() || triangles.empty()) | if (empty() || triangles.empty()) | |||
return 0; | return 0; | |||
// FIXME: do not include all values here ... | // FIXME: do not include all values here ... | |||
osg::Vec3Array* vertices = new osg::Vec3Array; | osg::Vec3Array* vertices = new osg::Vec3Array; | |||
osg::Vec3Array* normals = new osg::Vec3Array; | osg::Vec3Array* normals = new osg::Vec3Array; | |||
osg::Vec2Array* texCoords = new osg::Vec2Array; | osg::Vec2Array* priTexCoords = new osg::Vec2Array; | |||
osg::Vec2Array* secTexCoords = new osg::Vec2Array; | ||||
osg::Vec4Array* colors = new osg::Vec4Array; | osg::Vec4Array* colors = new osg::Vec4Array; | |||
colors->push_back(osg::Vec4(1, 1, 1, 1)); | colors->push_back(osg::Vec4(1, 1, 1, 1)); | |||
osg::Geometry* geometry = new osg::Geometry; | osg::Geometry* geometry = new osg::Geometry; | |||
if (useVBOs) { | ||||
geometry->setUseDisplayList(false); | ||||
geometry->setUseVertexBufferObjects(true); | ||||
} | ||||
geometry->setDataVariance(osg::Object::STATIC); | geometry->setDataVariance(osg::Object::STATIC); | |||
geometry->setVertexArray(vertices); | geometry->setVertexArray(vertices); | |||
geometry->setNormalArray(normals); | geometry->setNormalArray(normals); | |||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); | geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); | |||
geometry->setColorArray(colors); | geometry->setColorArray(colors); | |||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL); | geometry->setColorBinding(osg::Geometry::BIND_OVERALL); | |||
geometry->setTexCoordArray(0, texCoords); | if ( has_sec_tcs ) { | |||
geometry->setTexCoordArray(0, priTexCoords); | ||||
geometry->setTexCoordArray(1, secTexCoords); | ||||
} else { | ||||
geometry->setTexCoordArray(0, priTexCoords); | ||||
} | ||||
const unsigned invalid = ~unsigned(0); | const unsigned invalid = ~unsigned(0); | |||
std::vector<unsigned> indexMap(getNumVertices(), invalid); | std::vector<unsigned> indexMap(getNumVertices(), invalid); | |||
DrawElementsFacade deFacade(vertices->size()); | DrawElementsFacade deFacade(vertices->size()); | |||
for (index_type i = 0; i < triangles.size(); ++i) { | for (index_type i = 0; i < triangles.size(); ++i) { | |||
triangle_ref triangle = triangles[i]; | triangle_ref triangle = triangles[i]; | |||
if (indexMap[triangle[0]] == invalid) { | if (indexMap[triangle[0]] == invalid) { | |||
indexMap[triangle[0]] = vertices->size(); | indexMap[triangle[0]] = vertices->size(); | |||
vertices->push_back(toOsg(getVertex(triangle[0]).vertex)); | vertices->push_back(toOsg(getVertex(triangle[0]).GetVertex())); | |||
normals->push_back(toOsg(getVertex(triangle[0]).normal)); | normals->push_back(toOsg(getVertex(triangle[0]).GetNormal())); | |||
texCoords->push_back(toOsg(getVertex(triangle[0]).texCoord)); | priTexCoords->push_back(toOsg(getVertex(triangle[0]).GetTexCoord(0) | |||
)); | ||||
if ( has_sec_tcs ) { | ||||
secTexCoords->push_back(toOsg(getVertex(triangle[0]).GetTexCoor | ||||
d(1))); | ||||
} | ||||
} | } | |||
deFacade.push_back(indexMap[triangle[0]]); | deFacade.push_back(indexMap[triangle[0]]); | |||
if (indexMap[triangle[1]] == invalid) { | if (indexMap[triangle[1]] == invalid) { | |||
indexMap[triangle[1]] = vertices->size(); | indexMap[triangle[1]] = vertices->size(); | |||
vertices->push_back(toOsg(getVertex(triangle[1]).vertex)); | vertices->push_back(toOsg(getVertex(triangle[1]).GetVertex())); | |||
normals->push_back(toOsg(getVertex(triangle[1]).normal)); | normals->push_back(toOsg(getVertex(triangle[1]).GetNormal())); | |||
texCoords->push_back(toOsg(getVertex(triangle[1]).texCoord)); | priTexCoords->push_back(toOsg(getVertex(triangle[1]).GetTexCoord(0) | |||
)); | ||||
if ( has_sec_tcs ) { | ||||
secTexCoords->push_back(toOsg(getVertex(triangle[1]).GetTexCoor | ||||
d(1))); | ||||
} | ||||
} | } | |||
deFacade.push_back(indexMap[triangle[1]]); | deFacade.push_back(indexMap[triangle[1]]); | |||
if (indexMap[triangle[2]] == invalid) { | if (indexMap[triangle[2]] == invalid) { | |||
indexMap[triangle[2]] = vertices->size(); | indexMap[triangle[2]] = vertices->size(); | |||
vertices->push_back(toOsg(getVertex(triangle[2]).vertex)); | vertices->push_back(toOsg(getVertex(triangle[2]).GetVertex())); | |||
normals->push_back(toOsg(getVertex(triangle[2]).normal)); | normals->push_back(toOsg(getVertex(triangle[2]).GetNormal())); | |||
texCoords->push_back(toOsg(getVertex(triangle[2]).texCoord)); | priTexCoords->push_back(toOsg(getVertex(triangle[2]).GetTexCoord(0) | |||
)); | ||||
if ( has_sec_tcs ) { | ||||
secTexCoords->push_back(toOsg(getVertex(triangle[2]).GetTexCoor | ||||
d(1))); | ||||
} | ||||
} | } | |||
deFacade.push_back(indexMap[triangle[2]]); | deFacade.push_back(indexMap[triangle[2]]); | |||
} | } | |||
geometry->addPrimitiveSet(deFacade.getDrawElements()); | geometry->addPrimitiveSet(deFacade.getDrawElements()); | |||
return geometry; | return geometry; | |||
} | } | |||
osg::Geometry* buildGeometry() const | osg::Geometry* buildGeometry(bool useVBOs) const | |||
{ return buildGeometry(getTriangles()); } | { return buildGeometry(getTriangles(), useVBOs); } | |||
int getTextureIndex() const | int getTextureIndex() const | |||
{ | { | |||
if (empty() || getNumTriangles() == 0) | if (empty() || getNumTriangles() == 0) | |||
return 0; | return 0; | |||
triangle_ref triangleRef = getTriangleRef(0); | triangle_ref triangleRef = getTriangleRef(0); | |||
SGVec3f v0 = getVertex(triangleRef[0]).vertex; | SGVec3f v0 = getVertex(triangleRef[0]).GetVertex(); | |||
return floor(v0.x()); | return floor(v0.x()); | |||
} | } | |||
void hasSecondaryTexCoord( bool sec_tc ) { has_sec_tcs = sec_tc; } | ||||
private: | private: | |||
// Random seed for the triangle. | // Random seed for the triangle. | |||
mt seed; | mt seed; | |||
// does the triangle array have secondary texture coordinates | ||||
bool has_sec_tcs; | ||||
}; | }; | |||
#endif | #endif | |||
End of changes. 20 change blocks. | ||||
40 lines changed or deleted | 109 lines changed or added | |||
SGTriangle.hxx | SGTriangle.hxx | |||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU General Public License | // You should have received a copy of the GNU General Public License | |||
// along with this program; if not, write to the Free Software | // along with this program; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | |||
// | // | |||
#ifndef SGTriangle_H | #ifndef SGTriangle_H | |||
#define SGTrianlge_H | #define SGTriangle_H | |||
template<typename T> | template<typename T> | |||
class SGTriangle { | class SGTriangle { | |||
public: | public: | |||
SGTriangle() | SGTriangle() | |||
{ } | { } | |||
SGTriangle(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2) | SGTriangle(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2) | |||
{ set(v0, v1, v2); } | { set(v0, v1, v2); } | |||
SGTriangle(const SGVec3<T> v[3]) | SGTriangle(const SGVec3<T> v[3]) | |||
{ set(v); } | { set(v); } | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
SGWeakPtr.hxx | SGWeakPtr.hxx | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// You should have received a copy of the GNU General Public License | // You should have received a copy of the GNU General Public License | |||
// along with this program; if not, write to the Free Software | // along with this program; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | |||
// | // | |||
#ifndef SGWeakPtr_HXX | #ifndef SGWeakPtr_HXX | |||
#define SGWeakPtr_HXX | #define SGWeakPtr_HXX | |||
#include "SGWeakReferenced.hxx" | #include "SGWeakReferenced.hxx" | |||
/** | ||||
* Class for handling weak references to classes derived from SGWeakReferen | ||||
ced | ||||
* or SGVirtualWeakReferenced. | ||||
*/ | ||||
template<typename T> | template<typename T> | |||
class SGWeakPtr { | class SGWeakPtr { | |||
public: | public: | |||
typedef T element_type; | ||||
SGWeakPtr(void) | SGWeakPtr(void) | |||
{ } | { } | |||
SGWeakPtr(const SGWeakPtr& p) : mWeakData(p.mWeakData) | SGWeakPtr(const SGWeakPtr& p) : mWeakData(p.mWeakData) | |||
{ } | { } | |||
SGWeakPtr(T* ptr) | SGWeakPtr(T* ptr) | |||
{ assign(ptr); } | { assign(ptr); } | |||
template<typename U> | template<typename U> | |||
SGWeakPtr(const SGSharedPtr<U>& p) | SGWeakPtr(const SGSharedPtr<U>& p) | |||
{ SGSharedPtr<T> sharedPtr = p; assign(sharedPtr.get()); } | { assign(p.get()); } | |||
template<typename U> | template<typename U> | |||
SGWeakPtr(const SGWeakPtr<U>& p) | SGWeakPtr(const SGWeakPtr<U>& p) | |||
{ SGSharedPtr<T> sharedPtr = p.lock(); assign(sharedPtr.get()); } | { SGSharedPtr<T> sharedPtr = p.lock(); assign(sharedPtr.get()); } | |||
~SGWeakPtr(void) | ~SGWeakPtr(void) | |||
{ } | { } | |||
template<typename U> | template<typename U> | |||
SGWeakPtr& operator=(const SGSharedPtr<U>& p) | SGWeakPtr& operator=(const SGSharedPtr<U>& p) | |||
{ SGSharedPtr<T> sharedPtr = p; assign(sharedPtr.get()); return *this; } | { assign(p.get()); return *this; } | |||
template<typename U> | template<typename U> | |||
SGWeakPtr& operator=(const SGWeakPtr<U>& p) | SGWeakPtr& operator=(const SGWeakPtr<U>& p) | |||
{ SGSharedPtr<T> sharedPtr = p.lock(); assign(sharedPtr.get()); return *t his; } | { SGSharedPtr<T> sharedPtr = p.lock(); assign(sharedPtr.get()); return *t his; } | |||
SGWeakPtr& operator=(const SGWeakPtr& p) | SGWeakPtr& operator=(const SGWeakPtr& p) | |||
{ mWeakData = p.mWeakData; return *this; } | { mWeakData = p.mWeakData; return *this; } | |||
template<typename U> | ||||
bool operator==(const SGWeakPtr<U>& rhs) const | ||||
{ return mWeakData == rhs.mWeakData; } | ||||
template<typename U> | ||||
bool operator!=(const SGWeakPtr<U>& rhs) const | ||||
{ return mWeakData != rhs.mWeakData; } | ||||
template<typename U> | ||||
bool operator<(const SGWeakPtr<U>& rhs) const | ||||
{ return mWeakData < rhs.mWeakData; } | ||||
SGSharedPtr<T> lock(void) const | SGSharedPtr<T> lock(void) const | |||
{ | { | |||
if (!mWeakData) | if (!mWeakData) | |||
return SGSharedPtr<T>(); | return SGSharedPtr<T>(); | |||
SGSharedPtr<T> sharedPtr; | SGSharedPtr<T> sharedPtr; | |||
sharedPtr.assignNonRef(mWeakData->getPointer<T>()); | sharedPtr.assignNonRef(mWeakData->getPointer<T>()); | |||
return sharedPtr; | return sharedPtr; | |||
} | } | |||
bool expired() const | ||||
{ return !mWeakData || mWeakData->mRefcount == 0; } | ||||
void reset() | ||||
{ mWeakData.reset(); } | ||||
void clear() | void clear() | |||
{ mWeakData = 0; } | { mWeakData.reset(); } | |||
void swap(SGWeakPtr& weakPtr) | void swap(SGWeakPtr& weakPtr) | |||
{ mWeakData.swap(weakPtr.mWeakData); } | { mWeakData.swap(weakPtr.mWeakData); } | |||
private: | private: | |||
void assign(T* p) | void assign(T* p) | |||
{ | { | |||
if (p) | if (p) | |||
mWeakData = p->mWeakData; | mWeakData = p->mWeakData; | |||
else | else | |||
mWeakData = 0; | mWeakData = 0; | |||
End of changes. 7 change blocks. | ||||
3 lines changed or deleted | 25 lines changed or added | |||
SGWeakReferenced.hxx | SGWeakReferenced.hxx | |||
---|---|---|---|---|
skipping to change at line 24 | skipping to change at line 24 | |||
// along with this program; if not, write to the Free Software | // along with this program; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130 1, USA. | |||
// | // | |||
#ifndef SGWeakReferenced_HXX | #ifndef SGWeakReferenced_HXX | |||
#define SGWeakReferenced_HXX | #define SGWeakReferenced_HXX | |||
#include "SGReferenced.hxx" | #include "SGReferenced.hxx" | |||
#include "SGSharedPtr.hxx" | #include "SGSharedPtr.hxx" | |||
#include <boost/type_traits/is_base_of.hpp> | ||||
#include <boost/utility/enable_if.hpp> | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
# pragma warning(push) | # pragma warning(push) | |||
// C4355: 'this' : used in base member initializer list | // C4355: 'this' : used in base member initializer list | |||
// Tell MSVC we know what we do and really want to do it this way. | // Tell MSVC we know what we do and really want to do it this way. | |||
# pragma warning(disable: 4355) | # pragma warning(disable: 4355) | |||
#endif | #endif | |||
template<typename T> | template<typename T> | |||
class SGWeakPtr; | class SGWeakPtr; | |||
class SGVirtualWeakReferenced; | ||||
/** | ||||
* Base class for all reference counted SimGear objects supporting weak | ||||
* references, not incrementing the reference count. | ||||
* | ||||
* Classes derived from this one are meant to be managed with the SGSharedP | ||||
tr | ||||
* and SGWeakPtr classes. | ||||
* | ||||
* If the class hierarchy contains virtual base classes use | ||||
* SGVirtualWeakReferenced instead. | ||||
*/ | ||||
class SGWeakReferenced { | class SGWeakReferenced { | |||
public: | public: | |||
/// The object backref and the reference count for this object need to be | /// The object backref and the reference count for this object need to be | |||
/// there in any case. Also these are per object and shall not be copied nor | /// there in any case. Also these are per object and shall not be copied nor | |||
/// assigned. | /// assigned. | |||
/// The reference count for this object is stored in a secondary object t hat | /// The reference count for this object is stored in a secondary object t hat | |||
/// is shared with all weak pointers to this current object. This way we | /// is shared with all weak pointers to this current object. This way we | |||
/// have an atomic decision using the reference count of this current obj ect | /// have an atomic decision using the reference count of this current obj ect | |||
/// if the backref is still valid. At the time where the atomic count is | /// if the backref is still valid. At the time where the atomic count is | |||
/// equal to zero the object is considered dead. | /// equal to zero the object is considered dead. | |||
skipping to change at line 60 | skipping to change at line 74 | |||
~SGWeakReferenced(void) | ~SGWeakReferenced(void) | |||
{ mWeakData->mWeakReferenced = 0; } | { mWeakData->mWeakReferenced = 0; } | |||
/// Do not copy the weak backward references ... | /// Do not copy the weak backward references ... | |||
SGWeakReferenced& operator=(const SGWeakReferenced&) | SGWeakReferenced& operator=(const SGWeakReferenced&) | |||
{ return *this; } | { return *this; } | |||
/// The usual operations on weak pointers. | /// The usual operations on weak pointers. | |||
/// The interface should stay the same then what we have in Referenced. | /// The interface should stay the same then what we have in Referenced. | |||
static unsigned get(const SGWeakReferenced* ref) | static unsigned get(const SGWeakReferenced* ref) | |||
{ if (ref) return ++(ref->mWeakData->mRefcount); else return 0u; } | { if (ref) return ++(ref->mWeakData->mRefcount); else return 0; } | |||
static unsigned put(const SGWeakReferenced* ref) | static unsigned put(const SGWeakReferenced* ref) | |||
{ if (ref) return --(ref->mWeakData->mRefcount); else return ~0u; } | { if (ref) return --(ref->mWeakData->mRefcount); else return 0; } | |||
static unsigned count(const SGWeakReferenced* ref) | static unsigned count(const SGWeakReferenced* ref) | |||
{ if (ref) return ref->mWeakData->mRefcount; else return 0u; } | { if (ref) return ref->mWeakData->mRefcount; else return 0; } | |||
private: | private: | |||
/// Support for weak references, not increasing the reference count | /// Support for weak references, not increasing the reference count | |||
/// that is done through that small helper class which holds an uncounted | /// that is done through that small helper class which holds an uncounted | |||
/// reference which is zeroed out on destruction of the current object | /// reference which is zeroed out on destruction of the current object | |||
class WeakData : public SGReferenced { | class WeakData : public SGReferenced { | |||
public: | public: | |||
WeakData(SGWeakReferenced* weakReferenced) : | WeakData(SGWeakReferenced* weakReferenced) : | |||
mRefcount(0u), | mRefcount(0u), | |||
mWeakReferenced(weakReferenced) | mWeakReferenced(weakReferenced) | |||
skipping to change at line 92 | skipping to change at line 106 | |||
// need to check that value and try to do an atomic test and set. If this | // need to check that value and try to do an atomic test and set. If this | |||
// fails, try again. The usual lockless algorithm ... | // fails, try again. The usual lockless algorithm ... | |||
unsigned count; | unsigned count; | |||
do { | do { | |||
count = mRefcount; | count = mRefcount; | |||
if (count == 0) | if (count == 0) | |||
return 0; | return 0; | |||
} while (!mRefcount.compareAndExchange(count, count + 1)); | } while (!mRefcount.compareAndExchange(count, count + 1)); | |||
// We know that as long as the refcount is not zero, the pointer stil l | // We know that as long as the refcount is not zero, the pointer stil l | |||
// points to valid data. So it is safe to work on it. | // points to valid data. So it is safe to work on it. | |||
return static_cast<T*>(mWeakReferenced); | return up_cast<T>(mWeakReferenced); | |||
} | } | |||
SGAtomic mRefcount; | SGAtomic mRefcount; | |||
SGWeakReferenced* mWeakReferenced; | SGWeakReferenced* mWeakReferenced; | |||
private: | private: | |||
WeakData(void); | WeakData(void); | |||
WeakData(const WeakData&); | WeakData(const WeakData&); | |||
WeakData& operator=(const WeakData&); | WeakData& operator=(const WeakData&); | |||
/// Upcast in a class hierarchy with a virtual base class | ||||
template<class T> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::is_base_of<SGVirtualWeakReferenced, T>, | ||||
T* | ||||
>::type | ||||
up_cast(SGWeakReferenced* ptr); | ||||
/// Upcast in a non-virtual class hierarchy | ||||
template<class T> | ||||
static | ||||
typename boost::disable_if< | ||||
boost::is_base_of<SGVirtualWeakReferenced, T>, | ||||
T* | ||||
>::type | ||||
up_cast(SGWeakReferenced* ptr) | ||||
{ | ||||
return static_cast<T*>(ptr); | ||||
} | ||||
}; | }; | |||
SGSharedPtr<WeakData> mWeakData; | SGSharedPtr<WeakData> mWeakData; | |||
template<typename T> | template<typename T> | |||
friend class SGWeakPtr; | friend class SGWeakPtr; | |||
}; | }; | |||
/** | ||||
* Base class for all reference counted SimGear objects with virtual base | ||||
* classes, supporting weak references. | ||||
* | ||||
* Classes derived from this one are meant to be managed with the SGSharedP | ||||
tr | ||||
* and SGWeakPtr classes. | ||||
* | ||||
* @code{cpp} | ||||
* | ||||
* class Base1: | ||||
* public virtual SGVirtualWeakReferenced | ||||
* {}; | ||||
* | ||||
* class Base2: | ||||
* public virtual SGVirtualWeakReferenced | ||||
* {}; | ||||
* | ||||
* class Derived: | ||||
* public Base1, | ||||
* public Base2 | ||||
* {}; | ||||
* | ||||
* SGSharedPtr<Derived> ptr( new Derived() ); | ||||
* SGWeakPtr<Derived> weak_ptr( ptr ); | ||||
* SGSharedPtr<Base1> ptr1( weak_ptr.lock() ); | ||||
* SGSharedPtr<Base2> ptr2( weak_ptr.lock() ); | ||||
* | ||||
* @endcode | ||||
*/ | ||||
class SGVirtualWeakReferenced: | ||||
public SGWeakReferenced | ||||
{ | ||||
public: | ||||
virtual ~SGVirtualWeakReferenced() {} | ||||
}; | ||||
/// Upcast in a class hierarchy with a virtual base class | ||||
// We (clang) need the definition of SGVirtualWeakReferenced for the static | ||||
_cast | ||||
template<class T> | ||||
typename boost::enable_if< | ||||
boost::is_base_of<SGVirtualWeakReferenced, T>, | ||||
T* | ||||
>::type | ||||
SGWeakReferenced::WeakData::up_cast(SGWeakReferenced* ptr) | ||||
{ | ||||
// First get the virtual base class, which then can be used to further | ||||
// upcast. | ||||
return dynamic_cast<T*>(static_cast<SGVirtualWeakReferenced*>(ptr)); | ||||
} | ||||
#ifdef _MSC_VER | #ifdef _MSC_VER | |||
# pragma warning(pop) | # pragma warning(pop) | |||
#endif | #endif | |||
#endif | #endif | |||
End of changes. 9 change blocks. | ||||
4 lines changed or deleted | 92 lines changed or added | |||
animation.hxx | animation.hxx | |||
---|---|---|---|---|
skipping to change at line 71 | skipping to change at line 71 | |||
/** | /** | |||
* Read a 3d vector from the configuration property node. | * Read a 3d vector from the configuration property node. | |||
* | * | |||
* Reads values from @a name/[xyz]@a prefix and defaults to the according | * Reads values from @a name/[xyz]@a prefix and defaults to the according | |||
* value of @a def for each value which is not set. | * value of @a def for each value which is not set. | |||
* | * | |||
* @param name Name of the root node containing all coordinates | * @param name Name of the root node containing all coordinates | |||
* @param suffix Suffix appended to each child node (x,y,z) | * @param suffix Suffix appended to each child node (x,y,z) | |||
* @param def Vector containing default values | * @param def Vector containing default values | |||
*/ | */ | |||
SGVec3d readVec3( const SGPropertyNode& cfg, | ||||
const std::string& name, | ||||
const std::string& suffix = "", | ||||
const SGVec3d& def = SGVec3d::zeros() ) const; | ||||
SGVec3d readVec3( const std::string& name, | SGVec3d readVec3( const std::string& name, | |||
const std::string& suffix = "", | const std::string& suffix = "", | |||
const SGVec3d& def = SGVec3d::zeros() ) const; | const SGVec3d& def = SGVec3d::zeros() ) const; | |||
void readRotationCenterAndAxis(SGVec3d& center, SGVec3d& axis) const; | void readRotationCenterAndAxis(SGVec3d& center, SGVec3d& axis) const; | |||
SGExpressiond* readOffsetValue(const char* tag_name) const; | SGExpressiond* readOffsetValue(const char* tag_name) const; | |||
void removeMode(osg::Node& node, osg::StateAttribute::GLMode mode); | void removeMode(osg::Node& node, osg::StateAttribute::GLMode mode); | |||
void removeAttribute(osg::Node& node, osg::StateAttribute::Type type); | void removeAttribute(osg::Node& node, osg::StateAttribute::Type type); | |||
void removeTextureMode(osg::Node& node, unsigned unit, | void removeTextureMode(osg::Node& node, unsigned unit, | |||
osg::StateAttribute::GLMode mode); | osg::StateAttribute::GLMode mode); | |||
void removeTextureAttribute(osg::Node& node, unsigned unit, | void removeTextureAttribute(osg::Node& node, unsigned unit, | |||
osg::StateAttribute::Type type); | osg::StateAttribute::Type type); | |||
skipping to change at line 311 | skipping to change at line 317 | |||
class SGTexTransformAnimation : public SGAnimation { | class SGTexTransformAnimation : public SGAnimation { | |||
public: | public: | |||
SGTexTransformAnimation(const SGPropertyNode* configNode, | SGTexTransformAnimation(const SGPropertyNode* configNode, | |||
SGPropertyNode* modelRoot); | SGPropertyNode* modelRoot); | |||
virtual osg::Group* createAnimationGroup(osg::Group& parent); | virtual osg::Group* createAnimationGroup(osg::Group& parent); | |||
private: | private: | |||
class Transform; | class Transform; | |||
class Translation; | class Translation; | |||
class Rotation; | class Rotation; | |||
class Trapezoid; | ||||
class UpdateCallback; | class UpdateCallback; | |||
void appendTexTranslate(const SGPropertyNode* config, | ||||
UpdateCallback* updateCallback); | SGExpressiond* readValue( const SGPropertyNode& cfg, | |||
void appendTexRotate(const SGPropertyNode* config, | const std::string& suffix = "" ); | |||
UpdateCallback* updateCallback); | ||||
void appendTexTranslate( const SGPropertyNode& cfg, | ||||
UpdateCallback* updateCallback); | ||||
void appendTexRotate( const SGPropertyNode& cfg, | ||||
UpdateCallback* updateCallback); | ||||
void appendTexTrapezoid( const SGPropertyNode& cfg, | ||||
UpdateCallback* updateCallback); | ||||
}; | }; | |||
////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | |||
// Shader animation | // Shader animation | |||
////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | |||
class SGShaderAnimation : public SGAnimation { | class SGShaderAnimation : public SGAnimation { | |||
public: | public: | |||
SGShaderAnimation(const SGPropertyNode* configNode, | SGShaderAnimation(const SGPropertyNode* configNode, | |||
SGPropertyNode* modelRoot, | SGPropertyNode* modelRoot, | |||
End of changes. 4 change blocks. | ||||
4 lines changed or deleted | 17 lines changed or added | |||
canvas_fwd.hxx | canvas_fwd.hxx | |||
---|---|---|---|---|
skipping to change at line 42 | skipping to change at line 42 | |||
#include <map> | #include <map> | |||
#include <vector> | #include <vector> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
namespace canvas | namespace canvas | |||
{ | { | |||
#define SG_FWD_DECL(name)\ | #define SG_FWD_DECL(name)\ | |||
class name;\ | class name;\ | |||
typedef boost::shared_ptr<name> name##Ptr;\ | typedef SGSharedPtr<name> name##Ptr;\ | |||
typedef boost::weak_ptr<name> name##WeakPtr; | typedef SGWeakPtr<name> name##WeakPtr; | |||
SG_FWD_DECL(Canvas) | SG_FWD_DECL(Canvas) | |||
SG_FWD_DECL(Element) | SG_FWD_DECL(Element) | |||
SG_FWD_DECL(Group) | SG_FWD_DECL(Group) | |||
SG_FWD_DECL(Image) | SG_FWD_DECL(Image) | |||
SG_FWD_DECL(Map) | SG_FWD_DECL(Map) | |||
SG_FWD_DECL(Path) | SG_FWD_DECL(Path) | |||
SG_FWD_DECL(Text) | SG_FWD_DECL(Text) | |||
SG_FWD_DECL(Window) | ||||
SG_FWD_DECL(Event) | SG_FWD_DECL(Event) | |||
SG_FWD_DECL(CustomEvent) | ||||
SG_FWD_DECL(MouseEvent) | SG_FWD_DECL(MouseEvent) | |||
#undef SG_FWD_DECL | ||||
#define SG_FWD_DECL(name)\ | ||||
class name;\ | ||||
typedef boost::shared_ptr<name> name##Ptr;\ | ||||
typedef boost::weak_ptr<name> name##WeakPtr; | ||||
SG_FWD_DECL(Placement) | SG_FWD_DECL(Placement) | |||
SG_FWD_DECL(SystemAdapter) | SG_FWD_DECL(SystemAdapter) | |||
#undef SG_FWD_DECL | #undef SG_FWD_DECL | |||
class EventManager; | class EventManager; | |||
class EventVisitor; | class EventVisitor; | |||
struct EventTarget; | ||||
typedef std::deque<EventTarget> EventPropagationPath; | ||||
typedef std::map<std::string, const SGPropertyNode*> Style; | typedef std::map<std::string, const SGPropertyNode*> Style; | |||
typedef ElementPtr (*ElementFactory)( const CanvasWeakPtr&, | typedef ElementPtr (*ElementFactory)( const CanvasWeakPtr&, | |||
const SGPropertyNode_ptr&, | const SGPropertyNode_ptr&, | |||
const Style&, | const Style&, | |||
Element* ); | Element* ); | |||
typedef osg::ref_ptr<osgText::Font> FontPtr; | typedef osg::ref_ptr<osgText::Font> FontPtr; | |||
typedef std::vector<PlacementPtr> Placements; | typedef std::vector<PlacementPtr> Placements; | |||
typedef boost::function<Placements( SGPropertyNode*, | typedef boost::function<Placements( SGPropertyNode*, | |||
End of changes. 5 change blocks. | ||||
2 lines changed or deleted | 15 lines changed or added | |||
cloud.hxx | cloud.hxx | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
#ifndef _SG_CLOUD_HXX_ | #ifndef _SG_CLOUD_HXX_ | |||
#define _SG_CLOUD_HXX_ | #define _SG_CLOUD_HXX_ | |||
#include <simgear/compiler.h> | #include <simgear/compiler.h> | |||
#include <simgear/misc/sg_path.hxx> | #include <simgear/misc/sg_path.hxx> | |||
#include <simgear/math/SGMath.hxx> | #include <simgear/math/SGMath.hxx> | |||
#include <simgear/structure/SGReferenced.hxx> | #include <simgear/structure/SGReferenced.hxx> | |||
#include <string> | #include <string> | |||
using std::string; | ||||
#include <osg/ref_ptr> | #include <osg/ref_ptr> | |||
#include <osg/Array> | #include <osg/Array> | |||
#include <osg/Geode> | #include <osg/Geode> | |||
#include <osg/Group> | #include <osg/Group> | |||
#include <osg/MatrixTransform> | #include <osg/MatrixTransform> | |||
#include <osg/Switch> | #include <osg/Switch> | |||
class SGCloudField; | class SGCloudField; | |||
skipping to change at line 76 | skipping to change at line 75 | |||
static const std::string SG_CLOUD_BROKEN_STRING; // "broken" | static const std::string SG_CLOUD_BROKEN_STRING; // "broken" | |||
static const std::string SG_CLOUD_SCATTERED_STRING; // "scattered" | static const std::string SG_CLOUD_SCATTERED_STRING; // "scattered" | |||
static const std::string SG_CLOUD_FEW_STRING; // "few" | static const std::string SG_CLOUD_FEW_STRING; // "few" | |||
static const std::string SG_CLOUD_CIRRUS_STRING; // "cirrus" | static const std::string SG_CLOUD_CIRRUS_STRING; // "cirrus" | |||
static const std::string SG_CLOUD_CLEAR_STRING; // "clear" | static const std::string SG_CLOUD_CLEAR_STRING; // "clear" | |||
/** | /** | |||
* Constructor | * Constructor | |||
* @param tex_path the path to the set of cloud textures | * @param tex_path the path to the set of cloud textures | |||
*/ | */ | |||
SGCloudLayer( const string &tex_path ); | SGCloudLayer( const std::string &tex_path ); | |||
/** | /** | |||
* Destructor | * Destructor | |||
*/ | */ | |||
~SGCloudLayer( void ); | ~SGCloudLayer( void ); | |||
/** get the cloud span (in meters) */ | /** get the cloud span (in meters) */ | |||
float getSpan_m () const; | float getSpan_m () const; | |||
/** | /** | |||
* set the cloud span | * set the cloud span | |||
skipping to change at line 141 | skipping to change at line 140 | |||
/** get coverage type */ | /** get coverage type */ | |||
Coverage getCoverage () const; | Coverage getCoverage () const; | |||
/** | /** | |||
* set coverage type | * set coverage type | |||
* @param coverage the coverage type | * @param coverage the coverage type | |||
*/ | */ | |||
void setCoverage (Coverage coverage); | void setCoverage (Coverage coverage); | |||
/** get coverage as string */ | /** get coverage as string */ | |||
const string & getCoverageString() const; | const std::string & getCoverageString() const; | |||
/** get coverage as string */ | /** get coverage as string */ | |||
static const string & getCoverageString( Coverage coverage ); | static const std::string & getCoverageString( Coverage coverage ); | |||
/** get coverage type from string */ | /** get coverage type from string */ | |||
static Coverage getCoverageType( const std::string & coverage ); | static Coverage getCoverageType( const std::string & coverage ); | |||
/** set coverage as string */ | /** set coverage as string */ | |||
void setCoverageString( const string & coverage ); | void setCoverageString( const std::string & coverage ); | |||
/** | /** | |||
* set the cloud movement direction | * set the cloud movement direction | |||
* @param dir the cloud movement direction | * @param dir the cloud movement direction | |||
*/ | */ | |||
inline void setDirection(float dir) { | inline void setDirection(float dir) { | |||
// cout << "cloud dir = " << dir << endl; | // cout << "cloud dir = " << dir << endl; | |||
direction = dir; | direction = dir; | |||
} | } | |||
End of changes. 5 change blocks. | ||||
5 lines changed or deleted | 4 lines changed or added | |||
condition.hxx | condition.hxx | |||
---|---|---|---|---|
skipping to change at line 40 | skipping to change at line 40 | |||
*/ | */ | |||
class SGCondition : public SGReferenced | class SGCondition : public SGReferenced | |||
{ | { | |||
public: | public: | |||
SGCondition (); | SGCondition (); | |||
virtual ~SGCondition (); | virtual ~SGCondition (); | |||
virtual bool test () const = 0; | virtual bool test () const = 0; | |||
virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const { } | virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const { } | |||
}; | }; | |||
typedef SGSharedPtr<SGCondition> SGConditionRef; | ||||
/** | /** | |||
* Base class for a conditional components. | * Base class for a conditional components. | |||
* | * | |||
* This class manages the conditions and tests; the component should | * This class manages the conditions and tests; the component should | |||
* invoke the test() method whenever it needs to decide whether to | * invoke the test() method whenever it needs to decide whether to | |||
* active itself, draw itself, and so on. | * active itself, draw itself, and so on. | |||
*/ | */ | |||
class SGConditional : public SGReferenced | class SGConditional : public SGReferenced | |||
{ | { | |||
public: | public: | |||
SGConditional (); | SGConditional (); | |||
virtual ~SGConditional (); | virtual ~SGConditional (); | |||
// transfer pointer ownership | // transfer pointer ownership | |||
virtual void setCondition (SGCondition * condition); | virtual void setCondition (SGCondition * condition); | |||
virtual const SGCondition * getCondition () const { return _condition; } | virtual const SGCondition * getCondition () const { return _condition; } | |||
virtual bool test () const; | virtual bool test () const; | |||
private: | private: | |||
SGSharedPtr<SGCondition> _condition; | SGConditionRef _condition; | |||
}; | }; | |||
/** | /** | |||
* Global function to make a condition out of properties. | * Global function to make a condition out of properties. | |||
* | * | |||
* The top-level is always an implicit 'and' group, whatever the | * The top-level is always an implicit 'and' group, whatever the | |||
* node's name (it should usually be "condition"). | * node's name (it should usually be "condition"). | |||
* | * | |||
* @param node The top-level condition node (usually named "condition"). | * @param node The top-level condition node (usually named "condition"). | |||
* @return A pointer to a newly-allocated condition; it is the | * @return A pointer to a newly-allocated condition; it is the | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 3 lines changed or added | |||
debug_types.h | debug_types.h | |||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
SG_CLIPPER = 0x00002000, | SG_CLIPPER = 0x00002000, | |||
SG_NETWORK = 0x00004000, | SG_NETWORK = 0x00004000, | |||
SG_ATC = 0x00008000, | SG_ATC = 0x00008000, | |||
SG_NASAL = 0x00010000, | SG_NASAL = 0x00010000, | |||
SG_INSTR = 0x00020000, | SG_INSTR = 0x00020000, | |||
SG_SYSTEMS = 0x00040000, | SG_SYSTEMS = 0x00040000, | |||
SG_AI = 0x00080000, | SG_AI = 0x00080000, | |||
SG_ENVIRONMENT = 0x00100000, | SG_ENVIRONMENT = 0x00100000, | |||
SG_SOUND = 0x00200000, | SG_SOUND = 0x00200000, | |||
SG_NAVAID = 0x00400000, | SG_NAVAID = 0x00400000, | |||
SG_UNDEFD = 0x00800000, // For range checking | SG_GUI = 0x00800000, | |||
SG_UNDEFD = 0x01000000, // For range checking | ||||
SG_ALL = 0xFFFFFFFF | SG_ALL = 0xFFFFFFFF | |||
} sgDebugClass; | } sgDebugClass; | |||
/** | /** | |||
* Define the possible logging priorities (and their order). | * Define the possible logging priorities (and their order). | |||
*/ | */ | |||
typedef enum { | typedef enum { | |||
SG_BULK = 1, // For frequent messages | SG_BULK = 1, // For frequent messages | |||
SG_DEBUG, // Less frequent debug type messages | SG_DEBUG, // Less frequent debug type messages | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
event_mgr.hxx | event_mgr.hxx | |||
---|---|---|---|---|
skipping to change at line 75 | skipping to change at line 75 | |||
int _numEntries; | int _numEntries; | |||
int _tableSize; | int _tableSize; | |||
}; | }; | |||
class SGEventMgr : public SGSubsystem | class SGEventMgr : public SGSubsystem | |||
{ | { | |||
public: | public: | |||
SGEventMgr(); | SGEventMgr(); | |||
~SGEventMgr(); | ~SGEventMgr(); | |||
virtual void init() {} | virtual void init(); | |||
virtual void update(double delta_time_sec); | virtual void update(double delta_time_sec); | |||
virtual void unbind(); | virtual void unbind(); | |||
virtual void shutdown(); | virtual void shutdown(); | |||
void setRealtimeProperty(SGPropertyNode* node) { _rtProp = node; } | void setRealtimeProperty(SGPropertyNode* node) { _rtProp = node; } | |||
/** | /** | |||
* Add a single function callback event as a repeating task. | * Add a single function callback event as a repeating task. | |||
* ex: addTask("foo", &Function ... ) | * ex: addTask("foo", &Function ... ) | |||
*/ | */ | |||
skipping to change at line 132 | skipping to change at line 132 | |||
friend class SGTimer; | friend class SGTimer; | |||
void add(const std::string& name, SGCallback* cb, | void add(const std::string& name, SGCallback* cb, | |||
double interval, double delay, | double interval, double delay, | |||
bool repeat, bool simtime); | bool repeat, bool simtime); | |||
SGPropertyNode_ptr _freezeProp; | SGPropertyNode_ptr _freezeProp; | |||
SGPropertyNode_ptr _rtProp; | SGPropertyNode_ptr _rtProp; | |||
SGTimerQueue _rtQueue; | SGTimerQueue _rtQueue; | |||
SGTimerQueue _simQueue; | SGTimerQueue _simQueue; | |||
bool _inited; | ||||
}; | }; | |||
#endif // _SG_EVENT_MGR_HXX | #endif // _SG_EVENT_MGR_HXX | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 2 lines changed or added | |||
from_nasal.hxx | from_nasal.hxx | |||
---|---|---|---|---|
skipping to change at line 66 | skipping to change at line 66 | |||
< typename boost::remove_reference<Var>::type | < typename boost::remove_reference<Var>::type | |||
>::type return_type; | >::type return_type; | |||
typedef return_type(*type)(naContext, naRef); | typedef return_type(*type)(naContext, naRef); | |||
static type get() | static type get() | |||
{ | { | |||
return &from_nasal<return_type>; | return &from_nasal<return_type>; | |||
} | } | |||
}; | }; | |||
template<class T> | ||||
T get_member(naContext c, naRef obj, const std::string& name) | ||||
{ | ||||
naRef out; | ||||
if( !naMember_get(c, obj, to_nasal(c, name), &out) ) | ||||
return T(); | ||||
return from_nasal<T>(c, out); | ||||
} | ||||
} // namespace nasal | } // namespace nasal | |||
#endif /* SG_FROM_NASAL_HXX_ */ | #endif /* SG_FROM_NASAL_HXX_ */ | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 10 lines changed or added | |||
from_nasal_function_templates.hxx | from_nasal_function_templates.hxx | |||
---|---|---|---|---|
#ifndef SG_FROM_NASAL_HELPER_HXX_ | #ifndef SG_FROM_NASAL_HELPER_HXX_ | |||
# error Nasal cppbind - do not include this file! | # error Nasal cppbind - do not include this file! | |||
#endif | #endif | |||
#ifndef SG_DONT_DO_ANYTHING | ||||
#define n BOOST_PP_ITERATION() | #define n BOOST_PP_ITERATION() | |||
#ifndef SG_BOOST_FUNCTION_FROM_NASAL_FWD | #ifndef SG_BOOST_FUNCTION_FROM_NASAL_FWD | |||
# define SG_CALL_TRAITS_PARAM(z, n, dummy)\ | # define SG_CALL_TRAITS_PARAM(z, n, dummy)\ | |||
typename boost::call_traits<A##n>::param_type a##n | typename boost::call_traits<A##n>::param_type a##n | |||
# define SG_CALL_ARG(z, n, dummy)\ | # define SG_CALL_ARG(z, n, dummy)\ | |||
to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n) | to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n) | |||
template< | template< | |||
class Ret | class Ret | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | |||
BOOST_PP_ENUM_PARAMS(n, class A) | ||||
> | > | |||
typename boost::disable_if<boost::is_void<Ret>, Ret>::type | typename boost::disable_if<boost::is_void<Ret>, Ret>::type | |||
callNasalFunction( const ObjectHolder* holder | callNasalMethod( const ObjectHolder<SGReferenced>* holder, | |||
BOOST_PP_COMMA_IF(n) | Me self | |||
BOOST_PP_ENUM(n, SG_CALL_TRAITS_PARAM, 0) | BOOST_PP_ENUM_TRAILING(n, SG_CALL_TRAITS_PARAM, 0) ) | |||
) | ||||
{ | { | |||
naContext ctx = naNewContext(); | naContext ctx = naNewContext(); | |||
naRef args[] = { | #if n | |||
naRef args[n] = { | ||||
BOOST_PP_ENUM(n, SG_CALL_ARG, 0) | BOOST_PP_ENUM(n, SG_CALL_ARG, 0) | |||
}; | }; | |||
const int num_args = sizeof(args)/sizeof(args[0]); | #else | |||
naRef* args = NULL; | ||||
#endif | ||||
naRef result = | naRef result = | |||
naCallMethod(holder->get_naRef(), naNil(), num_args, args, naNil()); | naCallMethodCtx(ctx, holder->get_naRef(), self, n, args, naNil()); | |||
const char* error = naGetError(ctx); | ||||
std::string error_str(error ? error : ""); | ||||
Ret r = Ret(); | ||||
if( !error ) | ||||
r = from_nasal_helper(ctx, result, static_cast<Ret*>(0)); | ||||
Ret r = from_nasal_helper(ctx, result, static_cast<Ret*>(0)); | ||||
naFreeContext(ctx); | naFreeContext(ctx); | |||
if( error ) | ||||
throw std::runtime_error(error_str); | ||||
return r; | return r; | |||
} | } | |||
template< | template< | |||
class Ret | class Ret | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | |||
BOOST_PP_ENUM_PARAMS(n, class A) | ||||
> | > | |||
typename boost::enable_if<boost::is_void<Ret>, Ret>::type | typename boost::enable_if<boost::is_void<Ret>, Ret>::type | |||
callNasalFunction( const ObjectHolder* holder | callNasalMethod( const ObjectHolder<SGReferenced>* holder, | |||
BOOST_PP_COMMA_IF(n) | Me self | |||
BOOST_PP_ENUM(n, SG_CALL_TRAITS_PARAM, 0) | BOOST_PP_ENUM_TRAILING(n, SG_CALL_TRAITS_PARAM, 0) ) | |||
) | ||||
{ | { | |||
naContext ctx = naNewContext(); | callNasalMethod< | |||
naRef args[] = { | naRef // do not do any conversion and just ignore the return value | |||
BOOST_PP_ENUM(n, SG_CALL_ARG, 0) | // TODO warn if something different to nil is returned? | |||
}; | BOOST_PP_COMMA_IF(n) | |||
const int num_args = sizeof(args)/sizeof(args[0]); | BOOST_PP_ENUM_PARAMS(n, A) | |||
> | ||||
naCallMethod(holder->get_naRef(), naNil(), num_args, args, naNil()); | ( | |||
naFreeContext(ctx); | holder, | |||
self | ||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, a) | ||||
); | ||||
} | } | |||
# undef SG_CALL_TRAITS_PARAM | # undef SG_CALL_TRAITS_PARAM | |||
# undef SG_CALL_ARG | # undef SG_CALL_ARG | |||
#endif | #endif | |||
template< | template< | |||
class Ret | class Ret | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | |||
BOOST_PP_ENUM_PARAMS(n, class A) | ||||
> | > | |||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))> | typename boost::disable_if< | |||
// free function if first argument is not nasal::Me or no argument at a | ||||
ll | ||||
boost::is_same<BOOST_PP_IF(n, A0, void), Me>, | ||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))> | ||||
>::type | ||||
boostFunctionFromNasal(naRef code, Ret (*)(BOOST_PP_ENUM_PARAMS(n, A))) | boostFunctionFromNasal(naRef code, Ret (*)(BOOST_PP_ENUM_PARAMS(n, A))) | |||
#ifdef SG_BOOST_FUNCTION_FROM_NASAL_FWD | #ifdef SG_BOOST_FUNCTION_FROM_NASAL_FWD | |||
; | ; | |||
#else | #else | |||
{ | { | |||
return boost::bind | return boost::bind | |||
( | ( | |||
&callNasalFunction<Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, A | &callNasalMethod<Ret BOOST_PP_ENUM_TRAILING_PARAMS(n, A)>, | |||
)>, | ObjectHolder<SGReferenced>::makeShared(code), | |||
ObjectHolder::makeShared(code) | boost::bind(naNil) | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_COMMA_IF(n) | |||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(n), _) | BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(n), _) | |||
); | ); | |||
} | } | |||
#endif | #endif | |||
#if n > 0 | ||||
template< | ||||
class Ret | ||||
BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | ||||
> | ||||
typename boost::enable_if< | ||||
// method if type of first argument is nasal::Me | ||||
boost::is_same<A0, Me>, | ||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, A))> | ||||
>::type | ||||
boostFunctionFromNasal(naRef code, Ret (*)(BOOST_PP_ENUM_PARAMS(n, A))) | ||||
#ifdef SG_BOOST_FUNCTION_FROM_NASAL_FWD | ||||
; | ||||
#else | ||||
{ | ||||
return boost::bind | ||||
( | ||||
&callNasalMethod< | ||||
Ret | ||||
BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) | ||||
BOOST_PP_ENUM_SHIFTED_PARAMS(n, A) | ||||
>, | ||||
ObjectHolder<SGReferenced>::makeShared(code), | ||||
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(n), _) | ||||
); | ||||
} | ||||
#endif | ||||
#endif | ||||
#undef n | #undef n | |||
#endif // SG_DONT_DO_ANYTHING | ||||
End of changes. 16 change blocks. | ||||
30 lines changed or deleted | 75 lines changed or added | |||
from_nasal_helper.hxx | from_nasal_helper.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_FROM_NASAL_HELPER_HXX_ | #ifndef SG_FROM_NASAL_HELPER_HXX_ | |||
#define SG_FROM_NASAL_HELPER_HXX_ | #define SG_FROM_NASAL_HELPER_HXX_ | |||
#include "nasal_traits.hxx" | #include "nasal_traits.hxx" | |||
#include <simgear/math/SGMath.hxx> | ||||
#include <simgear/math/SGRect.hxx> | ||||
#include <simgear/nasal/nasal.h> | #include <simgear/nasal/nasal.h> | |||
#include <simgear/nasal/cppbind/NasalObjectHolder.hxx> | #include <simgear/nasal/cppbind/NasalObjectHolder.hxx> | |||
#include <simgear/nasal/cppbind/to_nasal.hxx> | #include <simgear/nasal/cppbind/to_nasal.hxx> | |||
#include <simgear/structure/exception.hxx> | #include <simgear/structure/exception.hxx> | |||
#include <simgear/structure/SGSharedPtr.hxx> | #include <simgear/structure/SGSharedPtr.hxx> | |||
#include <boost/bind.hpp> | #include <boost/bind.hpp> | |||
#include <boost/call_traits.hpp> | #include <boost/call_traits.hpp> | |||
#include <boost/function.hpp> | #include <boost/function.hpp> | |||
#include <boost/preprocessor/control/if.hpp> | ||||
#include <boost/preprocessor/iteration/iterate.hpp> | #include <boost/preprocessor/iteration/iterate.hpp> | |||
#include <boost/preprocessor/repetition/enum_trailing.hpp> | ||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp> | ||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp> | #include <boost/preprocessor/repetition/enum_shifted_params.hpp> | |||
#include <boost/type_traits.hpp> | #include <boost/type_traits.hpp> | |||
#include <boost/utility/enable_if.hpp> | #include <boost/utility/enable_if.hpp> | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
class SGPath; | class SGPath; | |||
namespace nasal | namespace nasal | |||
skipping to change at line 75 | skipping to change at line 80 | |||
*/ | */ | |||
explicit bad_nasal_cast(const std::string& msg); | explicit bad_nasal_cast(const std::string& msg); | |||
virtual ~bad_nasal_cast() throw(); | virtual ~bad_nasal_cast() throw(); | |||
protected: | protected: | |||
std::string _msg; | std::string _msg; | |||
}; | }; | |||
/** | /** | |||
* Wrap a naRef to indicate it references the self/me object in Nasal met | ||||
hod | ||||
* calls. | ||||
*/ | ||||
struct Me | ||||
{ | ||||
naRef _ref; | ||||
Me(naRef ref): | ||||
_ref(ref) | ||||
{} | ||||
operator naRef() { return _ref; } | ||||
}; | ||||
/** | ||||
* Simple pass through for unified handling also of naRef. | * Simple pass through for unified handling also of naRef. | |||
*/ | */ | |||
inline naRef from_nasal_helper(naContext, naRef ref, const naRef*) | inline naRef from_nasal_helper(naContext, naRef ref, const naRef*) | |||
{ return ref; } | { return ref; } | |||
/** | /** | |||
* Convert Nasal string to std::string | * Convert Nasal string to std::string | |||
*/ | */ | |||
std::string from_nasal_helper(naContext c, naRef ref, const std::string*) ; | std::string from_nasal_helper(naContext c, naRef ref, const std::string*) ; | |||
skipping to change at line 127 | skipping to change at line 147 | |||
/** | /** | |||
* Convert a Nasal function to a boost::function with the given signature . | * Convert a Nasal function to a boost::function with the given signature . | |||
* | * | |||
* @tparam Sig Signature of returned function (arguments and return va lue | * @tparam Sig Signature of returned function (arguments and return va lue | |||
* are automatically converted using from_nasal/to_nasal) | * are automatically converted using from_nasal/to_nasal) | |||
*/ | */ | |||
template<class Sig> | template<class Sig> | |||
boost::function<Sig> | boost::function<Sig> | |||
from_nasal_helper(naContext c, naRef ref, boost::function<Sig>*) | from_nasal_helper(naContext c, naRef ref, boost::function<Sig>*) | |||
{ | { | |||
if( naIsNil(ref) ) | ||||
return boost::function<Sig>(); | ||||
if( !naIsCode(ref) | if( !naIsCode(ref) | |||
&& !naIsCCode(ref) | && !naIsCCode(ref) | |||
&& !naIsFunc(ref) ) | && !naIsFunc(ref) ) | |||
throw bad_nasal_cast("not a function"); | throw bad_nasal_cast("not a function"); | |||
return detail::boostFunctionFromNasal(ref, static_cast<Sig*>(0)); | return detail::boostFunctionFromNasal(ref, static_cast<Sig*>(0)); | |||
} | } | |||
template<class Sig> | template<class Sig> | |||
typename boost::enable_if< boost::is_function<Sig>, | typename boost::enable_if< boost::is_function<Sig>, | |||
skipping to change at line 193 | skipping to change at line 216 | |||
typename boost::enable_if<is_vec2<Vec2>, Vec2>::type | typename boost::enable_if<is_vec2<Vec2>, Vec2>::type | |||
from_nasal_helper(naContext c, naRef ref, const Vec2*) | from_nasal_helper(naContext c, naRef ref, const Vec2*) | |||
{ | { | |||
std::vector<double> vec = | std::vector<double> vec = | |||
from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0)); | from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0)); | |||
if( vec.size() != 2 ) | if( vec.size() != 2 ) | |||
throw bad_nasal_cast("Expected vector with two elements"); | throw bad_nasal_cast("Expected vector with two elements"); | |||
return Vec2(vec[0], vec[1]); | return Vec2(vec[0], vec[1]); | |||
} | } | |||
/** | ||||
* Convert a Nasal vector with 4 elements ([x, y, w, h]) to an SGRect | ||||
*/ | ||||
template<class T> | ||||
SGRect<T> from_nasal_helper(naContext c, naRef ref, const SGRect<T>*) | ||||
{ | ||||
std::vector<double> vec = | ||||
from_nasal_helper(c, ref, static_cast<std::vector<double>*>(0)); | ||||
if( vec.size() != 4 ) | ||||
throw bad_nasal_cast("Expected vector with four elements"); | ||||
return SGRect<T>(vec[0], vec[1], vec[2], vec[3]); | ||||
} | ||||
// Helpers for wrapping calls to Nasal functions into boost::function | // Helpers for wrapping calls to Nasal functions into boost::function | |||
namespace detail | namespace detail | |||
{ | { | |||
#define BOOST_PP_ITERATION_LIMITS (0, 9) | // Dummy include to add a build dependency on this file for gcc/CMake/e | |||
tc. | ||||
#define SG_DONT_DO_ANYTHING | ||||
# include <simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx> | ||||
#undef SG_DONT_DO_ANYTHING | ||||
// Now the actual include (we are limited to 8 arguments (+me) here bec | ||||
ause | ||||
// boost::bind has an upper limit of 9) | ||||
#define BOOST_PP_ITERATION_LIMITS (0, 8) | ||||
#define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/from_nasal_functi on_templates.hxx> | #define BOOST_PP_FILENAME_1 <simgear/nasal/cppbind/detail/from_nasal_functi on_templates.hxx> | |||
#include BOOST_PP_ITERATE() | #include BOOST_PP_ITERATE() | |||
} | } | |||
} // namespace nasal | } // namespace nasal | |||
#endif /* SG_FROM_NASAL_HELPER_HXX_ */ | #endif /* SG_FROM_NASAL_HELPER_HXX_ */ | |||
End of changes. 7 change blocks. | ||||
1 lines changed or deleted | 48 lines changed or added | |||
functor_templates.hxx | functor_templates.hxx | |||
---|---|---|---|---|
#ifndef SG_NASAL_GHOST_HXX_ | #ifndef SG_NASAL_GHOST_HXX_ | |||
# error Nasal cppbind - do not include this file! | # error Nasal cppbind - do not include this file! | |||
#endif | #endif | |||
#ifndef SG_DONT_DO_ANYTHING | ||||
#define n BOOST_PP_ITERATION() | #define n BOOST_PP_ITERATION() | |||
#define SG_GHOST_FUNC_TYPE\ | #define SG_GHOST_FUNC_TYPE\ | |||
boost::function<Ret (raw_type& BOOST_PP_COMMA_IF(n)BOOST_PP_ENUM_PARAMS(n ,A))> | boost::function<Ret (raw_type& BOOST_PP_ENUM_TRAILING_PARAMS(n,A))> | |||
/** | /** | |||
* Bind any callable entity accepting an instance of raw_type and an arbi trary | * Bind any callable entity accepting an instance of raw_type and an arbi trary | |||
* number of arguments as method. | * number of arguments as method. | |||
*/ | */ | |||
template< | template< | |||
class Ret | class Ret | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | |||
BOOST_PP_ENUM_PARAMS(n, class A) | ||||
> | > | |||
Ghost& method(const std::string& name, const SG_GHOST_FUNC_TYPE& func) | Ghost& method(const std::string& name, const SG_GHOST_FUNC_TYPE& func) | |||
{ | { | |||
#if defined(SG_GCC_VERSION) && SG_GCC_VERSION < 40407 | #if defined(SG_GCC_VERSION) && SG_GCC_VERSION < 40407 | |||
// The old version of g++ used on Jenkins (16.11.2012) only compiles th is | // The old version of g++ used on Jenkins (16.11.2012) only compiles th is | |||
// version. | // version. | |||
# define SG_GHOST_REQUIRE_ARG(z, n, dummy)\ | # define SG_GHOST_REQUIRE_ARG(z, n, dummy)\ | |||
boost::bind(&arg_from_nasal<A##n>, _2, n) | boost::bind(&arg_from_nasal<A##n>, _2, n) | |||
#else | #else | |||
// VS (2008, 2010, ... ?) only allow this version. | // VS (2008, 2010, ... ?) only allow this version. | |||
skipping to change at line 39 | skipping to change at line 39 | |||
boost::bind(&Ghost::arg_from_nasal<A##n>, _2, n) | boost::bind(&Ghost::arg_from_nasal<A##n>, _2, n) | |||
#endif | #endif | |||
return method<Ret> | return method<Ret> | |||
( | ( | |||
name, | name, | |||
typename boost::function<Ret (raw_type&, const CallContext&)> | typename boost::function<Ret (raw_type&, const CallContext&)> | |||
( boost::bind( | ( boost::bind( | |||
func, | func, | |||
_1 | _1 | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING(n, SG_GHOST_REQUIRE_ARG, 0) | |||
BOOST_PP_ENUM(n, SG_GHOST_REQUIRE_ARG, 0) | ||||
)) | )) | |||
); | ); | |||
#undef SG_GHOST_REQUIRE_ARG | #undef SG_GHOST_REQUIRE_ARG | |||
} | } | |||
#define SG_GHOST_MEM_FN(cv)\ | #define SG_GHOST_MEM_FN(cv)\ | |||
/**\ | /**\ | |||
* Bind a member function with an arbitrary number of arguments as method .\ | * Bind a member function with an arbitrary number of arguments as method .\ | |||
*/\ | */\ | |||
template<\ | template<\ | |||
class Ret\ | class Ret\ | |||
BOOST_PP_COMMA_IF(n)\ | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)\ | |||
BOOST_PP_ENUM_PARAMS(n, class A)\ | ||||
>\ | >\ | |||
Ghost& method\ | Ghost& method\ | |||
(\ | (\ | |||
const std::string& name,\ | const std::string& name,\ | |||
Ret (raw_type::*fn)(BOOST_PP_ENUM_PARAMS(n,A)) cv\ | Ret (raw_type::*fn)(BOOST_PP_ENUM_PARAMS(n,A)) cv\ | |||
)\ | )\ | |||
{\ | {\ | |||
return method<\ | return method<\ | |||
Ret\ | Ret\ | |||
BOOST_PP_COMMA_IF(n)\ | BOOST_PP_ENUM_TRAILING_PARAMS(n,A)\ | |||
BOOST_PP_ENUM_PARAMS(n,A)\ | ||||
>(name, SG_GHOST_FUNC_TYPE(fn));\ | >(name, SG_GHOST_FUNC_TYPE(fn));\ | |||
} | } | |||
// Work around MSVC warning C4003: not enough actual parameters for macro | // Work around MSVC warning C4003: not enough actual parameters for macro | |||
// We really do not want to pass a parameter, even if MSVC can not believe it. | // We really do not want to pass a parameter, even if MSVC can not believe it. | |||
#define SG_GHOST_NO_CV | #define SG_GHOST_NO_CV | |||
SG_GHOST_MEM_FN(const) | SG_GHOST_MEM_FN(const) | |||
SG_GHOST_MEM_FN(SG_GHOST_NO_CV) | SG_GHOST_MEM_FN(SG_GHOST_NO_CV) | |||
#undef SG_GHOST_MEM_FN | #undef SG_GHOST_MEM_FN | |||
#undef SG_GHOST_NO_CV | #undef SG_GHOST_NO_CV | |||
/** | /** | |||
* Bind free function accepting an instance of raw_type and an arbitrary | * Bind free function accepting an instance of raw_type and an arbitrary | |||
* number of arguments as method. | * number of arguments as method. | |||
*/ | */ | |||
template< | template< | |||
class Ret, | class Ret, | |||
class Type | class Type | |||
BOOST_PP_COMMA_IF(n) | BOOST_PP_ENUM_TRAILING_PARAMS(n, class A) | |||
BOOST_PP_ENUM_PARAMS(n, class A) | ||||
> | > | |||
Ghost& method | Ghost& method | |||
( | ( | |||
const std::string& name, | const std::string& name, | |||
Ret (*fn)(Type BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,A)) | Ret (*fn)(Type BOOST_PP_ENUM_TRAILING_PARAMS(n,A)) | |||
) | ) | |||
{ | { | |||
BOOST_STATIC_ASSERT | BOOST_STATIC_ASSERT | |||
(( boost::is_convertible<raw_type&, Type>::value | (( boost::is_convertible<raw_type&, Type>::value | |||
//|| boost::is_convertible<raw_type*, Type>::value | //|| boost::is_convertible<raw_type*, Type>::value | |||
// TODO check how to do it with pointer... | // TODO check how to do it with pointer... | |||
)); | )); | |||
return method<Ret>(name, SG_GHOST_FUNC_TYPE(fn)); | return method<Ret>(name, SG_GHOST_FUNC_TYPE(fn)); | |||
} | } | |||
#undef n | #undef n | |||
#undef SG_GHOST_TYPEDEF_FUNC_TYPE | #undef SG_GHOST_TYPEDEF_FUNC_TYPE | |||
#endif // SG_DONT_DO_ANYTHING | ||||
End of changes. 9 change blocks. | ||||
12 lines changed or deleted | 8 lines changed or added | |||
map.hxx | map.hxx | |||
---|---|---|---|---|
skipping to change at line 36 | skipping to change at line 36 | |||
{ | { | |||
template<class Key, class Value> | template<class Key, class Value> | |||
class Map: | class Map: | |||
public std::map<Key, Value> | public std::map<Key, Value> | |||
{ | { | |||
public: | public: | |||
Map() {} | Map() {} | |||
/** | /** | |||
* Initilize a new mape with the given key/value pair. | * Initialize a new map with the given key/value pair. | |||
*/ | */ | |||
Map(const Key& key, const Value& value) | Map(const Key& key, const Value& value) | |||
{ | { | |||
(*this)[key] = value; | (*this)[key] = value; | |||
} | } | |||
/** | /** | |||
* Change/add new value. | * Change/add new value. | |||
*/ | */ | |||
Map& operator()(const Key& key, const Value& value) | Map& operator()(const Key& key, const Value& value) | |||
End of changes. 1 change blocks. | ||||
1 lines changed or deleted | 1 lines changed or added | |||
mat.hxx | mat.hxx | |||
---|---|---|---|---|
skipping to change at line 44 | skipping to change at line 44 | |||
#include "Effect.hxx" | #include "Effect.hxx" | |||
#include <osg/ref_ptr> | #include <osg/ref_ptr> | |||
#include <osg/Texture2D> | #include <osg/Texture2D> | |||
namespace osg | namespace osg | |||
{ | { | |||
class StateSet; | class StateSet; | |||
} | } | |||
typedef osg::ref_ptr<osg::Texture2D> Texture2DRef; | ||||
#include <simgear/structure/SGSharedPtr.hxx> | #include <simgear/structure/SGSharedPtr.hxx> | |||
#include <simgear/threads/SGThread.hxx> // for SGMutex | #include <simgear/threads/SGThread.hxx> // for SGMutex | |||
#include <simgear/math/SGMath.hxx> | #include <simgear/math/SGMath.hxx> | |||
#include <simgear/bvh/BVHMaterial.hxx> | #include <simgear/bvh/BVHMaterial.hxx> | |||
namespace simgear | namespace simgear | |||
{ | { | |||
class Effect; | class Effect; | |||
void reload_shaders(); | void reload_shaders(); | |||
class SGReaderWriterOptions; | class SGReaderWriterOptions; | |||
skipping to change at line 458 | skipping to change at line 460 | |||
std::vector<SGSharedPtr<SGMatModelGroup> > object_groups; | std::vector<SGSharedPtr<SGMatModelGroup> > object_groups; | |||
// taxiway-/runway-sign texture elements | // taxiway-/runway-sign texture elements | |||
std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs; | std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs; | |||
// Tree texture, typically a strip of applicable tree textures | // Tree texture, typically a strip of applicable tree textures | |||
std::string tree_texture; | std::string tree_texture; | |||
// Object mask, a simple RGB texture used as a mask when placing | // Object mask, a simple RGB texture used as a mask when placing | |||
// random vegetation, objects and buildings | // random vegetation, objects and buildings | |||
std::vector<osg::Texture2D*> _masks; | std::vector<Texture2DRef> _masks; | |||
// Condition, indicating when this material is active | // Condition, indicating when this material is active | |||
SGSharedPtr<const SGCondition> condition; | SGSharedPtr<const SGCondition> condition; | |||
// Parameters from the materials file | // Parameters from the materials file | |||
const SGPropertyNode* parameters; | const SGPropertyNode* parameters; | |||
// per-material lock for entrypoints called from multiple threads | // per-material lock for entrypoints called from multiple threads | |||
SGMutex _lock; | SGMutex _lock; | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 3 lines changed or added | |||
modellib.hxx | modellib.hxx | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
#include <simgear/compiler.h> // for SG_USING_STD | #include <simgear/compiler.h> // for SG_USING_STD | |||
#include <string> | #include <string> | |||
#include <osg/Node> | #include <osg/Node> | |||
#include <osgDB/ReaderWriter> | #include <osgDB/ReaderWriter> | |||
#include <simgear/props/props.hxx> | #include <simgear/props/props.hxx> | |||
#include <simgear/misc/sg_path.hxx> | #include <simgear/misc/sg_path.hxx> | |||
namespace osg { | ||||
class PagedLOD; | ||||
} | ||||
namespace simgear { | namespace simgear { | |||
class SGModelData; // defined below | class SGModelData; // defined below | |||
/** | /** | |||
* Class for loading and managing models with XML wrappers. | * Class for loading and managing models with XML wrappers. | |||
*/ | */ | |||
class SGModelLib | class SGModelLib | |||
{ | { | |||
public: | public: | |||
skipping to change at line 71 | skipping to change at line 75 | |||
// the model file. Once the viewer steps onto that node the | // the model file. Once the viewer steps onto that node the | |||
// model will be loaded. | // model will be loaded. | |||
static osg::Node* loadDeferredModel(const std::string &path, | static osg::Node* loadDeferredModel(const std::string &path, | |||
SGPropertyNode *prop_root = NULL, | SGPropertyNode *prop_root = NULL, | |||
SGModelData *data=0); | SGModelData *data=0); | |||
// Load a 3D model (any format) through the DatabasePager. | // Load a 3D model (any format) through the DatabasePager. | |||
// This function initially just returns a PagedLOD node that refers to | // This function initially just returns a PagedLOD node that refers to | |||
// the model file. Once the viewer steps onto that node the | // the model file. Once the viewer steps onto that node the | |||
// model will be loaded. When the viewer does no longer reference this | // model will be loaded. When the viewer does no longer reference this | |||
// node for a long time the node is unloaded again. | // node for a long time the node is unloaded again. | |||
static osg::Node* loadPagedModel(const std::string &path, | static osg::PagedLOD* loadPagedModel(const std::string &path, | |||
SGPropertyNode *prop_root = NULL, | SGPropertyNode *prop_root = NULL, | |||
SGModelData *data=0); | SGModelData *data=0); | |||
static std::string findDataFile(const std::string& file, | static std::string findDataFile(const std::string& file, | |||
const osgDB::Options* opts = NULL, | const osgDB::Options* opts = NULL, | |||
SGPath currentDir = SGPath()); | SGPath currentDir = SGPath()); | |||
protected: | protected: | |||
SGModelLib(); | SGModelLib(); | |||
~SGModelLib (); | ~SGModelLib (); | |||
End of changes. 2 change blocks. | ||||
1 lines changed or deleted | 5 lines changed or added | |||
nasal.h | nasal.h | |||
---|---|---|---|---|
skipping to change at line 183 | skipping to change at line 183 | |||
int naIsNil(naRef r) GCC_PURE; | int naIsNil(naRef r) GCC_PURE; | |||
int naIsNum(naRef r) GCC_PURE; | int naIsNum(naRef r) GCC_PURE; | |||
int naIsString(naRef r) GCC_PURE; | int naIsString(naRef r) GCC_PURE; | |||
int naIsScalar(naRef r) GCC_PURE; | int naIsScalar(naRef r) GCC_PURE; | |||
int naIsVector(naRef r) GCC_PURE; | int naIsVector(naRef r) GCC_PURE; | |||
int naIsHash(naRef r) GCC_PURE; | int naIsHash(naRef r) GCC_PURE; | |||
int naIsCode(naRef r) GCC_PURE; | int naIsCode(naRef r) GCC_PURE; | |||
int naIsFunc(naRef r) GCC_PURE; | int naIsFunc(naRef r) GCC_PURE; | |||
int naIsCCode(naRef r) GCC_PURE; | int naIsCCode(naRef r) GCC_PURE; | |||
// Object equality (check for same instance, aka. pointer equality) | ||||
int naIsIdentical(naRef l, naRef r) GCC_PURE; | ||||
// Allocators/generators: | // Allocators/generators: | |||
naRef naNil() GCC_PURE; | naRef naNil() GCC_PURE; | |||
naRef naNum(double num) GCC_PURE; | naRef naNum(double num) GCC_PURE; | |||
naRef naNewString(naContext c); | naRef naNewString(naContext c); | |||
naRef naNewVector(naContext c); | naRef naNewVector(naContext c); | |||
naRef naNewHash(naContext c); | naRef naNewHash(naContext c); | |||
naRef naNewFunc(naContext c, naRef code); | naRef naNewFunc(naContext c, naRef code); | |||
/** | /** | |||
* Register extension function | * Register extension function | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 3 lines changed or added | |||
nasal_traits.hxx | nasal_traits.hxx | |||
---|---|---|---|---|
skipping to change at line 23 | skipping to change at line 23 | |||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
// Library General Public License for more details. | // Library General Public License for more details. | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_NASAL_TRAITS_HXX_ | #ifndef SG_NASAL_TRAITS_HXX_ | |||
#define SG_NASAL_TRAITS_HXX_ | #define SG_NASAL_TRAITS_HXX_ | |||
#include <boost/mpl/logical.hpp> | ||||
#include <boost/type_traits/integral_constant.hpp> | #include <boost/type_traits/integral_constant.hpp> | |||
#include <boost/type_traits/is_base_of.hpp> | ||||
#include <boost/utility/enable_if.hpp> | ||||
// Forward declarations | ||||
class SGReferenced; | ||||
class SGWeakReferenced; | ||||
template<class T> class SGSharedPtr; | ||||
template<class T> class SGWeakPtr; | ||||
template<class T> class SGVec2; | ||||
namespace boost | ||||
{ | ||||
template<class T> class shared_ptr; | ||||
template<class T> class weak_ptr; | ||||
} | ||||
namespace osg | ||||
{ | ||||
class Referenced; | ||||
template<class T> class ref_ptr; | ||||
template<class T> class observer_ptr; | ||||
template<class T, class Y> | ||||
ref_ptr<T> static_pointer_cast(const ref_ptr<Y>&); | ||||
class Vec2b; | ||||
class Vec2d; | ||||
class Vec2f; | ||||
class Vec2s; | ||||
} | ||||
// The actual traits... | ||||
namespace nasal | namespace nasal | |||
{ | { | |||
template<class T> | template<class T> | |||
struct is_vec2: public boost::integral_constant<bool, false> {}; | struct is_vec2: public boost::integral_constant<bool, false> {}; | |||
#define SG_MAKE_TRAIT(templ,type,attr)\ | #define SG_MAKE_TRAIT(templ,type,attr)\ | |||
template templ\ | template templ\ | |||
struct attr< type >:\ | struct attr< type >:\ | |||
public boost::integral_constant<bool, true> {}; | public boost::integral_constant<bool, true> {}; | |||
#ifdef SGVec2_H | SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2) | |||
SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2) | SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2) | |||
#endif | SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2) | |||
SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2) | ||||
#ifdef OSG_VEC2B | SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2) | |||
SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2) | ||||
#endif | ||||
#ifdef OSG_VEC2D | ||||
SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2) | ||||
#endif | ||||
#ifdef OSG_VEC2F | ||||
SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2) | ||||
#endif | ||||
#ifdef OSG_VEC2S | ||||
SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2) | ||||
#endif | ||||
#undef SG_MAKE_TRAIT | #undef SG_MAKE_TRAIT | |||
template<class T> | ||||
struct shared_ptr_traits; | ||||
template<class T> | ||||
struct is_strong_ref: | ||||
public boost::integral_constant<bool, false> | ||||
{}; | ||||
template<class T> | ||||
struct is_weak_ref: | ||||
public boost::integral_constant<bool, false> | ||||
{}; | ||||
#define SG_MAKE_SHARED_PTR_TRAIT(strong, weak, intrusive)\ | ||||
template<class T>\ | ||||
struct shared_ptr_traits<strong<T> >\ | ||||
{\ | ||||
typedef strong<T> strong_ref;\ | ||||
typedef weak<T> weak_ref;\ | ||||
typedef T element_type;\ | ||||
typedef boost::integral_constant<bool, true> is_strong;\ | ||||
typedef boost::integral_constant<bool, intrusive> is_intrusive;\ | ||||
};\ | ||||
template<class T>\ | ||||
struct shared_ptr_traits<weak<T> >\ | ||||
{\ | ||||
typedef strong<T> strong_ref;\ | ||||
typedef weak<T> weak_ref;\ | ||||
typedef T element_type;\ | ||||
typedef boost::integral_constant<bool, false> is_strong;\ | ||||
typedef boost::integral_constant<bool, intrusive> is_intrusive;\ | ||||
};\ | ||||
template<class T>\ | ||||
struct is_strong_ref<strong<T> >:\ | ||||
public boost::integral_constant<bool, true>\ | ||||
{};\ | ||||
template<class T>\ | ||||
struct is_weak_ref<weak<T> >:\ | ||||
public boost::integral_constant<bool, true>\ | ||||
{}; | ||||
SG_MAKE_SHARED_PTR_TRAIT(SGSharedPtr, SGWeakPtr, true) | ||||
SG_MAKE_SHARED_PTR_TRAIT(osg::ref_ptr, osg::observer_ptr, true) | ||||
SG_MAKE_SHARED_PTR_TRAIT(boost::shared_ptr, boost::weak_ptr, false) | ||||
#undef SG_MAKE_SHARED_PTR_TRAIT | ||||
template<class T> | ||||
struct supports_weak_ref: | ||||
public boost::integral_constant<bool, true> | ||||
{}; | ||||
template<class T> | ||||
struct supports_weak_ref<SGSharedPtr<T> >: | ||||
public boost::integral_constant< | ||||
bool, | ||||
boost::is_base_of<SGWeakReferenced, T>::value | ||||
> | ||||
{}; | ||||
template<class T> | ||||
struct shared_ptr_storage | ||||
{ | ||||
typedef T storage_type; | ||||
typedef typename T::element_type element_type; | ||||
typedef typename shared_ptr_traits<T>::strong_ref strong_ref; | ||||
typedef typename shared_ptr_traits<T>::weak_ref weak_ref; | ||||
template<class U> | ||||
static storage_type* ref(U ptr) | ||||
{ | ||||
return new storage_type(ptr); | ||||
} | ||||
static void unref(storage_type* ptr) | ||||
{ | ||||
delete ptr; | ||||
} | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::is_same<U, element_type*>, | ||||
element_type* | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return get_pointer(*ptr); | ||||
} | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::mpl::or_< | ||||
boost::is_same<U, strong_ref>, | ||||
boost::mpl::and_< | ||||
boost::is_same<U, weak_ref>, | ||||
supports_weak_ref<U> | ||||
> | ||||
>, | ||||
U | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return U(*ptr); | ||||
} | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::mpl::and_< | ||||
boost::is_same<U, weak_ref>, | ||||
boost::mpl::not_<supports_weak_ref<U> > | ||||
>, | ||||
U | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return U(); | ||||
} | ||||
}; | ||||
namespace internal | ||||
{ | ||||
template<class T> | ||||
struct intrusive_ptr_storage | ||||
{ | ||||
typedef typename T::element_type storage_type; | ||||
typedef typename T::element_type element_type; | ||||
typedef typename shared_ptr_traits<T>::strong_ref strong_ref; | ||||
typedef typename shared_ptr_traits<T>::weak_ref weak_ref; | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::is_same<U, element_type*>, | ||||
element_type* | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return ptr; | ||||
} | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::mpl::or_< | ||||
boost::is_same<U, strong_ref>, | ||||
boost::mpl::and_< | ||||
boost::is_same<U, weak_ref>, | ||||
supports_weak_ref<U> | ||||
> | ||||
>, | ||||
U | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return U(ptr); | ||||
} | ||||
template<class U> | ||||
static | ||||
typename boost::enable_if< | ||||
boost::mpl::and_< | ||||
boost::is_same<U, weak_ref>, | ||||
boost::mpl::not_<supports_weak_ref<U> > | ||||
>, | ||||
U | ||||
>::type | ||||
get(storage_type* ptr) | ||||
{ | ||||
return U(); | ||||
} | ||||
}; | ||||
} | ||||
template<class T> | ||||
struct shared_ptr_storage<SGSharedPtr<T> >: | ||||
public internal::intrusive_ptr_storage<SGSharedPtr<T> > | ||||
{ | ||||
typedef T storage_type; | ||||
typedef T element_type; | ||||
static storage_type* ref(element_type* ptr) | ||||
{ | ||||
T::get(ptr); | ||||
return ptr; | ||||
} | ||||
static void unref(storage_type* ptr) | ||||
{ | ||||
if( !T::put(ptr) ) | ||||
delete ptr; | ||||
} | ||||
}; | ||||
template<class T> | ||||
struct shared_ptr_storage<osg::ref_ptr<T> >: | ||||
public internal::intrusive_ptr_storage<osg::ref_ptr<T> > | ||||
{ | ||||
typedef T storage_type; | ||||
typedef T element_type; | ||||
static storage_type* ref(element_type* ptr) | ||||
{ | ||||
ptr->ref(); | ||||
return ptr; | ||||
} | ||||
static void unref(storage_type* ptr) | ||||
{ | ||||
ptr->unref(); | ||||
} | ||||
}; | ||||
} // namespace nasal | } // namespace nasal | |||
#endif /* SG_NASAL_TRAITS_HXX_ */ | #endif /* SG_NASAL_TRAITS_HXX_ */ | |||
End of changes. 5 change blocks. | ||||
19 lines changed or deleted | 244 lines changed or added | |||
newbucket.hxx | newbucket.hxx | |||
---|---|---|---|---|
skipping to change at line 42 | skipping to change at line 42 | |||
*/ | */ | |||
#ifndef _NEWBUCKET_HXX | #ifndef _NEWBUCKET_HXX | |||
#define _NEWBUCKET_HXX | #define _NEWBUCKET_HXX | |||
#include <simgear/compiler.h> | #include <simgear/compiler.h> | |||
#include <simgear/constants.h> | #include <simgear/constants.h> | |||
#include <simgear/math/SGMath.hxx> | #include <simgear/math/SGMath.hxx> | |||
#include <cmath> | #include <cmath> | |||
#include <cstdio> // sprintf() | ||||
#include <ostream> | ||||
#include <string> | #include <string> | |||
#include <iosfwd> | ||||
#include <vector> | #include <vector> | |||
// #define NO_DEPRECATED_API | ||||
/** | /** | |||
* standard size of a bucket in degrees (1/8 of a degree) | * standard size of a bucket in degrees (1/8 of a degree) | |||
*/ | */ | |||
#define SG_BUCKET_SPAN 0.125 | #define SG_BUCKET_SPAN 0.125 | |||
/** | /** | |||
* half of a standard SG_BUCKET_SPAN | * half of a standard SG_BUCKET_SPAN | |||
*/ | */ | |||
#define SG_HALF_BUCKET_SPAN ( 0.5 * SG_BUCKET_SPAN ) | #define SG_HALF_BUCKET_SPAN ( 0.5 * SG_BUCKET_SPAN ) | |||
skipping to change at line 100 | skipping to change at line 101 | |||
* This class encapsulates the world tiling scheme. It provides ways | * This class encapsulates the world tiling scheme. It provides ways | |||
* to calculate a unique tile index from a lat/lon, and it can provide | * to calculate a unique tile index from a lat/lon, and it can provide | |||
* information such as the dimensions of a given tile. | * information such as the dimensions of a given tile. | |||
*/ | */ | |||
class SGBucket { | class SGBucket { | |||
private: | private: | |||
short lon; // longitude index (-180 to 179) | short lon; // longitude index (-180 to 179) | |||
short lat; // latitude index (-90 to 89) | short lat; // latitude index (-90 to 89) | |||
char x; // x subdivision (0 to 7) | unsigned char x; // x subdivision (0 to 7) | |||
char y; // y subdivision (0 to 7) | unsigned char y; // y subdivision (0 to 7) | |||
void innerSet( double dlon, double dlat ); | ||||
public: | public: | |||
/** | /** | |||
* Default constructor. | * Default constructor, creates an invalid SGBucket | |||
*/ | */ | |||
SGBucket(); | SGBucket(); | |||
/** | /** | |||
* Check if this bucket refers to a valid tile, or not. | ||||
*/ | ||||
bool isValid() const; | ||||
#ifndef NO_DEPRECATED_API | ||||
/** | ||||
* Construct a bucket given a specific location. | * Construct a bucket given a specific location. | |||
* @param dlon longitude specified in degrees | * @param dlon longitude specified in degrees | |||
* @param dlat latitude specified in degrees | * @param dlat latitude specified in degrees | |||
*/ | */ | |||
SGBucket(const double dlon, const double dlat); | SGBucket(const double dlon, const double dlat); | |||
#endif | ||||
/** | /** | |||
* Construct a bucket given a specific location. | * Construct a bucket given a specific location. | |||
* @param dlon longitude specified in degrees | * @param dlon longitude specified in degrees | |||
* @param dlat latitude specified in degrees | * @param dlat latitude specified in degrees | |||
*/ | */ | |||
SGBucket(const SGGeod& geod); | SGBucket(const SGGeod& geod); | |||
/** Construct a bucket. | ||||
* @param is_good if false, create an invalid bucket. This is | ||||
* useful * if you are comparing cur_bucket to last_bucket and | ||||
* you want to * make sure last_bucket starts out as something | ||||
* impossible. | ||||
*/ | ||||
SGBucket(const bool is_good); | ||||
/** Construct a bucket given a unique bucket index number. | /** Construct a bucket given a unique bucket index number. | |||
* @param bindex unique bucket index | * @param bindex unique bucket index | |||
*/ | */ | |||
SGBucket(const long int bindex); | SGBucket(const long int bindex); | |||
#ifndef NO_DEPRECATED_API | ||||
/** | /** | |||
* Reset a bucket to represent a new lat and lon | * Reset a bucket to represent a new lat and lon | |||
* @param dlon longitude specified in degrees | * @param dlon longitude specified in degrees | |||
* @param dlat latitude specified in degrees | * @param dlat latitude specified in degrees | |||
*/ | */ | |||
void set_bucket( double dlon, double dlat ); | void set_bucket(const SGGeod& geod); | |||
/** | ||||
* Reset a bucket to represent a new lat and lon | ||||
* @param lonlat an array of double[2] holding lon and lat | ||||
* (specified) in degrees | ||||
*/ | ||||
void set_bucket( double *lonlat ); | ||||
/** | /** | |||
* Reset a bucket to represent a new lat and lon | * Reset a bucket to represent a new lat and lon | |||
* @param dlon longitude specified in degrees | * @param dlon longitude specified in degrees | |||
* @param dlat latitude specified in degrees | * @param dlat latitude specified in degrees | |||
*/ | */ | |||
void set_bucket(const SGGeod& geod); | void set_bucket( double dlon, double dlat ); | |||
#endif | ||||
/** | /** | |||
* Create an impossible bucket. | * Create an impossible bucket. | |||
* This is useful if you are comparing cur_bucket to last_bucket | * This is useful if you are comparing cur_bucket to last_bucket | |||
* and you want to make sure last_bucket starts out as something | * and you want to make sure last_bucket starts out as something | |||
* impossible. | * impossible. | |||
*/ | */ | |||
inline void make_bad() { | void make_bad(); | |||
set_bucket(0.0, 0.0); | ||||
lon = -1000; | ||||
} | ||||
/** | /** | |||
* Generate the unique scenery tile index for this bucket | * Generate the unique scenery tile index for this bucket | |||
* | * | |||
* The index is constructed as follows: | * The index is constructed as follows: | |||
* | * | |||
* 9 bits - to represent 360 degrees of longitude (-180 to 179) | * 9 bits - to represent 360 degrees of longitude (-180 to 179) | |||
* 8 bits - to represent 180 degrees of latitude (-90 to 89) | * 8 bits - to represent 180 degrees of latitude (-90 to 89) | |||
* | * | |||
* Each 1 degree by 1 degree tile is further broken down into an 8x8 | * Each 1 degree by 1 degree tile is further broken down into an 8x8 | |||
skipping to change at line 193 | skipping to change at line 186 | |||
*/ | */ | |||
inline long int gen_index() const { | inline long int gen_index() const { | |||
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x; | return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x; | |||
} | } | |||
/** | /** | |||
* Generate the unique scenery tile index for this bucket in ascii | * Generate the unique scenery tile index for this bucket in ascii | |||
* string form. | * string form. | |||
* @return tile index in string form | * @return tile index in string form | |||
*/ | */ | |||
inline std::string gen_index_str() const { | std::string gen_index_str() const; | |||
char tmp[20]; | ||||
std::sprintf(tmp, "%ld", | ||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) | ||||
+ (y << 3) + x); | ||||
return (std::string)tmp; | ||||
} | ||||
/** | /** | |||
* Build the base path name for this bucket. | * Build the base path name for this bucket. | |||
* @return base path in string form | * @return base path in string form | |||
*/ | */ | |||
std::string gen_base_path() const; | std::string gen_base_path() const; | |||
/** | /** | |||
* @return the center lon of a tile. | * @return the center lon of a tile. | |||
*/ | */ | |||
skipping to change at line 228 | skipping to change at line 215 | |||
} | } | |||
/** | /** | |||
* @return the center lat of a tile. | * @return the center lat of a tile. | |||
*/ | */ | |||
inline double get_center_lat() const { | inline double get_center_lat() const { | |||
return lat + y / 8.0 + SG_HALF_BUCKET_SPAN; | return lat + y / 8.0 + SG_HALF_BUCKET_SPAN; | |||
} | } | |||
/** | /** | |||
* @return the highest (furthest from the equator) latitude of this | ||||
* tile. This is the top edge for tiles north of the equator, and | ||||
* the bottom edge for tiles south | ||||
*/ | ||||
double get_highest_lat() const; | ||||
/** | ||||
* @return the width of the tile in degrees. | * @return the width of the tile in degrees. | |||
*/ | */ | |||
double get_width() const; | double get_width() const; | |||
/** | /** | |||
* @return the height of the tile in degrees. | * @return the height of the tile in degrees. | |||
*/ | */ | |||
double get_height() const; | double get_height() const; | |||
/** | /** | |||
skipping to change at line 288 | skipping to change at line 282 | |||
/** | /** | |||
* @return the x coord within the 1x1 degree chunk this tile. | * @return the x coord within the 1x1 degree chunk this tile. | |||
*/ | */ | |||
inline int get_x() const { return x; } | inline int get_x() const { return x; } | |||
/** | /** | |||
* @return the y coord within the 1x1 degree chunk this tile. | * @return the y coord within the 1x1 degree chunk this tile. | |||
*/ | */ | |||
inline int get_y() const { return y; } | inline int get_y() const { return y; } | |||
/** | ||||
* @return bucket offset from this by dx,dy | ||||
*/ | ||||
SGBucket sibling(int dx, int dy) const; | ||||
// friends | // friends | |||
friend std::ostream& operator<< ( std::ostream&, const SGBucket& ); | friend std::ostream& operator<< ( std::ostream&, const SGBucket& ); | |||
friend bool operator== ( const SGBucket&, const SGBucket& ); | friend bool operator== ( const SGBucket&, const SGBucket& ); | |||
}; | }; | |||
inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs) | inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs) | |||
{ | { | |||
return !(lhs == rhs); | return !(lhs == rhs); | |||
} | } | |||
#ifndef NO_DEPRECATED_API | ||||
/** | /** | |||
* \relates SGBucket | * \relates SGBucket | |||
* Return the bucket which is offset from the specified dlon, dlat by | * Return the bucket which is offset from the specified dlon, dlat by | |||
* the specified tile units in the X & Y direction. | * the specified tile units in the X & Y direction. | |||
* @param dlon starting lon in degrees | * @param dlon starting lon in degrees | |||
* @param dlat starting lat in degrees | * @param dlat starting lat in degrees | |||
* @param x number of bucket units to offset in x (lon) direction | * @param x number of bucket units to offset in x (lon) direction | |||
* @param y number of bucket units to offset in y (lat) direction | * @param y number of bucket units to offset in y (lat) direction | |||
* @return offset bucket | * @return offset bucket | |||
*/ | */ | |||
SGBucket sgBucketOffset( double dlon, double dlat, int x, int y ); | SGBucket sgBucketOffset( double dlon, double dlat, int x, int y ); | |||
#endif | ||||
/** | /** | |||
* \relates SGBucket | * \relates SGBucket | |||
* Calculate the offset between two buckets (in quantity of buckets). | * Calculate the offset between two buckets (in quantity of buckets). | |||
* @param b1 bucket 1 | * @param b1 bucket 1 | |||
* @param b2 bucket 2 | * @param b2 bucket 2 | |||
* @param dx offset distance (lon) in tile units | * @param dx offset distance (lon) in tile units | |||
* @param dy offset distance (lat) in tile units | * @param dy offset distance (lat) in tile units | |||
*/ | */ | |||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ); | void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ); | |||
skipping to change at line 335 | skipping to change at line 336 | |||
* @param max max lon,lat of bounding box in degrees | * @param max max lon,lat of bounding box in degrees | |||
* @param list standard vector of buckets within the bounding box | * @param list standard vector of buckets within the bounding box | |||
*/ | */ | |||
void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBuck et>& list ); | void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBuck et>& list ); | |||
/** | /** | |||
* Write the bucket lon, lat, x, and y to the output stream. | * Write the bucket lon, lat, x, and y to the output stream. | |||
* @param out output stream | * @param out output stream | |||
* @param b bucket | * @param b bucket | |||
*/ | */ | |||
inline std::ostream& | std::ostream& operator<< ( std::ostream& out, const SGBucket& b ); | |||
operator<< ( std::ostream& out, const SGBucket& b ) | ||||
{ | ||||
return out << b.lon << ":" << (int)b.x << ", " << b.lat << ":" << (int) | ||||
b.y; | ||||
} | ||||
/** | /** | |||
* Compare two bucket structures for equality. | * Compare two bucket structures for equality. | |||
* @param b1 bucket 1 | * @param b1 bucket 1 | |||
* @param b2 bucket 2 | * @param b2 bucket 2 | |||
* @return comparison result | * @return comparison result | |||
*/ | */ | |||
inline bool | inline bool | |||
operator== ( const SGBucket& b1, const SGBucket& b2 ) | operator== ( const SGBucket& b1, const SGBucket& b2 ) | |||
{ | { | |||
End of changes. 19 change blocks. | ||||
39 lines changed or deleted | 35 lines changed or added | |||
props.hxx | props.hxx | |||
---|---|---|---|---|
skipping to change at line 884 | skipping to change at line 884 | |||
* Get a vector of all children with the specified name. | * Get a vector of all children with the specified name. | |||
*/ | */ | |||
simgear::PropertyList getChildren (const char * name) const; | simgear::PropertyList getChildren (const char * name) const; | |||
/** | /** | |||
* Get a vector of all children with the specified name. | * Get a vector of all children with the specified name. | |||
*/ | */ | |||
simgear::PropertyList getChildren (const std::string& name) const | simgear::PropertyList getChildren (const std::string& name) const | |||
{ return getChildren(name.c_str()); } | { return getChildren(name.c_str()); } | |||
/** | ||||
* Remove child by pointer (if it is a child of this node). | ||||
* | ||||
* @return true, if the node was deleted. | ||||
*/ | ||||
bool removeChild(SGPropertyNode* node); | ||||
// TODO do we need the removeXXX methods to return the deleted nodes? | // TODO do we need the removeXXX methods to return the deleted nodes? | |||
/** | /** | |||
* Remove child by position. | * Remove child by position. | |||
*/ | */ | |||
SGPropertyNode_ptr removeChild (int pos, bool keep = true); | SGPropertyNode_ptr removeChild(int pos); | |||
/** | /** | |||
* Remove a child node | * Remove a child node | |||
*/ | */ | |||
SGPropertyNode_ptr removeChild (const char * name, int index = 0, | SGPropertyNode_ptr removeChild(const char * name, int index = 0); | |||
bool keep = true); | ||||
/** | /** | |||
* Remove a child node | * Remove a child node | |||
*/ | */ | |||
SGPropertyNode_ptr removeChild (const std::string& name, int index = 0, | SGPropertyNode_ptr removeChild(const std::string& name, int index = 0) | |||
bool keep = true) | { return removeChild(name.c_str(), index); } | |||
{ return removeChild(name.c_str(), index, keep); } | ||||
/** | /** | |||
* Remove all children with the specified name. | * Remove all children with the specified name. | |||
*/ | */ | |||
simgear::PropertyList removeChildren (const char * name, bool keep = true ); | simgear::PropertyList removeChildren(const char * name); | |||
/** | /** | |||
* Remove all children with the specified name. | * Remove all children with the specified name. | |||
*/ | */ | |||
simgear::PropertyList removeChildren (const std::string& name, | simgear::PropertyList removeChildren(const std::string& name) | |||
bool keep = true) | { return removeChildren(name.c_str()); } | |||
{ return removeChildren(name.c_str(), keep); } | ||||
/** | /** | |||
* Remove all children (does not change the value of the node) | * Remove all children (does not change the value of the node) | |||
*/ | */ | |||
void removeAllChildren(); | void removeAllChildren(); | |||
// | // | |||
// Alias support. | // Alias support. | |||
// | // | |||
skipping to change at line 1242 | skipping to change at line 1246 | |||
const simgear::PropertyList& values, | const simgear::PropertyList& values, | |||
const double_list& deltas, | const double_list& deltas, | |||
const std::string& easing = "swing" ); | const std::string& easing = "swing" ); | |||
/** | /** | |||
* Set the interpolation manager used by the interpolate methods. | * Set the interpolation manager used by the interpolate methods. | |||
*/ | */ | |||
static void setInterpolationMgr(simgear::PropertyInterpolationMgr* mgr); | static void setInterpolationMgr(simgear::PropertyInterpolationMgr* mgr); | |||
/** | /** | |||
* Get the interpolation manager | ||||
*/ | ||||
static simgear::PropertyInterpolationMgr* getInterpolationMgr(); | ||||
/** | ||||
* Print the value of the property to a stream. | * Print the value of the property to a stream. | |||
*/ | */ | |||
std::ostream& printOn(std::ostream& stream) const; | std::ostream& printOn(std::ostream& stream) const; | |||
// | // | |||
// Data binding. | // Data binding. | |||
// | // | |||
/** | /** | |||
* Test whether this node is bound to an external data source. | * Test whether this node is bound to an external data source. | |||
skipping to change at line 1622 | skipping to change at line 1631 | |||
* Attributes, removed children, and aliases aren't considered. | * Attributes, removed children, and aliases aren't considered. | |||
*/ | */ | |||
static bool compare (const SGPropertyNode& lhs, const SGPropertyNode& rhs ); | static bool compare (const SGPropertyNode& lhs, const SGPropertyNode& rhs ); | |||
protected: | protected: | |||
void fireValueChanged (SGPropertyNode * node); | void fireValueChanged (SGPropertyNode * node); | |||
void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child); | void fireChildAdded (SGPropertyNode * parent, SGPropertyNode * child); | |||
void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child); | void fireChildRemoved (SGPropertyNode * parent, SGPropertyNode * child); | |||
SGPropertyNode_ptr eraseChild(simgear::PropertyList::iterator child); | ||||
/** | /** | |||
* Protected constructor for making new nodes on demand. | * Protected constructor for making new nodes on demand. | |||
*/ | */ | |||
SGPropertyNode (const std::string& name, int index, SGPropertyNode * pare nt); | SGPropertyNode (const std::string& name, int index, SGPropertyNode * pare nt); | |||
template<typename Itr> | template<typename Itr> | |||
SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent); | SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent); | |||
static simgear::PropertyInterpolationMgr* _interpolation_mgr; | static simgear::PropertyInterpolationMgr* _interpolation_mgr; | |||
private: | private: | |||
skipping to change at line 1670 | skipping to change at line 1681 | |||
* Trace a write access. | * Trace a write access. | |||
*/ | */ | |||
void trace_write () const; | void trace_write () const; | |||
int _index; | int _index; | |||
std::string _name; | std::string _name; | |||
/// To avoid cyclic reference counting loops this shall not be a referenc e | /// To avoid cyclic reference counting loops this shall not be a referenc e | |||
/// counted pointer | /// counted pointer | |||
SGPropertyNode * _parent; | SGPropertyNode * _parent; | |||
simgear::PropertyList _children; | simgear::PropertyList _children; | |||
simgear::PropertyList _removedChildren; | ||||
mutable std::string _buffer; | mutable std::string _buffer; | |||
simgear::props::Type _type; | simgear::props::Type _type; | |||
bool _tied; | bool _tied; | |||
int _attr; | int _attr; | |||
// The right kind of pointer... | // The right kind of pointer... | |||
union { | union { | |||
SGPropertyNode * alias; | SGPropertyNode * alias; | |||
SGRaw* val; | SGRaw* val; | |||
} _value; | } _value; | |||
skipping to change at line 1698 | skipping to change at line 1708 | |||
char * string_val; | char * string_val; | |||
} _local_val; | } _local_val; | |||
std::vector<SGPropertyChangeListener *> * _listeners; | std::vector<SGPropertyChangeListener *> * _listeners; | |||
// Pass name as a pair of iterators | // Pass name as a pair of iterators | |||
template<typename Itr> | template<typename Itr> | |||
SGPropertyNode * getChildImpl (Itr begin, Itr end, int index = 0, bool cr eate = false); | SGPropertyNode * getChildImpl (Itr begin, Itr end, int index = 0, bool cr eate = false); | |||
// very internal method | // very internal method | |||
template<typename Itr> | template<typename Itr> | |||
SGPropertyNode* getExistingChild (Itr begin, Itr end, int index, bool cre ate); | SGPropertyNode* getExistingChild (Itr begin, Itr end, int index); | |||
// very internal path parsing function | // very internal path parsing function | |||
template<typename SplitItr> | template<typename SplitItr> | |||
friend SGPropertyNode* find_node_aux(SGPropertyNode * current, SplitItr& itr, | friend SGPropertyNode* find_node_aux(SGPropertyNode * current, SplitItr& itr, | |||
bool create, int last_index); | bool create, int last_index); | |||
// For boost | // For boost | |||
friend size_t hash_value(const SGPropertyNode& node); | friend size_t hash_value(const SGPropertyNode& node); | |||
}; | }; | |||
// Convenience functions for use in templates | // Convenience functions for use in templates | |||
template<typename T> | template<typename T> | |||
End of changes. 10 change blocks. | ||||
12 lines changed or deleted | 22 lines changed or added | |||
props_io.hxx | props_io.hxx | |||
---|---|---|---|---|
skipping to change at line 59 | skipping to change at line 59 | |||
* Write properties to an XML file. | * Write properties to an XML file. | |||
*/ | */ | |||
void writeProperties (const std::string &file, | void writeProperties (const std::string &file, | |||
const SGPropertyNode * start_node, | const SGPropertyNode * start_node, | |||
bool write_all = false, | bool write_all = false, | |||
SGPropertyNode::Attribute archive_flag = SGPropertyNod e::ARCHIVE); | SGPropertyNode::Attribute archive_flag = SGPropertyNod e::ARCHIVE); | |||
/** | /** | |||
* Copy properties from one node to another. | * Copy properties from one node to another. | |||
*/ | */ | |||
bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out, | bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out); | |||
int attr_value=0, int attr_mask=0); | ||||
bool copyPropertiesWithAttribute(const SGPropertyNode *in, SGPropertyNode * out, | bool copyPropertiesWithAttribute(const SGPropertyNode *in, SGPropertyNode * out, | |||
SGPropertyNode::Attribute attr); | SGPropertyNode::Attribute attr); | |||
#endif // __PROPS_IO_HXX | #endif // __PROPS_IO_HXX | |||
// end of props_io.hxx | // end of props_io.hxx | |||
End of changes. 1 change blocks. | ||||
2 lines changed or deleted | 1 lines changed or added | |||
pt_lights.hxx | pt_lights.hxx | |||
---|---|---|---|---|
skipping to change at line 41 | skipping to change at line 41 | |||
#include <string> | #include <string> | |||
#include <vector> // STL | #include <vector> // STL | |||
#include <osg/Drawable> | #include <osg/Drawable> | |||
#include <osg/Node> | #include <osg/Node> | |||
#include <osg/Point> | #include <osg/Point> | |||
#include <simgear/math/sg_types.hxx> | #include <simgear/math/sg_types.hxx> | |||
#include <simgear/scene/material/matlib.hxx> | #include <simgear/scene/material/matlib.hxx> | |||
#include <simgear/scene/util/SGReaderWriterOptions.hxx> | ||||
#include <simgear/scene/util/SGSceneFeatures.hxx> | #include <simgear/scene/util/SGSceneFeatures.hxx> | |||
#include "SGLightBin.hxx" | #include "SGLightBin.hxx" | |||
#include "SGDirectionalLightBin.hxx" | #include "SGDirectionalLightBin.hxx" | |||
namespace simgear | namespace simgear | |||
{ | { | |||
class Effect; | class Effect; | |||
} | } | |||
skipping to change at line 86 | skipping to change at line 87 | |||
getLights(const SGLightBin& lights, unsigned inc = 1, float alphaOff = 0) ; | getLights(const SGLightBin& lights, unsigned inc = 1, float alphaOff = 0) ; | |||
static osg::Drawable* | static osg::Drawable* | |||
getLights(const SGDirectionalLightBin& lights); | getLights(const SGDirectionalLightBin& lights); | |||
static osg::Drawable* | static osg::Drawable* | |||
getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights, | getVasi(const SGVec3f& up, const SGDirectionalLightBin& lights, | |||
const SGVec4f& red, const SGVec4f& white); | const SGVec4f& red, const SGVec4f& white); | |||
static osg::Node* | static osg::Node* | |||
getSequenced(const SGDirectionalLightBin& lights); | getSequenced(const SGDirectionalLightBin& lights, const simgear::SGReader WriterOptions* options); | |||
static osg::Node* | static osg::Node* | |||
getOdal(const SGLightBin& lights); | getOdal(const SGLightBin& lights, const simgear::SGReaderWriterOptions* o ptions); | |||
static osg::Node* | static osg::Node* | |||
getHoldShort(const SGDirectionalLightBin& lights); | getHoldShort(const SGDirectionalLightBin& lights, const simgear::SGReader WriterOptions* options); | |||
static osg::Node* | static osg::Node* | |||
getGuard(const SGDirectionalLightBin& lights); | getGuard(const SGDirectionalLightBin& lights, const simgear::SGReaderWrit erOptions* options); | |||
}; | }; | |||
simgear::Effect* getLightEffect(float size, const osg::Vec3& attenuation, | simgear::Effect* getLightEffect(float size, const osg::Vec3& attenuation, | |||
float minSize, float maxSize, bool directio | float minSize, float maxSize, bool directio | |||
nal); | nal, | |||
const simgear::SGReaderWriterOptions* optio | ||||
ns); | ||||
#endif // _SG_PT_LIGHTS_HXX | #endif // _SG_PT_LIGHTS_HXX | |||
End of changes. 6 change blocks. | ||||
6 lines changed or deleted | 9 lines changed or added | |||
sg_binobj.hxx | sg_binobj.hxx | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
#include <zlib.h> // for gzFile | #include <zlib.h> // for gzFile | |||
#include <simgear/compiler.h> | #include <simgear/compiler.h> | |||
#include <simgear/constants.h> | #include <simgear/constants.h> | |||
#include <simgear/math/sg_types.hxx> | #include <simgear/math/sg_types.hxx> | |||
#include <simgear/math/SGMath.hxx> | #include <simgear/math/SGMath.hxx> | |||
#include <vector> | #include <vector> | |||
#include <string> | #include <string> | |||
#include <boost/array.hpp> | ||||
/** STL Structure used to store object information */ | #define MAX_TC_SETS (4) | |||
#define MAX_VAS (8) | ||||
// I really want to pass around fixed length arrays, as the size | ||||
// has to be hardcoded | ||||
// but it's a C++0x feature use boost in its absence | ||||
typedef boost::array<int_list, MAX_TC_SETS> tci_list; | ||||
typedef boost::array<int_list, MAX_VAS> vai_list; | ||||
/** STL Structure used to store (integer index) object information */ | ||||
typedef std::vector < int_list > group_list; | typedef std::vector < int_list > group_list; | |||
typedef group_list::iterator group_list_iterator; | typedef group_list::iterator group_list_iterator; | |||
typedef group_list::const_iterator const_group_list_iterator; | typedef group_list::const_iterator const_group_list_iterator; | |||
/** STL Structure used to store (tc index) object information */ | ||||
typedef std::vector < tci_list > group_tci_list; | ||||
typedef group_tci_list::iterator group_tci_list_iterator; | ||||
typedef group_tci_list::const_iterator const_group_tci_list_iterator; | ||||
/** STL Structure used to store (va index) object information */ | ||||
typedef std::vector < vai_list > group_vai_list; | ||||
typedef group_vai_list::iterator group_vai_list_iterator; | ||||
typedef group_vai_list::const_iterator const_group_vai_list_iterator; | ||||
// forward decls | // forward decls | |||
class SGBucket; | class SGBucket; | |||
class SGPath; | class SGPath; | |||
class SGBinObjectPoint { | ||||
public: | ||||
std::string material; | ||||
int_list v_list; | ||||
int_list n_list; | ||||
int_list c_list; | ||||
void clear( void ) { | ||||
material = ""; | ||||
v_list.clear(); | ||||
n_list.clear(); | ||||
c_list.clear(); | ||||
}; | ||||
}; | ||||
class SGBinObjectTriangle { | ||||
public: | ||||
std::string material; | ||||
int_list v_list; | ||||
int_list n_list; | ||||
int_list c_list; | ||||
tci_list tc_list; | ||||
vai_list va_list; | ||||
void clear( void ) { | ||||
material = ""; | ||||
v_list.clear(); | ||||
n_list.clear(); | ||||
c_list.clear(); | ||||
for ( unsigned int i=0; i<MAX_TC_SETS; i++ ) { | ||||
tc_list[i].clear(); | ||||
} | ||||
for ( unsigned int i=0; i<MAX_VAS; i++ ) { | ||||
va_list[i].clear(); | ||||
} | ||||
}; | ||||
}; | ||||
/** | /** | |||
* A class to manipulate the simgear 3d object format. | * A class to manipulate the simgear 3d object format. | |||
* This class provides functionality to both read and write the binary form at. | * This class provides functionality to both read and write the binary form at. | |||
* | * | |||
* Here is a really quick overview of the file syntax: | * Here is a really quick overview of the file syntax: | |||
* | * | |||
* - scenery-file: magic, nobjects, object+ | * - scenery-file: magic, nobjects, object+ | |||
* | * | |||
* - magic: "TG" + version | * - magic: "TG" + version | |||
* | * | |||
skipping to change at line 88 | skipping to change at line 148 | |||
* | * | |||
* - vertex: FLOAT, FLOAT, FLOAT | * - vertex: FLOAT, FLOAT, FLOAT | |||
*/ | */ | |||
class SGBinObject { | class SGBinObject { | |||
private: | private: | |||
unsigned short version; | unsigned short version; | |||
SGVec3d gbs_center; | SGVec3d gbs_center; | |||
float gbs_radius; | float gbs_radius; | |||
std::vector<SGVec3d> wgs84_nodes; // vertex list | std::vector<SGVec3d> wgs84_nodes; // vertex list | |||
std::vector<SGVec4f> colors; // color list | std::vector<SGVec4f> colors; // color list | |||
std::vector<SGVec3f> normals; // normal list | std::vector<SGVec3f> normals; // normal list | |||
std::vector<SGVec2f> texcoords; // texture coordinate list | std::vector<SGVec2f> texcoords; // texture coordinate list | |||
std::vector<float> va_flt; // vertex attribute list (floats) | ||||
group_list pts_v; // points vertex index | std::vector<int> va_int; // vertex attribute list (ints) | |||
group_list pts_n; // points normal index | ||||
group_list pts_c; // points color index | group_list pts_v; // points vertex index | |||
group_list pts_tc; // points texture coordinate index | group_list pts_n; // points normal index | |||
string_list pt_materials; // points materials | group_list pts_c; // points color index | |||
group_tci_list pts_tcs; // points texture coordinates ( up | ||||
group_list tris_v; // triangles vertex index | to 4 sets ) | |||
group_list tris_n; // triangles normal index | group_vai_list pts_vas; // points vertex attributes ( up to | |||
group_list tris_c; // triangles color index | 8 sets ) | |||
group_list tris_tc; // triangles texture coordinate inde | string_list pt_materials; // points materials | |||
x | ||||
string_list tri_materials; // triangles materials | group_list tris_v; // triangles vertex index | |||
group_list tris_n; // triangles normal index | ||||
group_list strips_v; // tristrips vertex index | group_list tris_c; // triangles color index | |||
group_list strips_n; // tristrips normal index | group_tci_list tris_tcs; // triangles texture coordinates ( | |||
group_list strips_c; // tristrips color index | up to 4 sets ) | |||
group_list strips_tc; // tristrips texture coordinate index | group_vai_list tris_vas; // triangles vertex attributes ( up | |||
string_list strip_materials;// tristrips materials | to 8 sets ) | |||
string_list tri_materials; // triangles materials | ||||
group_list fans_v; // fans vertex index | ||||
group_list fans_n; // fans normal index | group_list strips_v; // tristrips vertex index | |||
group_list fans_c; // fans color index | group_list strips_n; // tristrips normal index | |||
group_list fans_tc; // fans texture coordinate index | group_list strips_c; // tristrips color index | |||
string_list fan_materials; // fans materials | group_tci_list strips_tcs; // tristrips texture coordinates ( | |||
up to 4 sets ) | ||||
group_vai_list strips_vas; // tristrips vertex attributes ( up | ||||
to 8 sets ) | ||||
string_list strip_materials; // tristrips materials | ||||
group_list fans_v; // fans vertex index | ||||
group_list fans_n; // fans normal index | ||||
group_list fans_c; // fans color index | ||||
group_tci_list fans_tcs; // fanss texture coordinates ( up t | ||||
o 4 sets ) | ||||
group_vai_list fans_vas; // fans vertex attributes ( up to 8 | ||||
sets ) | ||||
string_list fan_materials; // fans materials | ||||
void read_properties(gzFile fp, int nproperties); | void read_properties(gzFile fp, int nproperties); | |||
void read_object( gzFile fp, | void read_object( gzFile fp, | |||
int obj_type, | int obj_type, | |||
int nproperties, | int nproperties, | |||
int nelements, | int nelements, | |||
group_list& vertices, | group_list& vertices, | |||
group_list& normals, | group_list& normals, | |||
group_list& colors, | group_list& colors, | |||
group_list& texCoords, | group_tci_list& texCoords, | |||
group_vai_list& vertexAttribs, | ||||
string_list& materials); | string_list& materials); | |||
void write_header(gzFile fp, int type, int nProps, int nElements); | void write_header(gzFile fp, int type, int nProps, int nElements); | |||
void write_objects(gzFile fp, int type, const group_list& verts, | void write_objects(gzFile fp, | |||
const group_list& normals, const group_list& colors, | int type, | |||
const group_list& texCoords, const string_list& materials); | const group_list& verts, | |||
const group_list& normals, | ||||
const group_list& colors, | ||||
const group_tci_list& texCoords, | ||||
const group_vai_list& vertexAttribs, | ||||
const string_list& materials); | ||||
unsigned int count_objects(const string_list& materials); | unsigned int count_objects(const string_list& materials); | |||
public: | ||||
public: | ||||
inline unsigned short get_version() const { return version; } | inline unsigned short get_version() const { return version; } | |||
inline const SGVec3d& get_gbs_center() const { return gbs_center; } | inline const SGVec3d& get_gbs_center() const { return gbs_center; } | |||
inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; } | inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; } | |||
inline float get_gbs_radius() const { return gbs_radius; } | inline float get_gbs_radius() const { return gbs_radius; } | |||
inline void set_gbs_radius( float r ) { gbs_radius = r; } | inline void set_gbs_radius( float r ) { gbs_radius = r; } | |||
inline const std::vector<SGVec3d>& get_wgs84_nodes() const | inline const std::vector<SGVec3d>& get_wgs84_nodes() const { return wgs | |||
{ return wgs84_nodes; } | 84_nodes; } | |||
inline void set_wgs84_nodes( const std::vector<SGVec3d>& n ) | inline void set_wgs84_nodes( const std::vector<SGVec3d>& n ) { wgs84_no | |||
{ wgs84_nodes = n; } | des = n; } | |||
inline const std::vector<SGVec4f>& get_colors() const { return colors; } | inline const std::vector<SGVec4f>& get_colors() const { return colors; } | |||
inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; } | inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; } | |||
inline const std::vector<SGVec3f>& get_normals() const { return normals ; } | inline const std::vector<SGVec3f>& get_normals() const { return normals ; } | |||
inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; } | inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; } | |||
inline const std::vector<SGVec2f>& get_texcoords() const { return texco ords; } | inline const std::vector<SGVec2f>& get_texcoords() const { return texco ords; } | |||
inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; } | inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; } | |||
// Points API | ||||
bool add_point( const SGBinObjectPoint& pt ); | ||||
inline const group_list& get_pts_v() const { return pts_v; } | inline const group_list& get_pts_v() const { return pts_v; } | |||
inline void set_pts_v( const group_list& g ) { pts_v = g; } | ||||
inline const group_list& get_pts_n() const { return pts_n; } | inline const group_list& get_pts_n() const { return pts_n; } | |||
inline void set_pts_n( const group_list& g ) { pts_n = g; } | inline const group_tci_list& get_pts_tcs() const { return pts_tcs; } | |||
inline const group_list& get_pts_c() const { return pts_c; } | inline const group_vai_list& get_pts_vas() const { return pts_vas; } | |||
inline void set_pts_c( const group_list& g ) { pts_c = g; } | ||||
inline const group_list& get_pts_tc() const { return pts_tc; } | ||||
inline void set_pts_tc( const group_list& g ) { pts_tc = g; } | ||||
inline const string_list& get_pt_materials() const { return pt_material s; } | inline const string_list& get_pt_materials() const { return pt_material s; } | |||
inline void set_pt_materials( const string_list& s ) { pt_materials = s ; } | ||||
// Triangles API | ||||
bool add_triangle( const SGBinObjectTriangle& tri ); | ||||
inline const group_list& get_tris_v() const { return tris_v; } | inline const group_list& get_tris_v() const { return tris_v; } | |||
inline void set_tris_v( const group_list& g ) { tris_v = g; } | ||||
inline const group_list& get_tris_n() const { return tris_n; } | inline const group_list& get_tris_n() const { return tris_n; } | |||
inline void set_tris_n( const group_list& g ) { tris_n = g; } | ||||
inline const group_list& get_tris_c() const { return tris_c; } | inline const group_list& get_tris_c() const { return tris_c; } | |||
inline void set_tris_c( const group_list& g ) { tris_c = g; } | inline const group_tci_list& get_tris_tcs() const { return tris_tcs; } | |||
inline const group_list& get_tris_tc() const { return tris_tc; } | inline const group_vai_list& get_tris_vas() const { return tris_vas; } | |||
inline void set_tris_tc( const group_list& g ) { tris_tc = g; } | ||||
inline const string_list& get_tri_materials() const { return tri_materi als; } | inline const string_list& get_tri_materials() const { return tri_materi als; } | |||
inline void set_tri_materials( const string_list& s ) { tri_materials = s; } | ||||
// Strips API (deprecated - read only) | ||||
inline const group_list& get_strips_v() const { return strips_v; } | inline const group_list& get_strips_v() const { return strips_v; } | |||
inline void set_strips_v( const group_list& g ) { strips_v = g; } | ||||
inline const group_list& get_strips_n() const { return strips_n; } | inline const group_list& get_strips_n() const { return strips_n; } | |||
inline void set_strips_n( const group_list& g ) { strips_n = g; } | ||||
inline const group_list& get_strips_c() const { return strips_c; } | inline const group_list& get_strips_c() const { return strips_c; } | |||
inline void set_strips_c( const group_list& g ) { strips_c = g; } | inline const group_tci_list& get_strips_tcs() const { return strips_tcs | |||
; } | ||||
inline const group_list& get_strips_tc() const { return strips_tc; } | inline const group_vai_list& get_strips_vas() const { return strips_vas | |||
inline void set_strips_tc( const group_list& g ) { strips_tc = g; } | ; } | |||
inline const string_list& get_strip_materials() const { return strip_ma terials; } | inline const string_list& get_strip_materials() const { return strip_ma terials; } | |||
inline void set_strip_materials( const string_list& s ) { strip_materia ls = s; } | ||||
// Fans API (deprecated - read only ) | ||||
inline const group_list& get_fans_v() const { return fans_v; } | inline const group_list& get_fans_v() const { return fans_v; } | |||
inline void set_fans_v( const group_list& g ) { fans_v = g; } | ||||
inline const group_list& get_fans_n() const { return fans_n; } | inline const group_list& get_fans_n() const { return fans_n; } | |||
inline void set_fans_n( const group_list& g ) { fans_n = g; } | ||||
inline const group_list& get_fans_c() const { return fans_c; } | inline const group_list& get_fans_c() const { return fans_c; } | |||
inline void set_fans_c( const group_list& g ) { fans_c = g; } | inline const group_tci_list& get_fans_tcs() const { return fans_tcs; } | |||
inline const group_vai_list& get_fans_vas() const { return fans_vas; } | ||||
inline const group_list& get_fans_tc() const { return fans_tc; } | ||||
inline void set_fans_tc( const group_list& g ) { fans_tc = g; } | ||||
inline const string_list& get_fan_materials() const { return fan_materi als; } | inline const string_list& get_fan_materials() const { return fan_materi als; } | |||
inline void set_fan_materials( const string_list& s ) { fan_materials = s; } | ||||
/** | /** | |||
* Read a binary file object and populate the provided structures. | * Read a binary file object and populate the provided structures. | |||
* @param file input file name | * @param file input file name | |||
* @return result of read | * @return result of read | |||
*/ | */ | |||
bool read_bin( const std::string& file ); | bool read_bin( const std::string& file ); | |||
/** | /** | |||
* Write out the structures to a binary file. We assume that the | * Write out the structures to a binary file. We assume that the | |||
End of changes. 29 change blocks. | ||||
66 lines changed or deleted | 134 lines changed or added | |||
sg_path.hxx | sg_path.hxx | |||
---|---|---|---|---|
skipping to change at line 59 | skipping to change at line 59 | |||
class SGPath { | class SGPath { | |||
public: | public: | |||
struct Permissions | struct Permissions | |||
{ | { | |||
bool read : 1; | bool read : 1; | |||
bool write : 1; | bool write : 1; | |||
}; | }; | |||
typedef Permissions (*PermissonChecker)(const SGPath&); | typedef Permissions (*PermissionChecker)(const SGPath&); | |||
/** Default constructor */ | /** Default constructor */ | |||
explicit SGPath(PermissonChecker validator = NULL); | explicit SGPath(PermissionChecker validator = NULL); | |||
/** Copy contructor */ | /** Copy contructor */ | |||
SGPath(const SGPath& p); | SGPath(const SGPath& p); | |||
SGPath& operator=(const SGPath& p); | SGPath& operator=(const SGPath& p); | |||
/** | /** | |||
* Construct a path based on the starting path provided. | * Construct a path based on the starting path provided. | |||
* @param p initial path | * @param p initial path | |||
*/ | */ | |||
SGPath( const std::string& p, PermissonChecker validator = NULL ); | SGPath( const std::string& p, PermissionChecker validator = NULL ); | |||
/** | /** | |||
* Construct a path based on the starting path provided and a relative subpath | * Construct a path based on the starting path provided and a relative subpath | |||
* @param p initial path | * @param p initial path | |||
* @param r relative subpath | * @param r relative subpath | |||
*/ | */ | |||
SGPath( const SGPath& p, | SGPath( const SGPath& p, | |||
const std::string& r, | const std::string& r, | |||
PermissonChecker validator = NULL ); | PermissionChecker validator = NULL ); | |||
/** Destructor */ | /** Destructor */ | |||
~SGPath(); | ~SGPath(); | |||
/** | /** | |||
* Set path to a new value | * Set path to a new value | |||
* @param p new path | * @param p new path | |||
*/ | */ | |||
void set( const std::string& p ); | void set( const std::string& p ); | |||
SGPath& operator= ( const char* p ) { this->set(p); return *this; } | SGPath& operator= ( const char* p ) { this->set(p); return *this; } | |||
bool operator==(const SGPath& other) const; | bool operator==(const SGPath& other) const; | |||
bool operator!=(const SGPath& other) const; | bool operator!=(const SGPath& other) const; | |||
void setPermissonChecker(PermissonChecker validator); | void setPermissionChecker(PermissionChecker validator); | |||
PermissonChecker getPermissonChecker() const; | PermissionChecker getPermissionChecker() const; | |||
/** | /** | |||
* Set if file information (exists, type, mod-time) is cached or | * Set if file information (exists, type, mod-time) is cached or | |||
* retrieved each time it is queried. Caching is enabled by default | * retrieved each time it is queried. Caching is enabled by default | |||
*/ | */ | |||
void set_cached(bool cached); | void set_cached(bool cached); | |||
/** | /** | |||
* Append another piece to the existing path. Inserts a path | * Append another piece to the existing path. Inserts a path | |||
* separator between the existing component and the new component. | * separator between the existing component and the new component. | |||
skipping to change at line 208 | skipping to change at line 208 | |||
std::string str_native() const; | std::string str_native() const; | |||
/** | /** | |||
* Determine if file exists by attempting to fopen it. | * Determine if file exists by attempting to fopen it. | |||
* @return true if file exists, otherwise returns false. | * @return true if file exists, otherwise returns false. | |||
*/ | */ | |||
bool exists() const; | bool exists() const; | |||
/** | /** | |||
* Create the designated directory. | * Create the designated directory. | |||
* | ||||
* @param mode Permissions. See: | ||||
* http://en.wikipedia.org/wiki/File_system_permissions#Numeric_nota | ||||
tion | ||||
* @return 0 on success, or <0 on failure. | * @return 0 on success, or <0 on failure. | |||
*/ | */ | |||
int create_dir(mode_t mode); | int create_dir(mode_t mode = 0755); | |||
/** | /** | |||
* Check if reading file is allowed. Readabilty does not imply the exis tance | * Check if reading file is allowed. Readabilty does not imply the exis tance | |||
* of the file. | * of the file. | |||
* | * | |||
* @note By default all files will be marked as readable. No check is m ade | * @note By default all files will be marked as readable. No check is m ade | |||
* if the operating system allows the given file to be read. Deri ved | * if the operating system allows the given file to be read. Deri ved | |||
* classes may actually implement custom read/write rights. | * classes may actually implement custom read/write rights. | |||
*/ | */ | |||
bool canRead() const; | bool canRead() const; | |||
skipping to change at line 259 | skipping to change at line 262 | |||
*/ | */ | |||
time_t modTime() const; | time_t modTime() const; | |||
/** | /** | |||
* rename the file / directory we point at, to a new name | * rename the file / directory we point at, to a new name | |||
* this may fail if the new location is on a different volume / share, | * this may fail if the new location is on a different volume / share, | |||
* or if the destination already exists, or is not writeable | * or if the destination already exists, or is not writeable | |||
*/ | */ | |||
bool rename(const SGPath& newName); | bool rename(const SGPath& newName); | |||
enum StandardLocation | ||||
{ | ||||
HOME, | ||||
DESKTOP, | ||||
DOWNLOADS, | ||||
DOCUMENTS, | ||||
PICTURES | ||||
}; | ||||
static SGPath standardLocation( StandardLocation type, | ||||
const SGPath& def = SGPath() ); | ||||
/** | /** | |||
* Get a path stored in the environment variable with the given \a name . | * Get a path stored in the environment variable with the given \a name . | |||
* | * | |||
* @param name Name of the environment variable | * @param name Name of the environment variable | |||
* @param def Default path to return if the environment variable does not | * @param def Default path to return if the environment variable does not | |||
* exist or is empty. | * exist or is empty. | |||
*/ | */ | |||
static SGPath fromEnv(const char* name, const SGPath& def = SGPath()); | static SGPath fromEnv(const char* name, const SGPath& def = SGPath()); | |||
/** | /** | |||
skipping to change at line 282 | skipping to change at line 297 | |||
/** | /** | |||
* Get path to the user's desktop directory | * Get path to the user's desktop directory | |||
*/ | */ | |||
static SGPath desktop(const SGPath& def = SGPath()); | static SGPath desktop(const SGPath& def = SGPath()); | |||
/** | /** | |||
* Get path to the user's documents directory | * Get path to the user's documents directory | |||
*/ | */ | |||
static SGPath documents(const SGPath& def = SGPath()); | static SGPath documents(const SGPath& def = SGPath()); | |||
private: | private: | |||
void fix(); | void fix(); | |||
void validate() const; | void validate() const; | |||
void checkAccess() const; | void checkAccess() const; | |||
std::string path; | std::string path; | |||
PermissonChecker _permission_checker; | PermissionChecker _permission_checker; | |||
mutable bool _cached : 1; | mutable bool _cached : 1; | |||
mutable bool _rwCached : 1; | mutable bool _rwCached : 1; | |||
bool _cacheEnabled : 1; ///< cacheing can be disbled if required | bool _cacheEnabled : 1; ///< cacheing can be disbled if required | |||
mutable bool _canRead : 1; | mutable bool _canRead : 1; | |||
mutable bool _canWrite : 1; | mutable bool _canWrite : 1; | |||
mutable bool _exists : 1; | mutable bool _exists : 1; | |||
mutable bool _isDir : 1; | mutable bool _isDir : 1; | |||
mutable bool _isFile : 1; | mutable bool _isFile : 1; | |||
mutable time_t _modTime; | mutable time_t _modTime; | |||
End of changes. 10 change blocks. | ||||
8 lines changed or deleted | 25 lines changed or added | |||
sky.hxx | sky.hxx | |||
---|---|---|---|---|
skipping to change at line 223 | skipping to change at line 223 | |||
typedef layer_list_type::const_iterator layer_list_const_iterator; | typedef layer_list_type::const_iterator layer_list_const_iterator; | |||
// components of the sky | // components of the sky | |||
SGSharedPtr<SGSkyDome> dome; | SGSharedPtr<SGSkyDome> dome; | |||
SGSharedPtr<SGSun> oursun; | SGSharedPtr<SGSun> oursun; | |||
SGSharedPtr<SGMoon> moon; | SGSharedPtr<SGMoon> moon; | |||
SGSharedPtr<SGStars> planets; | SGSharedPtr<SGStars> planets; | |||
SGSharedPtr<SGStars> stars; | SGSharedPtr<SGStars> stars; | |||
layer_list_type cloud_layers; | layer_list_type cloud_layers; | |||
osg::ref_ptr<osg::Group> pre_root, cloud_root; | osg::ref_ptr<osg::Group> pre_root, pre_transform; | |||
osg::ref_ptr<osg::Group> pre_transform; | osg::ref_ptr<osg::Switch> cloud_root; | |||
osg::ref_ptr<osg::MatrixTransform> _ephTransform; | osg::ref_ptr<osg::MatrixTransform> _ephTransform; | |||
SGPath tex_path; | SGPath tex_path; | |||
// visibility | // visibility | |||
float visibility; | float visibility; | |||
float effective_visibility; | float effective_visibility; | |||
int in_cloud; | int in_cloud; | |||
skipping to change at line 346 | skipping to change at line 346 | |||
/** | /** | |||
* Modify the given visibility based on cloud layers, thickness, | * Modify the given visibility based on cloud layers, thickness, | |||
* transition range, and simulated "puffs". See discussion in detailed | * transition range, and simulated "puffs". See discussion in detailed | |||
* class description. | * class description. | |||
* @param alt current altitude | * @param alt current altitude | |||
* @param time_factor amount of time since modify_vis() last called so | * @param time_factor amount of time since modify_vis() last called so | |||
* we can scale effect rates properly despite variable frame rat es. | * we can scale effect rates properly despite variable frame rat es. | |||
*/ | */ | |||
void modify_vis( float alt, float time_factor ); | void modify_vis( float alt, float time_factor ); | |||
osg::Node* getPreRoot() { return pre_root.get(); } | osg::Group* getPreRoot() { return pre_root.get(); } | |||
osg::Node* getCloudRoot() { return cloud_root.get(); } | osg::Group* getCloudRoot() { return cloud_root.get(); } | |||
/** | /** | |||
* Specify the texture path (optional, defaults to current directory) | * Specify the texture path (optional, defaults to current directory) | |||
* @param path base path to texture locations | * @param path base path to texture locations | |||
*/ | */ | |||
void texture_path( const string& path ); | void texture_path( const std::string& path ); | |||
/** | /** | |||
* Get the current sun color | * Get the current sun color | |||
*/ | */ | |||
inline SGVec4f get_sun_color() { return oursun->get_color(); } | inline SGVec4f get_sun_color() { return oursun->get_color(); } | |||
/** | /** | |||
* Get the current scene color | * Get the current scene color | |||
*/ | */ | |||
inline SGVec4f get_scene_color() { return oursun->get_scene_color(); } | inline SGVec4f get_scene_color() { return oursun->get_scene_color(); } | |||
skipping to change at line 465 | skipping to change at line 465 | |||
void set_3dCloudUseImpostors(bool imp); | void set_3dCloudUseImpostors(bool imp); | |||
/** Get 3D cloud wrapping */ | /** Get 3D cloud wrapping */ | |||
bool get_3dCloudWrap() const; | bool get_3dCloudWrap() const; | |||
/** Set 3D cloud wrapping | /** Set 3D cloud wrapping | |||
* @param wrap whether to wrap 3D clouds | * @param wrap whether to wrap 3D clouds | |||
*/ | */ | |||
void set_3dCloudWrap(bool wrap); | void set_3dCloudWrap(bool wrap); | |||
void set_clouds_enabled(bool enabled); | ||||
}; | }; | |||
#endif // _SG_SKY_HXX | #endif // _SG_SKY_HXX | |||
End of changes. 4 change blocks. | ||||
5 lines changed or deleted | 7 lines changed or added | |||
strutils.hxx | strutils.hxx | |||
---|---|---|---|---|
skipping to change at line 179 | skipping to change at line 179 | |||
* (no-op on other platforms) | * (no-op on other platforms) | |||
*/ | */ | |||
std::string convertWindowsLocal8BitToUtf8(const std::string& a); | std::string convertWindowsLocal8BitToUtf8(const std::string& a); | |||
#if defined(SG_WINDOWS) | #if defined(SG_WINDOWS) | |||
typedef std::vector<wchar_t> WCharVec; | typedef std::vector<wchar_t> WCharVec; | |||
WCharVec convertUtf8ToWString(const std::string& a); | WCharVec convertUtf8ToWString(const std::string& a); | |||
#endif | #endif | |||
/** | /** | |||
* Get md5 hash of raw data. | ||||
*/ | ||||
std::string md5(const unsigned char* data, size_t num); | ||||
std::string md5(const char* data, size_t num); | ||||
std::string md5(const std::string& str); | ||||
/** | ||||
* convert base-64 encoded data to raw bytes (possibly with embedded | * convert base-64 encoded data to raw bytes (possibly with embedded | |||
* NULs). Throws an exception if input data is not base64, or is | * NULs). Throws an exception if input data is not base64, or is | |||
* malformed | * malformed | |||
*/ | */ | |||
void decodeBase64(const std::string& a, std::vector<unsigned char>& o utput); | void decodeBase64(const std::string& a, std::vector<unsigned char>& o utput); | |||
/** | /** | |||
* convert bytes to hexadecimal equivalent | * convert bytes to hexadecimal equivalent | |||
*/ | */ | |||
std::string encodeHex(const std::string& bytes); | std::string encodeHex(const std::string& bytes); | |||
End of changes. 1 change blocks. | ||||
0 lines changed or deleted | 7 lines changed or added | |||
subsystem_mgr.hxx | subsystem_mgr.hxx | |||
---|---|---|---|---|
// Written by David Megginson, started 2000-12 | // Written by David Megginson, started 2000-12 | |||
// | // | |||
// Copyright (C) 2000 David Megginson, david@megginson.com | // Copyright (C) 2000 David Megginson, david@megginson.com | |||
// | // | |||
// This program is free software; you can redistribute it and/or | // This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the GNU General Public License as | // modify it under the terms of the GNU General Public License as | |||
// published by the Free Software Foundation; either version 2 of the | // published by the Free Software Foundation; either version 2 of the | |||
// License, or (at your option) any later version. | // License, or (at your option) any later version. | |||
// | // | |||
// This program is distributed in the hope that it will be useful, but | // This program is distributed in the hope that it will be useful, but | |||
skipping to change at line 55 | skipping to change at line 54 | |||
const std::string& getName() const { return eventName; } | const std::string& getName() const { return eventName; } | |||
const SGTimeStamp& getTime() const { return time; } | const SGTimeStamp& getTime() const { return time; } | |||
}; | }; | |||
class SampleStatistic; | class SampleStatistic; | |||
typedef std::vector<TimingInfo> eventTimeVec; | typedef std::vector<TimingInfo> eventTimeVec; | |||
typedef std::vector<TimingInfo>::iterator eventTimeVecIterator; | typedef std::vector<TimingInfo>::iterator eventTimeVecIterator; | |||
typedef void (*SGSubsystemTimingCb)(void* userData, const std::string& name , SampleStatistic* pStatistic); | typedef void (*SGSubsystemTimingCb)(void* userData, const std::string& name , SampleStatistic* pStatistic); | |||
/** | /** | |||
* Basic interface for all FlightGear subsystems. | * Basic interface for all FlightGear subsystems. | |||
* | * | |||
* <p>This is an abstract interface that all FlightGear subsystems | * <p>This is an abstract interface that all FlightGear subsystems | |||
* will eventually implement. It defines the basic operations for | * will eventually implement. It defines the basic operations for | |||
* each subsystem: initialization, property binding and unbinding, and | * each subsystem: initialization, property binding and unbinding, and | |||
* updating. Interfaces may define additional methods, but the | * updating. Interfaces may define additional methods, but the | |||
* preferred way of exchanging information with other subsystems is | * preferred way of exchanging information with other subsystems is | |||
* through the property tree.</p> | * through the property tree.</p> | |||
* | * | |||
skipping to change at line 275 | skipping to change at line 275 | |||
bool _suspended; | bool _suspended; | |||
eventTimeVec timingInfo; | eventTimeVec timingInfo; | |||
static SGSubsystemTimingCb reportTimingCb; | static SGSubsystemTimingCb reportTimingCb; | |||
static void* reportTimingUserData; | static void* reportTimingUserData; | |||
}; | }; | |||
typedef SGSharedPtr<SGSubsystem> SGSubsystemRef; | typedef SGSharedPtr<SGSubsystem> SGSubsystemRef; | |||
/** | /** | |||
* A group of FlightGear subsystems. | * A group of FlightGear subsystems. | |||
*/ | */ | |||
class SGSubsystemGroup : public SGSubsystem | class SGSubsystemGroup : public SGSubsystem | |||
{ | { | |||
public: | public: | |||
SGSubsystemGroup (); | SGSubsystemGroup (); | |||
virtual ~SGSubsystemGroup (); | virtual ~SGSubsystemGroup (); | |||
skipping to change at line 304 | skipping to change at line 305 | |||
virtual void resume (); | virtual void resume (); | |||
virtual bool is_suspended () const; | virtual bool is_suspended () const; | |||
virtual void set_subsystem (const std::string &name, | virtual void set_subsystem (const std::string &name, | |||
SGSubsystem * subsystem, | SGSubsystem * subsystem, | |||
double min_step_sec = 0); | double min_step_sec = 0); | |||
virtual SGSubsystem * get_subsystem (const std::string &name); | virtual SGSubsystem * get_subsystem (const std::string &name); | |||
virtual void remove_subsystem (const std::string &name); | virtual void remove_subsystem (const std::string &name); | |||
virtual bool has_subsystem (const std::string &name) const; | virtual bool has_subsystem (const std::string &name) const; | |||
/** | ||||
* Remove all subsystems. | ||||
*/ | ||||
virtual void clearSubsystems(); | ||||
void reportTiming(void); | void reportTiming(void); | |||
/** | /** | |||
* | * | |||
*/ | */ | |||
void set_fixed_update_time(double fixed_dt); | void set_fixed_update_time(double fixed_dt); | |||
/** | /** | |||
* retrive list of member subsystem names | * retrive list of member subsystem names | |||
*/ | */ | |||
skipping to change at line 330 | skipping to change at line 336 | |||
typedef std::vector<Member *> MemberVec; | typedef std::vector<Member *> MemberVec; | |||
MemberVec _members; | MemberVec _members; | |||
double _fixedUpdateTime; | double _fixedUpdateTime; | |||
double _updateTimeRemainder; | double _updateTimeRemainder; | |||
/// index of the member we are currently init-ing | /// index of the member we are currently init-ing | |||
unsigned int _initPosition; | unsigned int _initPosition; | |||
}; | }; | |||
/** | /** | |||
* Manage subsystems for FlightGear. | * Manage subsystems for FlightGear. | |||
* | * | |||
* This top-level subsystem will eventually manage all of the | * This top-level subsystem will eventually manage all of the | |||
* subsystems in FlightGear: it broadcasts its life-cycle events | * subsystems in FlightGear: it broadcasts its life-cycle events | |||
* (init, bind, etc.) to all of the subsystems it manages. Subsystems | * (init, bind, etc.) to all of the subsystems it manages. Subsystems | |||
* are grouped to guarantee order of initialization and execution -- | * are grouped to guarantee order of initialization and execution -- | |||
* currently, the only two groups are INIT and GENERAL, but others | * currently, the only two groups are INIT and GENERAL, but others | |||
* will appear in the future. | * will appear in the future. | |||
* | * | |||
End of changes. 5 change blocks. | ||||
1 lines changed or deleted | 8 lines changed or added | |||
terrasync.hxx | terrasync.hxx | |||
---|---|---|---|---|
skipping to change at line 59 | skipping to change at line 59 | |||
virtual void bind(); | virtual void bind(); | |||
virtual void unbind(); | virtual void unbind(); | |||
virtual void update(double); | virtual void update(double); | |||
/// notify terrasync that the sim was repositioned, as opposed to | /// notify terrasync that the sim was repositioned, as opposed to | |||
/// us travelling in a direction. Avoid last_lat / last_lon blocking | /// us travelling in a direction. Avoid last_lat / last_lon blocking | |||
/// certain tiles when we reposition. | /// certain tiles when we reposition. | |||
void reposition(); | void reposition(); | |||
bool isIdle(); | bool isIdle(); | |||
bool schedulePosition(int lat, int lon); | ||||
bool scheduleTile(const SGBucket& bucket); | bool scheduleTile(const SGBucket& bucket); | |||
void syncAreaByPath(const std::string& aPath); | ||||
void setRoot(SGPropertyNode_ptr root); | void setRoot(SGPropertyNode_ptr root); | |||
/// retrive the associated log object, for displaying log | /// retrive the associated log object, for displaying log | |||
/// output somewhere (a UI, presumably) | /// output somewhere (a UI, presumably) | |||
BufferedLogCallback* log() const | BufferedLogCallback* log() const | |||
{ return _log; } | { return _log; } | |||
/** | /** | |||
* Test if a scenery directory is queued or actively syncing. | * Test if a scenery directory is queued or actively syncing. | |||
* File path is the tile name, eg 'e001n52' or 'w003n56'. Will return t rue | * File path is the tile name, eg 'e001n52' or 'w003n56'. Will return t rue | |||
* if either the Terrain or Objects variant is being synced. | * if either the Terrain or Objects variant is being synced. | |||
* | * | |||
*/ | */ | |||
bool isTileDirPending(const std::string& sceneryDir) const; | bool isTileDirPending(const std::string& sceneryDir) const; | |||
void scheduleDataDir(const std::string& dataDir); | void scheduleDataDir(const std::string& dataDir); | |||
bool isDataDirPending(const std::string& dataDir) const; | bool isDataDirPending(const std::string& dataDir) const; | |||
protected: | protected: | |||
void syncAirportsModels(); | void syncAirportsModels(); | |||
void syncArea(int lat, int lon); | ||||
void syncAreas(int lat, int lon, int lat_dir, int lon_dir); | ||||
void syncAreaByPath(const std::string& aPath); | ||||
class SvnThread; | class SvnThread; | |||
private: | private: | |||
SvnThread* _svnThread; | SvnThread* _svnThread; | |||
int last_lat; | ||||
int last_lon; | ||||
SGPropertyNode_ptr _terraRoot; | SGPropertyNode_ptr _terraRoot; | |||
SGPropertyNode_ptr _stalledNode; | SGPropertyNode_ptr _stalledNode; | |||
SGPropertyNode_ptr _cacheHits; | SGPropertyNode_ptr _cacheHits; | |||
// we manually bind+init TerraSync during early startup | // we manually bind+init TerraSync during early startup | |||
// to get better overlap of slow operations (Shared Models sync | // to get better overlap of slow operations (Shared Models sync | |||
// and nav-cache rebuild). As a result we need to track the bind/init | // and nav-cache rebuild). As a result we need to track the bind/init | |||
// state explicitly to avoid duplicate calls. | // state explicitly to avoid duplicate calls. | |||
bool _bound, _inited; | bool _bound, _inited; | |||
End of changes. 4 change blocks. | ||||
7 lines changed or deleted | 2 lines changed or added | |||
tiedpropertylist.hxx | tiedpropertylist.hxx | |||
---|---|---|---|---|
skipping to change at line 54 | skipping to change at line 54 | |||
assert(empty()); | assert(empty()); | |||
} | } | |||
} | } | |||
void setRoot( SGPropertyNode_ptr root ) { _root = root; } | void setRoot( SGPropertyNode_ptr root ) { _root = root; } | |||
SGPropertyNode_ptr getRoot() const { return _root; } | SGPropertyNode_ptr getRoot() const { return _root; } | |||
template<typename T> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, c onst SGRawValue<T> &rawValue, bool useDefault = true ) { | template<typename T> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, c onst SGRawValue<T> &rawValue, bool useDefault = true ) { | |||
bool success = node->tie( rawValue, useDefault ); | bool success = node->tie( rawValue, useDefault ); | |||
if( success ) { | if( success ) { | |||
SG_LOG( SG_GENERAL, SG_DEBUG, "Tied " << node->getPath() ); | ||||
push_back( node ); | push_back( node ); | |||
} else { | } else { | |||
#if PROPS_STANDALONE | #if PROPS_STANDALONE | |||
cerr << "Failed to tie property " << node->getPath() << endl; | cerr << "Failed to tie property " << node->getPath() << endl; | |||
#else | #else | |||
SG_LOG(SG_GENERAL, SG_WARN, "Failed to tie property " << node-> getPath() ); | SG_LOG(SG_GENERAL, SG_WARN, "Failed to tie property " << node-> getPath() ); | |||
#endif | #endif | |||
} | } | |||
return node; | return node; | |||
} | } | |||
skipping to change at line 128 | skipping to change at line 127 | |||
template <class T, class V> SGPropertyNode_ptr Tie( const char * relati ve_path, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(i nt, V) = 0, bool useDefault = true) { | template <class T, class V> SGPropertyNode_ptr Tie( const char * relati ve_path, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(i nt, V) = 0, bool useDefault = true) { | |||
return Tie( _root->getNode( relative_path, true ), SGRawValueMethod sIndexed<T,V>(*obj, index, getter, setter), useDefault); | return Tie( _root->getNode( relative_path, true ), SGRawValueMethod sIndexed<T,V>(*obj, index, getter, setter), useDefault); | |||
} | } | |||
template <class T, class V> SGPropertyNode_ptr Tie( const char * relati ve_path, int prop_index, T * obj, int index, V (T::*getter)(int) const, voi d (T::*setter)(int, V) = 0, bool useDefault = true) { | template <class T, class V> SGPropertyNode_ptr Tie( const char * relati ve_path, int prop_index, T * obj, int index, V (T::*getter)(int) const, voi d (T::*setter)(int, V) = 0, bool useDefault = true) { | |||
return Tie( _root->getNode( relative_path,prop_index,true ), SGRawV alueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault); | return Tie( _root->getNode( relative_path,prop_index,true ), SGRawV alueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault); | |||
} | } | |||
void Untie() { | void Untie() { | |||
while( ! empty() ) { | while( ! empty() ) { | |||
SG_LOG( SG_GENERAL, SG_DEBUG, "untie of " << back()->getPath() ); | ||||
back()->untie(); | back()->untie(); | |||
pop_back(); | pop_back(); | |||
} | } | |||
} | } | |||
void setAttribute (SGPropertyNode::Attribute attr, bool state) | void setAttribute (SGPropertyNode::Attribute attr, bool state) | |||
{ | { | |||
for (std::vector<SGPropertyNode_ptr>::iterator it=begin() ; it < en d(); it++ ) | for (std::vector<SGPropertyNode_ptr>::iterator it=begin() ; it < en d(); it++ ) | |||
(*it)->setAttribute(attr, state); | (*it)->setAttribute(attr, state); | |||
} | } | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 0 lines changed or added | |||
to_nasal_helper.hxx | to_nasal_helper.hxx | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
// | // | |||
// You should have received a copy of the GNU Library General Public | // You should have received a copy of the GNU Library General Public | |||
// License along with this library; if not, write to the Free Software | // License along with this library; if not, write to the Free Software | |||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, U SA | |||
#ifndef SG_TO_NASAL_HELPER_HXX_ | #ifndef SG_TO_NASAL_HELPER_HXX_ | |||
#define SG_TO_NASAL_HELPER_HXX_ | #define SG_TO_NASAL_HELPER_HXX_ | |||
#include "nasal_traits.hxx" | #include "nasal_traits.hxx" | |||
#include <simgear/math/SGMath.hxx> | ||||
#include <simgear/math/SGRect.hxx> | ||||
#include <simgear/nasal/nasal.h> | #include <simgear/nasal/nasal.h> | |||
#include <boost/function/function_fwd.hpp> | #include <boost/function/function_fwd.hpp> | |||
#include <boost/utility/enable_if.hpp> | #include <boost/utility/enable_if.hpp> | |||
#include <boost/call_traits.hpp> | #include <boost/call_traits.hpp> | |||
#include <boost/type_traits.hpp> | #include <boost/type_traits.hpp> | |||
#include <map> | #include <map> | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
skipping to change at line 145 | skipping to change at line 147 | |||
return ret; | return ret; | |||
} | } | |||
//----------------------------------------------------------------------- ----- | //----------------------------------------------------------------------- ----- | |||
template<class Vec2> | template<class Vec2> | |||
typename boost::enable_if<is_vec2<Vec2>, naRef>::type | typename boost::enable_if<is_vec2<Vec2>, naRef>::type | |||
to_nasal_helper(naContext c, const Vec2& vec) | to_nasal_helper(naContext c, const Vec2& vec) | |||
{ | { | |||
// We take just double because in Nasal every number is represented as | // We take just double because in Nasal every number is represented as | |||
// double | // double | |||
double nasal_vec[2] = {vec[0], vec[1]}; | double nasal_vec[2] = { | |||
static_cast<double>(vec[0]), | ||||
static_cast<double>(vec[1]) | ||||
}; | ||||
return to_nasal_helper(c, nasal_vec); | return to_nasal_helper(c, nasal_vec); | |||
} | } | |||
//----------------------------------------------------------------------- ----- | //----------------------------------------------------------------------- ----- | |||
template<class T> | ||||
naRef to_nasal_helper(naContext c, const SGRect<T>& rect) | ||||
{ | ||||
std::vector<double> vec(4); | ||||
vec[0] = rect.x(); | ||||
vec[1] = rect.y(); | ||||
vec[2] = rect.width(); | ||||
vec[3] = rect.height(); | ||||
return to_nasal_helper(c, vec); | ||||
} | ||||
//----------------------------------------------------------------------- | ||||
----- | ||||
template<class Value> | template<class Value> | |||
naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& ma p) | naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& ma p) | |||
{ | { | |||
naRef hash = naNewHash(c); | naRef hash = naNewHash(c); | |||
typedef typename boost::call_traits<Value>::param_type param_type; | typedef typename boost::call_traits<Value>::param_type param_type; | |||
typedef typename std::map<std::string, Value>::const_iterator map_itera tor; | typedef typename std::map<std::string, Value>::const_iterator map_itera tor; | |||
for( map_iterator it = map.begin(); it != map.end(); ++it ) | for( map_iterator it = map.begin(); it != map.end(); ++it ) | |||
naHash_set | naHash_set | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 20 lines changed or added | |||
version.h | version.h | |||
---|---|---|---|---|
#define SIMGEAR_VERSION 3.0.0 | #define SIMGEAR_VERSION 3.2.0 | |||
End of changes. 1 change blocks. | ||||
lines changed or deleted | lines changed or added | |||