This commit is contained in:
gallaert
2018-03-04 19:47:48 +00:00
57 changed files with 899 additions and 194 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
// 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>
// //
+9 -11
View File
@@ -71,18 +71,18 @@ namespace canvas
public osg::NodeCallback public osg::NodeCallback
{ {
public: public:
CullCallback(const CanvasWeakPtr& canvas); explicit CullCallback(const CanvasWeakPtr& canvas);
private: private:
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); void operator()(osg::Node* node, osg::NodeVisitor* nv) override;
}; };
typedef osg::ref_ptr<CullCallback> CullCallbackPtr; typedef osg::ref_ptr<CullCallback> CullCallbackPtr;
Canvas(SGPropertyNode* node); explicit Canvas(SGPropertyNode* node);
virtual ~Canvas(); virtual ~Canvas();
virtual void onDestroy(); void onDestroy() override;
void setCanvasMgr(CanvasMgr* canvas_mgr); void setCanvasMgr(CanvasMgr* canvas_mgr);
CanvasMgr* getCanvasMgr() const; CanvasMgr* getCanvasMgr() const;
@@ -184,11 +184,9 @@ namespace canvas
bool propagateEvent( EventPtr const& event, bool propagateEvent( EventPtr const& event,
EventPropagationPath const& path ); EventPropagationPath const& path );
virtual void childAdded( SGPropertyNode * parent, void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override;
SGPropertyNode * child ); void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override;
virtual void childRemoved( SGPropertyNode * parent, void valueChanged(SGPropertyNode * node) override;
SGPropertyNode * child );
virtual void valueChanged (SGPropertyNode * node);
osg::Texture2D* getTexture() const; osg::Texture2D* getTexture() const;
@@ -254,8 +252,8 @@ namespace canvas
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;
}; };
} // namespace canvas } // namespace canvas
+5 -4
View File
@@ -1,4 +1,5 @@
// Canvas Event for event model similar to DOM Level 3 Event Model ///@file
/// Canvas Event for event model similar to DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -125,10 +126,10 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string Event::typeToStr(int type) std::string Event::typeToStr(int type)
{ {
TypeMap const& type_map = getTypeMap(); auto const& map_by_id = getTypeMap().by<id>();
TypeMap::map_by<id>::const_iterator it = type_map.by<id>().find(type); auto it = map_by_id.find(type);
if( it == type_map.by<id>().end() ) if( it == map_by_id.end() )
return "unknown"; return "unknown";
return it->second; return it->second;
} }
+12
View File
@@ -65,6 +65,11 @@ namespace canvas
// of the actual event instances. // of the actual event instances.
virtual ~Event(); virtual ~Event();
/**
* Clone event and set to the given type (Same type if not specified)
*/
virtual Event* clone(int type = 0) const = 0;
/** /**
* Get whether this events support bubbling * Get whether this events support bubbling
*/ */
@@ -110,7 +115,14 @@ namespace canvas
*/ */
bool defaultPrevented() const; bool defaultPrevented() const;
/**
* Register a new type string or get the id of an existing type string
*
* @param type Type string
* @return Id of the given @a type
*/
static int getOrRegisterType(const std::string& type); static int getOrRegisterType(const std::string& type);
static int strToType(const std::string& type); static int strToType(const std::string& type);
static std::string typeToStr(int type); static std::string typeToStr(int type);
+8 -3
View File
@@ -1,4 +1,5 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model ///@file
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,9 +18,11 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h> #include <simgear_config.h>
#include "CanvasEventManager.hxx" #include "CanvasEventManager.hxx"
#include <simgear/canvas/events/MouseEvent.hxx> #include "elements/CanvasElement.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx> #include "events/MouseEvent.hxx"
#include <cmath> #include <cmath>
namespace simgear namespace simgear
@@ -114,6 +117,8 @@ namespace canvas
return handled; return handled;
} }
case Event::DRAG: case Event::DRAG:
case Event::DRAG_START:
case Event::DRAG_END:
if( !_last_mouse_down.valid() ) if( !_last_mouse_down.valid() )
return false; return false;
else else
+2 -1
View File
@@ -1,4 +1,5 @@
// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model ///@file
/// Manage event handling inside a Canvas similar to the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+4 -1
View File
@@ -1,4 +1,5 @@
// Mapping between canvas gui Event types and their names ///@file
/// Mapping between canvas gui Event types and their names
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -25,6 +26,8 @@ ENUM_MAPPING(MOUSE_UP, "mouseup", MouseEvent)
ENUM_MAPPING(CLICK, "click", MouseEvent) ENUM_MAPPING(CLICK, "click", MouseEvent)
ENUM_MAPPING(DBL_CLICK, "dblclick", MouseEvent) ENUM_MAPPING(DBL_CLICK, "dblclick", MouseEvent)
ENUM_MAPPING(DRAG, "drag", MouseEvent) ENUM_MAPPING(DRAG, "drag", MouseEvent)
ENUM_MAPPING(DRAG_START, "dragstart", MouseEvent)
ENUM_MAPPING(DRAG_END, "dragend", MouseEvent)
ENUM_MAPPING(WHEEL, "wheel", MouseEvent) ENUM_MAPPING(WHEEL, "wheel", MouseEvent)
ENUM_MAPPING(MOUSE_MOVE, "mousemove", MouseEvent) ENUM_MAPPING(MOUSE_MOVE, "mousemove", MouseEvent)
ENUM_MAPPING(MOUSE_OVER, "mouseover", MouseEvent) ENUM_MAPPING(MOUSE_OVER, "mouseover", MouseEvent)
+5 -3
View File
@@ -1,5 +1,6 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal ///@file
// of the DOM Level 3 Event Model /// Visitor for traversing a canvas element hierarchy similar to the traversal
/// of the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -18,9 +19,10 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h> #include <simgear_config.h>
#include "CanvasEvent.hxx" #include "CanvasEvent.hxx"
#include "CanvasEventVisitor.hxx" #include "CanvasEventVisitor.hxx"
#include <simgear/canvas/elements/CanvasElement.hxx> #include "elements/CanvasElement.hxx"
namespace simgear namespace simgear
{ {
+3 -2
View File
@@ -1,5 +1,6 @@
// Visitor for traversing a canvas element hierarchy similar to the traversal ///@file
// of the DOM Level 3 Event Model /// Visitor for traversing a canvas element hierarchy similar to the traversal
/// of the DOM Level 3 Event Model
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+3 -3
View File
@@ -1,4 +1,5 @@
// Canvas with 2D rendering API ///@file
/// Canvas with 2D rendering API
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,12 +18,11 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h> #include <simgear_config.h>
#include "CanvasMgr.hxx" #include "CanvasMgr.hxx"
#include "Canvas.hxx" #include "Canvas.hxx"
#include "CanvasEventManager.hxx" #include "CanvasEventManager.hxx"
#include <boost/bind.hpp>
namespace simgear namespace simgear
{ {
namespace canvas namespace canvas
+3 -2
View File
@@ -1,4 +1,5 @@
// Canvas with 2D rendering API ///@file
/// Canvas with 2D rendering API
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -61,7 +62,7 @@ namespace canvas
protected: protected:
virtual void elementCreated(PropertyBasedElementPtr element); void elementCreated(PropertyBasedElementPtr element) override;
}; };
} // namespace canvas } // namespace canvas
+2 -1
View File
@@ -1,4 +1,5 @@
// Canvas placement for placing a canvas texture onto osg objects. ///@file
/// Canvas placement for placing a canvas texture onto osg 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.
+2 -2
View File
@@ -1,5 +1,5 @@
///@file ///@file
/// Placement for putting a canvas texture onto OpenSceneGraph objects. /// 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.
@@ -60,7 +60,7 @@ namespace canvas
*/ */
void setCaptureEvents(bool enable); void setCaptureEvents(bool enable);
virtual bool childChanged(SGPropertyNode* child); bool childChanged(SGPropertyNode* child) override;
protected: protected:
typedef SGSharedPtr<SGPickCallback> PickCallbackPtr; typedef SGSharedPtr<SGPickCallback> PickCallbackPtr;
+2 -1
View File
@@ -1,4 +1,5 @@
// Base class for canvas placements ///@file
/// Base class for canvas placements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+4 -4
View File
@@ -1,4 +1,5 @@
// Base class for canvas placements ///@file
/// Base class for canvas placements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -40,9 +41,8 @@ namespace canvas
protected: protected:
SGPropertyNode_ptr _node; SGPropertyNode_ptr _node;
private: Placement(const Placement&) = delete;
Placement(const Placement&) /* = delete */; Placement& operator=(const Placement&) = delete;
Placement& operator=(const Placement&) /* = delete */;
}; };
} // namespace canvas } // namespace canvas
+6 -1
View File
@@ -1,4 +1,5 @@
// Adapter for using the canvas with different applications ///@file
/// Adapter for using the canvas with different applications
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -29,6 +30,10 @@ namespace HTTP { class Client; }
namespace canvas namespace canvas
{ {
/**
* Provides access to different required systems of the application to the
* Canvas
*/
class SystemAdapter class SystemAdapter
{ {
public: public:
+15 -1
View File
@@ -1,4 +1,5 @@
// Window for placing a Canvas onto it (for dialogs, menus, etc.) ///@file
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -212,6 +213,19 @@ namespace canvas
_resize_left = getRegion().l() + offset.x(); _resize_left = getRegion().l() + offset.x();
} }
//----------------------------------------------------------------------------
bool Window::handleEvent(const EventPtr& event)
{
if( auto mouse_event = dynamic_cast<MouseEvent*>(event.get()) )
{
mouse_event->local_pos =
mouse_event->client_pos =
mouse_event->screen_pos - toOsg(getPosition());
}
return Image::handleEvent(event);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Window::parseDecorationBorder(const std::string& str) void Window::parseDecorationBorder(const std::string& str)
{ {
+4 -1
View File
@@ -1,4 +1,5 @@
// Window for placing a Canvas onto it (for dialogs, menus, etc.) ///@file
/// Window for placing a Canvas onto it (for dialogs, menus, etc.)
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -96,6 +97,8 @@ namespace canvas
void handleResize( uint8_t mode, void handleResize( uint8_t mode,
const osg::Vec2f& offset = osg::Vec2f() ); const osg::Vec2f& offset = osg::Vec2f() );
bool handleEvent(const EventPtr& event) override;
protected: protected:
enum Attributes enum Attributes
+5 -4
View File
@@ -1,4 +1,5 @@
// Owner Drawn Gauge helper class ///@file
/// Owner Drawn Gauge helper class
// //
// Written by Harald JOHNSEN, started May 2005. // Written by Harald JOHNSEN, started May 2005.
// //
@@ -6,9 +7,9 @@
// //
// Ported to OSG by Tim Moore - Jun 2007 // Ported to OSG by Tim Moore - Jun 2007
// //
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012 // Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing // 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and
// the texture in the scene by certain filter criteria // placing the texture in the scene by certain filter criteria.
// //
// 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
+5 -4
View File
@@ -1,4 +1,5 @@
// Owner Drawn Gauge helper class ///@file
/// Owner Drawn Gauge helper class
// //
// Written by Harald JOHNSEN, started May 2005. // Written by Harald JOHNSEN, started May 2005.
// //
@@ -6,9 +7,9 @@
// //
// Ported to OSG by Tim Moore - Jun 2007 // Ported to OSG by Tim Moore - Jun 2007
// //
// Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April 2012 // Heavily modified to be usable for the 2d Canvas by Thomas Geymayer - April
// Supports now multisampling/mipmapping, usage of the stencil buffer and placing // 2012 Supports now multisampling/mipmapping, usage of the stencil buffer and
// the texture in the scene by certain filter criteria // placing the texture in the scene by certain filter criteria.
// //
// 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
+2 -1
View File
@@ -1,4 +1,5 @@
// osg::Operation to initialize the OpenVG context used for path rendering ///@file
/// osg::Operation to initialize the OpenVG context used for path rendering
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+2 -1
View File
@@ -1,4 +1,5 @@
// osg::Operation to initialize the OpenVG context used for path rendering ///@file
/// osg::Operation to initialize the OpenVG context used for path rendering
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+2 -1
View File
@@ -1,4 +1,5 @@
// Canvas forward declarations ///@file
/// Canvas forward declarations
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+3 -3
View File
@@ -1,4 +1,5 @@
// Interface for 2D Canvas element ///@file
/// Interface for 2D Canvas element
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -271,8 +272,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Element::setFocus() void Element::setFocus()
{ {
CanvasPtr canvas = _canvas.lock(); if( auto canvas = _canvas.lock() )
if( canvas )
canvas->setFocusElement(this); canvas->setFocusElement(this);
} }
+6 -8
View File
@@ -95,7 +95,7 @@ namespace canvas
* *
*/ */
virtual ~Element() = 0; virtual ~Element() = 0;
virtual void onDestroy(); void onDestroy() override;
ElementPtr getParent() const; ElementPtr getParent() const;
CanvasWeakPtr getCanvas() const; CanvasWeakPtr getCanvas() const;
@@ -105,7 +105,7 @@ namespace canvas
* *
* @param dt Frame time in seconds * @param dt Frame time in seconds
*/ */
virtual void update(double dt); void update(double dt) override;
bool addEventListener(const std::string& type, const EventListener& cb); bool addEventListener(const std::string& type, const EventListener& cb);
virtual void clearEventListener(); virtual void clearEventListener();
@@ -154,11 +154,9 @@ namespace canvas
*/ */
osg::Vec2f posToLocal(const osg::Vec2f& pos) const; osg::Vec2f posToLocal(const osg::Vec2f& pos) const;
virtual void childAdded( SGPropertyNode * parent, void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override;
SGPropertyNode * child ); void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override;
virtual void childRemoved( SGPropertyNode * parent, void valueChanged(SGPropertyNode* child) override;
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 );
@@ -597,7 +595,7 @@ namespace canvas
osg::ref_ptr<osg::Drawable> _drawable; osg::ref_ptr<osg::Drawable> _drawable;
Element(const Element&);// = delete Element(const Element&) = delete;
template<class Derived> template<class Derived>
static Derived& derived_cast(Element& el) static Derived& derived_cast(Element& el)
+3 -1
View File
@@ -1,4 +1,5 @@
// A group of 2D Canvas elements ///@file
/// A group of 2D Canvas elements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -168,6 +169,7 @@ namespace canvas
if( !_scene_group.valid() ) if( !_scene_group.valid() )
return warnSceneGroupExpired("clearEventListener"); return warnSceneGroupExpired("clearEventListener");
// TODO should this be recursive?
for(size_t i = 0; i < _scene_group->getNumChildren(); ++i) for(size_t i = 0; i < _scene_group->getNumChildren(); ++i)
getChildByIndex(i)->clearEventListener(); getChildByIndex(i)->clearEventListener();
} }
+12 -10
View File
@@ -1,4 +1,5 @@
// A group of 2D Canvas elements ///@file
/// A group of 2D Canvas elements
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -86,14 +87,15 @@ namespace canvas
*/ */
ElementPtr getElementById(const std::string& id); ElementPtr getElementById(const std::string& id);
virtual void clearEventListener(); void clearEventListener() override;
virtual bool traverse(EventVisitor& visitor); bool traverse(EventVisitor& visitor) override;
virtual bool setStyle( const SGPropertyNode* child, bool setStyle( const SGPropertyNode* child,
const StyleInfo* style_info = 0 ); const StyleInfo* style_info = 0 ) override;
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const; osg::BoundingBox
getTransformedBounds(const osg::Matrix& m) const override;
protected: protected:
@@ -105,11 +107,11 @@ namespace canvas
*/ */
virtual ElementFactory getChildFactory(const std::string& type) const; virtual ElementFactory getChildFactory(const std::string& type) const;
virtual void updateImpl(double dt); void updateImpl(double dt) override;
virtual void childAdded(SGPropertyNode * child); void childAdded(SGPropertyNode * child) override;
virtual void childRemoved(SGPropertyNode * child); void childRemoved(SGPropertyNode * child) override;
virtual void childChanged(SGPropertyNode * child); void childChanged(SGPropertyNode * child) override;
void handleZIndexChanged(ElementPtr child, int z_index = 0); void handleZIndexChanged(ElementPtr child, int z_index = 0);
+2 -1
View File
@@ -1,4 +1,5 @@
// An image on the Canvas ///@file
/// An image on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+6 -5
View File
@@ -1,4 +1,5 @@
// An image on the Canvas ///@file
/// An image on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -53,7 +54,7 @@ namespace canvas
ElementWeakPtr parent = 0 ); ElementWeakPtr parent = 0 );
virtual ~Image(); virtual ~Image();
virtual void valueChanged(SGPropertyNode* child); void valueChanged(SGPropertyNode* child) override;
void setSrcCanvas(CanvasPtr canvas); void setSrcCanvas(CanvasPtr canvas);
CanvasWeakPtr getSrcCanvas() const; CanvasWeakPtr getSrcCanvas() const;
@@ -93,7 +94,7 @@ namespace canvas
const SGRect<float>& getRegion() const; const SGRect<float>& getRegion() const;
bool handleEvent(const EventPtr& event); bool handleEvent(const EventPtr& event) override;
/** /**
* *
@@ -108,9 +109,9 @@ namespace canvas
SRC_CANVAS = DEST_SIZE << 1 SRC_CANVAS = DEST_SIZE << 1
}; };
virtual void updateImpl(double dt); void updateImpl(double dt) override;
virtual void childChanged(SGPropertyNode * child); void childChanged(SGPropertyNode * child) override;
void setupDefaultDimensions(); void setupDefaultDimensions();
SGRect<int> getTextureDimensions() const; SGRect<int> getTextureDimensions() const;
+15 -6
View File
@@ -1,5 +1,6 @@
// A group of 2D Canvas elements which get automatically transformed according ///@file
// to the map parameters. /// A group of 2D Canvas elements which get automatically transformed according
/// to the map parameters.
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -199,10 +200,18 @@ namespace canvas
_projection = std::make_shared<SansonFlamsteedProjection>(); _projection = std::make_shared<SansonFlamsteedProjection>();
_projection->setWorldPosition(_node->getDoubleValue(REF_LAT), _projection->setWorldPosition(_node->getDoubleValue(REF_LAT),
_node->getDoubleValue(REF_LON) ); _node->getDoubleValue(REF_LON));
_projection->setOrientation(_node->getFloatValue(HDG));
_projection->setScreenRange(_node->getDoubleValue(SCREEN_RANGE)); // Only set existing properties to prevent using 0 instead of default values
_projection->setRange(_node->getDoubleValue(RANGE));
if( auto heading = _node->getChild(HDG) )
_projection->setOrientation(heading->getFloatValue());
if( auto screen_range = _node->getChild(SCREEN_RANGE) )
_projection->setScreenRange(screen_range->getDoubleValue());
if( auto range = _node->getChild(RANGE) )
_projection->setRange(range->getDoubleValue());
_projection_dirty = true; _projection_dirty = true;
} }
+8 -9
View File
@@ -1,5 +1,6 @@
// A group of 2D Canvas elements which get automatically transformed according ///@file
// to the map parameters. /// A group of 2D Canvas elements which get automatically transformed according
/// to the map parameters.
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -46,16 +47,14 @@ namespace canvas
virtual ~Map(); virtual ~Map();
protected: protected:
virtual void updateImpl(double dt); void updateImpl(double dt) override;
void updateProjection(SGPropertyNode* type_node); void updateProjection(SGPropertyNode* type_node);
virtual void childAdded( SGPropertyNode* parent, void childAdded(SGPropertyNode* parent, SGPropertyNode* child) override;
SGPropertyNode* child ); void childRemoved(SGPropertyNode* parent, SGPropertyNode* child) override;
virtual void childRemoved( SGPropertyNode* parent, void valueChanged(SGPropertyNode* child) override;
SGPropertyNode* child ); void childChanged(SGPropertyNode* child) override;
virtual void valueChanged(SGPropertyNode* child);
virtual void childChanged(SGPropertyNode* child);
using GeoNodes = using GeoNodes =
std::unordered_map<SGPropertyNode*, std::shared_ptr<GeoNodePair>>; std::unordered_map<SGPropertyNode*, std::shared_ptr<GeoNodePair>>;
+12 -8
View File
@@ -1,4 +1,5 @@
// An OpenVG path on the Canvas ///@file
/// An OpenVG path on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -230,9 +231,12 @@ namespace canvas
vgDestroyPaint(_paint_fill); vgDestroyPaint(_paint_fill);
} }
virtual const char* className() const { return "PathDrawable"; } const char* className() const override
virtual osg::Object* cloneType() const { return new PathDrawable(_path_element); } { return "PathDrawable"; }
virtual osg::Object* clone(const osg::CopyOp&) const { return new PathDrawable(_path_element); } osg::Object* cloneType() const override
{ return new PathDrawable(_path_element); }
osg::Object* clone(const osg::CopyOp&) const override
{ return new PathDrawable(_path_element); }
/** /**
* Replace the current path segments with the new ones * Replace the current path segments with the new ones
@@ -383,7 +387,7 @@ namespace canvas
/** /**
* Draw callback * Draw callback
*/ */
virtual void drawImplementation(osg::RenderInfo& renderInfo) const void drawImplementation(osg::RenderInfo& renderInfo) const override
{ {
if( _attributes_dirty & PATH ) if( _attributes_dirty & PATH )
return; return;
@@ -555,13 +559,13 @@ namespace canvas
/** /**
* Compute the bounding box * Compute the bounding box
*/ */
virtual osg::BoundingBox osg::BoundingBox
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
computeBound() computeBound()
#else #else
computeBoundingBox() computeBoundingBox()
#endif #endif
const const override
{ {
if( _path == VG_INVALID_HANDLE || (_attributes_dirty & PATH) ) if( _path == VG_INVALID_HANDLE || (_attributes_dirty & PATH) )
return osg::BoundingBox(); return osg::BoundingBox();
@@ -667,7 +671,7 @@ namespace canvas
struct PathUpdateCallback: struct PathUpdateCallback:
public osg::Drawable::UpdateCallback public osg::Drawable::UpdateCallback
{ {
virtual void update(osg::NodeVisitor*, osg::Drawable* drawable) void update(osg::NodeVisitor*, osg::Drawable* drawable) override
{ {
static_cast<PathDrawable*>(drawable)->update(); static_cast<PathDrawable*>(drawable)->update();
} }
+7 -5
View File
@@ -1,4 +1,5 @@
// An OpenVG path on the Canvas ///@file
/// An OpenVG path on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -40,7 +41,8 @@ namespace canvas
ElementWeakPtr parent = 0 ); ElementWeakPtr parent = 0 );
virtual ~Path(); virtual ~Path();
virtual osg::BoundingBox getTransformedBounds(const osg::Matrix& m) const; osg::BoundingBox
getTransformedBounds(const osg::Matrix& m) const override;
/** Add a segment with the given command and coordinates */ /** Add a segment with the given command and coordinates */
Path& addSegment(uint8_t cmd, std::initializer_list<float> coords = {}); Path& addSegment(uint8_t cmd, std::initializer_list<float> coords = {});
@@ -86,10 +88,10 @@ namespace canvas
bool _hasRect : 1; bool _hasRect : 1;
SGRectf _rect; SGRectf _rect;
virtual void updateImpl(double dt); void updateImpl(double dt) override;
virtual void childRemoved(SGPropertyNode * child); void childRemoved(SGPropertyNode * child) override;
virtual void childChanged(SGPropertyNode * child); void childChanged(SGPropertyNode * child) override;
void parseRectToVGPath(); void parseRectToVGPath();
}; };
+6 -5
View File
@@ -1,4 +1,5 @@
// A text on the Canvas ///@file
/// A text on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -17,6 +18,7 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#include <simgear_config.h> #include <simgear_config.h>
#include "CanvasText.hxx" #include "CanvasText.hxx"
#include <simgear/canvas/Canvas.hxx> #include <simgear/canvas/Canvas.hxx>
#include <simgear/canvas/CanvasSystemAdapter.hxx> #include <simgear/canvas/CanvasSystemAdapter.hxx>
@@ -56,21 +58,20 @@ namespace canvas
SGVec2i sizeForWidth(int w) const; SGVec2i sizeForWidth(int w) const;
virtual osg::BoundingBox osg::BoundingBox
#if OSG_VERSION_LESS_THAN(3,3,2) #if OSG_VERSION_LESS_THAN(3,3,2)
computeBound() computeBound()
#else #else
computeBoundingBox() computeBoundingBox()
#endif #endif
const; const override;
protected: protected:
friend class TextLine; friend class TextLine;
canvas::Text *_text_element; canvas::Text *_text_element;
virtual void computePositions(unsigned int contextID) const; void computePositions(unsigned int contextID) const override;
}; };
class TextLine class TextLine
+2 -1
View File
@@ -1,4 +1,5 @@
// A text on the Canvas ///@file
/// A text on the Canvas
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+2 -1
View File
@@ -1,4 +1,5 @@
// Geographic projections for Canvas map element ///@file
/// Geographic projections for Canvas map element
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+10 -1
View File
@@ -1,4 +1,5 @@
// Canvas user defined event ///@file
/// Canvas user defined event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -46,6 +47,14 @@ namespace canvas
// assert( type_map.find(type_id) != type_map.end() ); // assert( type_map.find(type_id) != type_map.end() );
} }
//----------------------------------------------------------------------------
CustomEvent* CustomEvent::clone(int type) const
{
auto event = new CustomEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void CustomEvent::setDetail(StringMap const& data) void CustomEvent::setDetail(StringMap const& data)
{ {
+8 -1
View File
@@ -38,6 +38,7 @@ namespace canvas
public: public:
/** /**
* @brief Construct a user defined event from a type string
* *
* @param type_str Event type name (if name does not exist yet it will * @param type_str Event type name (if name does not exist yet it will
* be registered as new event type) * be registered as new event type)
@@ -49,6 +50,10 @@ namespace canvas
StringMap const& data = StringMap() ); StringMap const& data = StringMap() );
/** /**
* @brief Construct a user defined event from a (previously registered)
* type id
*
* @see getOrRegisterType()
* *
* @param type_id Event type id * @param type_id Event type id
* @param bubbles If this event should take part in the bubbling phase * @param bubbles If this event should take part in the bubbling phase
@@ -58,6 +63,8 @@ namespace canvas
bool bubbles = false, bool bubbles = false,
StringMap const& data = StringMap() ); StringMap const& data = StringMap() );
CustomEvent* clone(int type = 0) const override;
/** /**
* Set user data * Set user data
*/ */
@@ -74,7 +81,7 @@ namespace canvas
* @see #bubbles * @see #bubbles
* @see CustomEvent() * @see CustomEvent()
*/ */
virtual bool canBubble() const { return bubbles; } bool canBubble() const override { return bubbles; }
StringMap detail; //!< User data map StringMap detail; //!< User data map
bool bubbles; //!< Whether the event supports bubbling bool bubbles; //!< Whether the event supports bubbling
+2 -1
View File
@@ -1,4 +1,5 @@
// Input device event ///@file
/// Input device event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
+10 -1
View File
@@ -1,4 +1,5 @@
// Keyboard event ///@file
/// Keyboard event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -69,6 +70,14 @@ namespace canvas
// // TODO what to do with wrong event type? // // TODO what to do with wrong event type?
} }
//----------------------------------------------------------------------------
KeyboardEvent* KeyboardEvent::clone(int type) const
{
auto event = new KeyboardEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void KeyboardEvent::setKey(uint32_t key) void KeyboardEvent::setKey(uint32_t key)
{ {
+1
View File
@@ -45,6 +45,7 @@ namespace canvas
KeyboardEvent(); KeyboardEvent();
KeyboardEvent(const osgGA::GUIEventAdapter& ea); KeyboardEvent(const osgGA::GUIEventAdapter& ea);
KeyboardEvent* clone(int type = 0) const override;
void setKey(uint32_t key); void setKey(uint32_t key);
void setUnmodifiedKey(uint32_t key); void setUnmodifiedKey(uint32_t key);
+10 -1
View File
@@ -1,4 +1,5 @@
// Mouse event ///@file
/// Mouse event
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -48,6 +49,14 @@ namespace canvas
button += 1; button += 1;
} }
//----------------------------------------------------------------------------
MouseEvent* MouseEvent::clone(int type) const
{
auto event = new MouseEvent(*this);
event->type = type;
return event;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool MouseEvent::canBubble() const bool MouseEvent::canBubble() const
{ {
+2 -1
View File
@@ -36,8 +36,9 @@ namespace canvas
public: public:
MouseEvent(); MouseEvent();
MouseEvent(const osgGA::GUIEventAdapter& ea); MouseEvent(const osgGA::GUIEventAdapter& ea);
MouseEvent* clone(int type = 0) const override;
virtual bool canBubble() const; bool canBubble() const override;
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; }
+2 -1
View File
@@ -1,4 +1,5 @@
// Keyboard event demo. Press some keys and get some info... ///@file
/// Keyboard event demo. Press some keys and get some info...
// //
// Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2014 Thomas Geymayer <tomgey@gmail.com>
// //
-2
View File
@@ -5,8 +5,6 @@
#include <signal.h> #include <signal.h>
#include <iostream> #include <iostream>
#include <boost/foreach.hpp>
#include <simgear/io/sg_file.hxx> #include <simgear/io/sg_file.hxx>
#include <simgear/io/HTTPClient.hxx> #include <simgear/io/HTTPClient.hxx>
+28 -19
View File
@@ -72,10 +72,10 @@ namespace simgear {
std::string strip( const std::string& s ); std::string strip( const std::string& s );
/** /**
* Return a new string with any trailing \r and \n characters removed. * Return a new string with any trailing \\r and \\n characters removed.
* Typically useful to clean a CR-terminated line obtained from * Typically useful to clean a CR-terminated line obtained from
* std::getline() which, upon reading CRLF (\r\n), discards the Line * std::getline() which, upon reading CRLF (\\r\\n), discards the Line
* Feed character (\n) but leaves the Carriage Return (\r) in the * Feed character (\\n) but leaves the Carriage Return (\\r) in the
* string. * string.
* @param s Input string * @param s Input string
* @return The cleaned string * @return The cleaned string
@@ -83,7 +83,7 @@ namespace simgear {
std::string stripTrailingNewlines(const std::string& s); std::string stripTrailingNewlines(const std::string& s);
/** /**
* Strip any trailing \r and \n characters from a string. * Strip any trailing \\r and \\n characters from a string.
* Should have slightly less overhead than stripTrailingNewlines(). * Should have slightly less overhead than stripTrailingNewlines().
* @param s Input string (modified in-place) * @param s Input string (modified in-place)
*/ */
@@ -112,11 +112,12 @@ namespace simgear {
* Produces a result similar to the perl and python functions of the * Produces a result similar to the perl and python functions of the
* same name. * same name.
* *
* @param s The string to split into words, * @param s The string to split into words
* @param sep Word delimiters. If not specified then any whitespace is a separator, * @param sep Word delimiters. If not specified then any whitespace is
* @param maxsplit If given, splits at no more than maxsplit places, * a separator
* resulting in at most maxsplit+1 words. * @param maxsplit If given, splits at no more than maxsplit places,
* @return Array of words. * resulting in at most maxsplit+1 words
* @return Array of words
*/ */
string_list string_list
split( const std::string& s, split( const std::string& s,
@@ -124,11 +125,11 @@ namespace simgear {
int maxsplit = 0 ); int maxsplit = 0 );
/** /**
* split a string on any of several characters. Commonly used to deal * Split a string on any of several characters. Commonly used to deal
* with strings containing whitespace, newlines. To parse CSS style * with strings containing whitespace, newlines. To parse CSS style
* string, use with '\n\t ,' as the seperator list. * string, use with '\\n\\t ,' as the separator list.
* *
* Note consecutive seperators will not produce empty entries in the * @note Consecutive separators will not produce empty entries in the
* the result, i.e splitting 'a,b,,c,d' with a ',' will produce a result * the result, i.e splitting 'a,b,,c,d' with a ',' will produce a result
* with four entries, not five. * with four entries, not five.
*/ */
@@ -226,14 +227,22 @@ namespace simgear {
bool to_bool(const std::string& s); bool to_bool(const std::string& s);
/** /**
* Like strcmp(), but for dotted versions strings NN.NN.NN * Compare dotted versions strings NN.NN.NN (analogous to strcmp())
* any number of terms are supported. *
* @return 0 if versions match, -ve number if v1 is lower, +ve if v1 * @note Any number of terms are supported.
* is greater *
* @param maxComponents is the maximum number of components to look at. * @param v1 First version
* This can be used to ignore (say) the patch level by setting it to 2 * @param v2 Second version
* @param maxComponents The maximum number of components to look at. This
* can be used to ignore (say) the patch level by
* setting it to 2
* @return 0 if versions match,
* -ve number if @a v1 is lower,
* +ve if @a v1 is greater
*/ */
int compare_versions(const std::string& v1, const std::string& v2, int maxComponents = 0); int compare_versions( const std::string& v1,
const std::string& v2,
int maxComponents = 0 );
/** /**
* Convert a string to upper case. * Convert a string to upper case.
+25 -4
View File
@@ -84,7 +84,7 @@ bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_ptr props) std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_ptr props)
{ {
BOOST_FOREACH(SGPropertyNode* v, props->getChildren("alternate-version")) { for (SGPropertyNode* v : props->getChildren("alternate-version")) {
std::string s(v->getStringValue("version")); std::string s(v->getStringValue("version"));
if (checkVersionString(aVersion, s)) { if (checkVersionString(aVersion, s)) {
return v->getStringValue("url");; return v->getStringValue("url");;
@@ -139,7 +139,7 @@ protected:
std::string ver(m_owner->root()->applicationVersion()); std::string ver(m_owner->root()->applicationVersion());
if (!checkVersion(ver, props)) { if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version required " << ver); SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", but version required " << ver);
// check for a version redirect entry // check for a version redirect entry
std::string url = redirectUrlForVersion(ver, props); std::string url = redirectUrlForVersion(ver, props);
@@ -169,7 +169,13 @@ protected:
m_owner->writeTimestamp(); m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::STATUS_REFRESHED); m_owner->refreshComplete(Delegate::STATUS_REFRESHED);
} }
void onFail() override
{
// network level failure
SG_LOG(SG_GENERAL, SG_WARN, "catalog network failure for:" << m_owner->url());
m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
}
private: private:
CatalogRef m_owner; CatalogRef m_owner;
@@ -215,7 +221,8 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
bool versionCheckOk = checkVersion(aRoot->applicationVersion(), props); bool versionCheckOk = checkVersion(aRoot->applicationVersion(), props);
if (!versionCheckOk) { if (!versionCheckOk) {
SG_LOG(SG_GENERAL, SG_INFO, "catalog at:" << aPath << " failed version check: need" << aRoot->applicationVersion()); SG_LOG(SG_GENERAL, SG_INFO, "catalog at:" << aPath << " failed version check: need version: "
<< aRoot->applicationVersion());
// keep the catalog but mark it as needing an update // keep the catalog but mark it as needing an update
} else { } else {
SG_LOG(SG_GENERAL, SG_DEBUG, "creating catalog from:" << aPath); SG_LOG(SG_GENERAL, SG_DEBUG, "creating catalog from:" << aPath);
@@ -540,6 +547,20 @@ Delegate::StatusCode Catalog::status() const
return m_status; return m_status;
} }
bool Catalog::isEnabled() const
{
switch (m_status) {
case Delegate::STATUS_SUCCESS:
case Delegate::STATUS_REFRESHED:
case Delegate::STATUS_IN_PROGRESS:
// this is important so we can use Catalog aircraft in offline mode
case Delegate::FAIL_DOWNLOAD:
return true;
default:
return false;
}
}
} // of namespace pkg } // of namespace pkg
} // of namespace simgear } // of namespace simgear
+6
View File
@@ -134,6 +134,12 @@ public:
SGPropertyNode* properties() const; SGPropertyNode* properties() const;
Delegate::StatusCode status() const; Delegate::StatusCode status() const;
/**
* is this Catalog usable? This may be false if the catalog is currently
* failing a version check or cannot be updated
*/
bool isEnabled() const;
typedef boost::function<void(Catalog*)> Callback; typedef boost::function<void(Catalog*)> Callback;
+191
View File
@@ -61,6 +61,7 @@ std::string readFileIntoString(const SGPath& path)
SGPath global_serverFilesRoot; SGPath global_serverFilesRoot;
unsigned int global_catalogVersion = 0; unsigned int global_catalogVersion = 0;
bool global_failRequests = false;
class TestPackageChannel : public TestServerChannel class TestPackageChannel : public TestServerChannel
{ {
@@ -71,6 +72,10 @@ public:
state = STATE_IDLE; state = STATE_IDLE;
SGPath localPath(global_serverFilesRoot); SGPath localPath(global_serverFilesRoot);
if (global_failRequests) {
closeWhenDone();
return;
}
if (path == "/catalogTest1/catalog.xml") { if (path == "/catalogTest1/catalog.xml") {
if (global_catalogVersion > 0) { if (global_catalogVersion > 0) {
@@ -540,6 +545,186 @@ void testInstallTarPackage(HTTP::Client* cl)
SG_VERIFY(p.exists()); SG_VERIFY(p.exists());
} }
void testDisableDueToVersion(HTTP::Client* cl)
{
global_catalogVersion = 0;
SGPath rootPath(simgear::Dir::current().path());
rootPath.append("cat_disable_at_version");
simgear::Dir pd(rootPath);
pd.removeChildren();
{
pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
root->setHTTPClient(cl);
pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
waitForUpdateComplete(cl, root);
SG_VERIFY(c->isEnabled());
// install a package
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_CHECK_EQUAL(p1->id(), "b737-NG");
pkg::InstallRef ins = p1->install();
SG_VERIFY(ins->isQueued());
waitForUpdateComplete(cl, root);
SG_VERIFY(p1->isInstalled());
}
// bump version and refresh
{
pkg::RootRef root(new pkg::Root(rootPath, "9.1.2"));
pkg::CatalogRef cat = root->getCatalogById("org.flightgear.test.catalog1");
SG_CHECK_EQUAL(root->allCatalogs().size(), 1);
SG_VERIFY(!cat->isEnabled());
SG_CHECK_EQUAL(root->catalogs().size(), 0);
root->setHTTPClient(cl);
root->refresh();
waitForUpdateComplete(cl, root);
SG_CHECK_EQUAL(root->allCatalogs().size(), 1);
SG_CHECK_EQUAL(cat->status(), pkg::Delegate::FAIL_VERSION);
SG_VERIFY(!cat->isEnabled());
SG_CHECK_EQUAL(cat->id(), "org.flightgear.test.catalog1");
auto enabledCats = root->catalogs();
auto it = std::find(enabledCats.begin(), enabledCats.end(), cat);
SG_VERIFY(it == enabledCats.end());
SG_CHECK_EQUAL(enabledCats.size(), 0);
auto allCats = root->allCatalogs();
auto j = std::find(allCats.begin(), allCats.end(), cat);
SG_VERIFY(j != allCats.end());
SG_CHECK_EQUAL(allCats.size(), 1);
// ensure existing package is still installed but not directly list
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_VERIFY(p1 != pkg::PackageRef());
SG_CHECK_EQUAL(p1->id(), "b737-NG");
auto packs = root->allPackages();
auto k = std::find(packs.begin(), packs.end(), p1);
SG_VERIFY(k == packs.end());
}
}
void testVersionMigrate(HTTP::Client* cl)
{
global_catalogVersion = 2; // version which has migration info
SGPath rootPath(simgear::Dir::current().path());
rootPath.append("cat_migrate_version");
simgear::Dir pd(rootPath);
pd.removeChildren();
{
pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
root->setHTTPClient(cl);
pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
waitForUpdateComplete(cl, root);
SG_VERIFY(c->isEnabled());
// install a package
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_CHECK_EQUAL(p1->id(), "b737-NG");
pkg::InstallRef ins = p1->install();
SG_VERIFY(ins->isQueued());
waitForUpdateComplete(cl, root);
SG_VERIFY(p1->isInstalled());
}
// bump version and refresh
{
pkg::RootRef root(new pkg::Root(rootPath, "10.1.2"));
root->setHTTPClient(cl);
// this should cause auto-migration
root->refresh(true);
waitForUpdateComplete(cl, root);
pkg::CatalogRef cat = root->getCatalogById("org.flightgear.test.catalog1");
SG_VERIFY(cat->isEnabled());
SG_CHECK_EQUAL(cat->status(), pkg::Delegate::STATUS_REFRESHED);
SG_CHECK_EQUAL(cat->id(), "org.flightgear.test.catalog1");
SG_CHECK_EQUAL(cat->url(), "http://localhost:2000/catalogTest1/catalog-v10.xml");
auto enabledCats = root->catalogs();
auto it = std::find(enabledCats.begin(), enabledCats.end(), cat);
SG_VERIFY(it != enabledCats.end());
// ensure existing package is still installed
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_VERIFY(p1 != pkg::PackageRef());
SG_CHECK_EQUAL(p1->id(), "b737-NG");
auto packs = root->allPackages();
auto k = std::find(packs.begin(), packs.end(), p1);
SG_VERIFY(k != packs.end());
}
}
void testOfflineMode(HTTP::Client* cl)
{
global_catalogVersion = 0;
SGPath rootPath(simgear::Dir::current().path());
rootPath.append("cat_offline_mode");
simgear::Dir pd(rootPath);
pd.removeChildren();
{
pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
root->setHTTPClient(cl);
pkg::CatalogRef c = pkg::Catalog::createFromUrl(root.ptr(), "http://localhost:2000/catalogTest1/catalog.xml");
waitForUpdateComplete(cl, root);
SG_VERIFY(c->isEnabled());
// install a package
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_CHECK_EQUAL(p1->id(), "b737-NG");
pkg::InstallRef ins = p1->install();
SG_VERIFY(ins->isQueued());
waitForUpdateComplete(cl, root);
SG_VERIFY(p1->isInstalled());
}
global_failRequests = true;
{
pkg::RootRef root(new pkg::Root(rootPath, "8.1.2"));
SG_CHECK_EQUAL(root->catalogs().size(), 1);
root->setHTTPClient(cl);
root->refresh(true);
waitForUpdateComplete(cl, root);
SG_CHECK_EQUAL(root->catalogs().size(), 1);
pkg::CatalogRef cat = root->getCatalogById("org.flightgear.test.catalog1");
SG_VERIFY(cat->isEnabled());
SG_CHECK_EQUAL(cat->status(), pkg::Delegate::FAIL_DOWNLOAD);
SG_CHECK_EQUAL(cat->id(), "org.flightgear.test.catalog1");
auto enabledCats = root->catalogs();
auto it = std::find(enabledCats.begin(), enabledCats.end(), cat);
SG_VERIFY(it != enabledCats.end());
// ensure existing package is still installed
pkg::PackageRef p1 = root->getPackageById("org.flightgear.test.catalog1.b737-NG");
SG_VERIFY(p1 != pkg::PackageRef());
SG_CHECK_EQUAL(p1->id(), "b737-NG");
auto packs = root->allPackages();
auto k = std::find(packs.begin(), packs.end(), p1);
SG_VERIFY(k != packs.end());
}
global_failRequests = false;
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@@ -564,6 +749,12 @@ int main(int argc, char* argv[])
testInstallTarPackage(&cl); testInstallTarPackage(&cl);
testDisableDueToVersion(&cl);
testOfflineMode(&cl);
testVersionMigrate(&cl);
std::cout << "Successfully passed all tests!" << std::endl; std::cout << "Successfully passed all tests!" << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
+33 -35
View File
@@ -408,15 +408,11 @@ Root::Root(const SGPath& aPath, const std::string& aVersion) :
} }
for (SGPath c : dir.children(Dir::TYPE_DIR | Dir::NO_DOT_OR_DOTDOT)) { for (SGPath c : dir.children(Dir::TYPE_DIR | Dir::NO_DOT_OR_DOTDOT)) {
CatalogRef cat = Catalog::createFromPath(this, c); // note this will set the catalog status, which will insert into
if (cat) { // disabled catalogs automatically if necesary
if (cat->status() == Delegate::STATUS_SUCCESS) { auto cat = Catalog::createFromPath(this, c);
d->catalogs[cat->id()] = cat; if (cat && cat->isEnabled()) {
} else { d->catalogs.insert({cat->id(), cat});
// catalog has problems, such as needing an update
// keep it out of the main collection for now
d->disabledCatalogs.push_back(cat);
}
} }
} // of child directories iteration } // of child directories iteration
} }
@@ -438,9 +434,15 @@ std::string Root::applicationVersion() const
CatalogRef Root::getCatalogById(const std::string& aId) const CatalogRef Root::getCatalogById(const std::string& aId) const
{ {
CatalogDict::const_iterator it = d->catalogs.find(aId); auto it = d->catalogs.find(aId);
if (it == d->catalogs.end()) { if (it == d->catalogs.end()) {
return NULL; // check disabled catalog list
auto j = std::find_if(d->disabledCatalogs.begin(), d->disabledCatalogs.end(),
[aId](const CatalogRef& cat) { return cat->id() == aId; });
if (j != d->disabledCatalogs.end()) {
return *j;
}
return nullptr;
} }
return it->second; return it->second;
@@ -484,6 +486,13 @@ CatalogList Root::catalogs() const
return r; return r;
} }
CatalogList Root::allCatalogs() const
{
CatalogList r = catalogs();
r.insert(r.end(), d->disabledCatalogs.begin(), d->disabledCatalogs.end());
return r;
}
PackageList PackageList
Root::allPackages() const Root::allPackages() const
@@ -544,12 +553,9 @@ void Root::refresh(bool aForce)
toRefresh.insert(toRefresh.end(), d->disabledCatalogs.begin(), toRefresh.insert(toRefresh.end(), d->disabledCatalogs.begin(),
d->disabledCatalogs.end()); d->disabledCatalogs.end());
for (auto cat : toRefresh) {
cat->refresh();
CatalogList::iterator j = toRefresh.begin(); didStartAny = true;
for (; j != toRefresh.end(); ++j) {
(*j)->refresh();
didStartAny = true;
} }
if (!didStartAny) { if (!didStartAny) {
@@ -677,23 +683,20 @@ void Root::catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason)
d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat)); d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat));
// catalog might have been previously disabled, let's remove in that case // catalog might have been previously disabled, let's remove in that case
CatalogList::iterator j = std::find(d->disabledCatalogs.begin(), auto j = std::find(d->disabledCatalogs.begin(),
d->disabledCatalogs.end(), d->disabledCatalogs.end(),
aCat); aCat);
if (j != d->disabledCatalogs.end()) { if (j != d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_INFO, "re-enabling disabled catalog:" << aCat->id()); SG_LOG(SG_GENERAL, SG_INFO, "re-enabling disabled catalog:" << aCat->id());
d->disabledCatalogs.erase(j); d->disabledCatalogs.erase(j);
} }
} }
if ((aReason != Delegate::STATUS_REFRESHED) && if (!aCat->isEnabled()) {
(aReason != Delegate::STATUS_IN_PROGRESS) &&
(aReason != Delegate::STATUS_SUCCESS))
{
// catalog has errors, disable it // catalog has errors, disable it
CatalogList::iterator j = std::find(d->disabledCatalogs.begin(), auto j = std::find(d->disabledCatalogs.begin(),
d->disabledCatalogs.end(), d->disabledCatalogs.end(),
aCat); aCat);
if (j == d->disabledCatalogs.end()) { if (j == d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_INFO, "disabling catalog:" << aCat->id()); SG_LOG(SG_GENERAL, SG_INFO, "disabling catalog:" << aCat->id());
d->disabledCatalogs.push_back(aCat); d->disabledCatalogs.push_back(aCat);
@@ -703,7 +706,7 @@ void Root::catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason)
if (catIt != d->catalogs.end()) { if (catIt != d->catalogs.end()) {
d->catalogs.erase(catIt); d->catalogs.erase(catIt);
} }
} // of catalog has errors case } // of catalog is disabled
if (d->refreshing.empty()) { if (d->refreshing.empty()) {
d->fireRefreshStatus(CatalogRef(), Delegate::STATUS_REFRESHED); d->fireRefreshStatus(CatalogRef(), Delegate::STATUS_REFRESHED);
@@ -718,13 +721,8 @@ bool Root::removeCatalogById(const std::string& aId)
CatalogDict::iterator catIt = d->catalogs.find(aId); CatalogDict::iterator catIt = d->catalogs.find(aId);
if (catIt == d->catalogs.end()) { if (catIt == d->catalogs.end()) {
// check the disabled list // check the disabled list
CatalogList::iterator j = d->disabledCatalogs.begin(); auto j = std::find_if(d->disabledCatalogs.begin(), d->disabledCatalogs.end(),
for (; j != d->disabledCatalogs.end(); ++j) { [aId](const CatalogRef& cat) { return cat->id() == aId; });
if ((*j)->id() == aId) {
break;
}
}
if (j == d->disabledCatalogs.end()) { if (j == d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: no catalog with id:" << aId); SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: no catalog with id:" << aId);
return false; return false;
+7 -1
View File
@@ -69,7 +69,13 @@ public:
std::string getLocale() const; std::string getLocale() const;
CatalogList catalogs() const; CatalogList catalogs() const;
/**
* retrive all catalogs, including currently disabled ones
*/
CatalogList allCatalogs() const;
void setMaxAgeSeconds(unsigned int seconds); void setMaxAgeSeconds(unsigned int seconds);
unsigned int maxAgeSeconds() const; unsigned int maxAgeSeconds() const;
@@ -0,0 +1,178 @@
<?xml version="1.0"?>
<PropertyList>
<id>org.flightgear.test.catalog1</id>
<description>First test catalog</description>
<url>http://localhost:2000/catalogTest1/catalog-v10.xml</url>
<catalog-version>4</catalog-version>
<version>10.0.*</version>
<version>10.1.*</version>
<package>
<id>alpha</id>
<name>Alpha package</name>
<revision type="int">8</revision>
<file-size-bytes type="int">593</file-size-bytes>
<md5>a469c4b837f0521db48616cfe65ac1ea</md5>
<url>http://localhost:2000/catalogTest1/alpha.zip</url>
<dir>alpha</dir>
</package>
<package>
<id>c172p</id>
<name>Cessna 172-P</name>
<dir>c172p</dir>
<description>A plane made by Cessna on Jupiter</description>
<revision type="int">42</revision>
<file-size-bytes type="int">860</file-size-bytes>
<author>Standard author</author>
<tag>cessna</tag>
<tag>ga</tag>
<tag>piston</tag>
<tag>ifr</tag>
<rating>
<FDM type="int">3</FDM>
<systems type="int">4</systems>
<model type="int">5</model>
<cockpit type="int">4</cockpit>
</rating>
<!-- local dependency -->
<depends>
<id>org.flightgear.test.catalog1.common-sounds</id>
<revision>10</revision>
</depends>
<preview>
<type>exterior</type>
<path>thumb-exterior.png</path>
<url>http://foo.bar.com/thumb-exterior.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
<preview>
<path>thumb-something.png</path>
<url>http://foo.bar.com/thumb-something.png</url>
</preview>
<variant>
<id>c172p-2d-panel</id>
<name>C172 with 2d panel only</name>
</variant>
<variant>
<id>c172p-floats</id>
<name>C172 with floats</name>
<description>A plane with floats</description>
<author>Floats variant author</author>
<preview>
<type>exterior</type>
<path>thumb-exterior-floats.png</path>
<url>http://foo.bar.com/thumb-exterior-floats.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
<thumbnail>http://foo.bar.com/thumb-floats.png</thumbnail>
<thumbnail-path>thumb-floats.png</thumbnail-path>
</variant>
<variant>
<id>c172p-skis</id>
<name>C172 with skis</name>
<description>A plane with skis</description>
<variant-of>c172p</variant-of>
<preview>
<type>exterior</type>
<path>thumb-exterior-skis.png</path>
<url>http://foo.bar.com/thumb-exterior-skis.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<variant>
<id>c172r</id>
<name>C172R</name>
<description>Equally good version of the C172</description>
<variant-of>_package_</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<variant>
<id>c172r-floats</id>
<name>C172R-floats</name>
<description>Equally good version of the C172 with floats</description>
<variant-of>c172r</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<md5>ec0e2ffdf98d6a5c05c77445e5447ff5</md5>
<url>http://localhost:2000/catalogTest1/c172p.zip</url>
<thumbnail>http://foo.bar.com/thumb-exterior.png</thumbnail>
<thumbnail-path>exterior.png</thumbnail-path>
</package>
<package>
<id>b737-NG</id>
<name>Boeing 737 NG</name>
<dir>b737NG</dir>
<description>A popular twin-engined narrow body jet</description>
<revision type="int">111</revision>
<file-size-bytes type="int">860</file-size-bytes>
<tag>boeing</tag>
<tag>jet</tag>
<tag>ifr</tag>
<rating>
<FDM type="int">5</FDM>
<systems type="int">5</systems>
<model type="int">4</model>
<cockpit type="int">4</cockpit>
</rating>
<md5>a94ca5704f305b90767f40617d194ed6</md5>
<url>http://localhost:2000/catalogTest1/b737.tar.gz</url>
</package>
<package>
<id>common-sounds</id>
<name>Common sound files for test catalog aircraft</name>
<revision>10</revision>
<dir>sounds</dir>
<url>http://localhost:2000/catalogTest1/common-sounds.zip</url>
<file-size-bytes>360</file-size-bytes>
<md5>acf9eb89cf396eb42f8823d9cdf17584</md5>
</package>
</PropertyList>
@@ -10,6 +10,11 @@
<version>8.0.0</version> <version>8.0.0</version>
<version>8.2.0</version> <version>8.2.0</version>
<alternate-version>
<version>10.*.*</version>
<url>http://localhost:2000/catalogTest1/catalog-v10.xml</url>
</alternate-version>
<package> <package>
<id>alpha</id> <id>alpha</id>
<name>Alpha package</name> <name>Alpha package</name>
+178
View File
@@ -0,0 +1,178 @@
<?xml version="1.0"?>
<PropertyList>
<id>org.flightgear.test.catalog1</id>
<description>First test catalog</description>
<url>http://localhost:2000/catalogTest1/catalog.xml</url>
<catalog-version>4</catalog-version>
<version>9.1.*</version>
<package>
<id>alpha</id>
<name>Alpha package</name>
<revision type="int">8</revision>
<file-size-bytes type="int">593</file-size-bytes>
<md5>a469c4b837f0521db48616cfe65ac1ea</md5>
<url>http://localhost:2000/catalogTest1/alpha.zip</url>
<dir>alpha</dir>
</package>
<package>
<id>c172p</id>
<name>Cessna 172-P</name>
<dir>c172p</dir>
<description>A plane made by Cessna on Jupiter</description>
<revision type="int">42</revision>
<file-size-bytes type="int">860</file-size-bytes>
<author>Standard author</author>
<tag>cessna</tag>
<tag>ga</tag>
<tag>piston</tag>
<tag>ifr</tag>
<rating>
<FDM type="int">3</FDM>
<systems type="int">4</systems>
<model type="int">5</model>
<cockpit type="int">4</cockpit>
</rating>
<!-- local dependency -->
<depends>
<id>org.flightgear.test.catalog1.common-sounds</id>
<revision>10</revision>
</depends>
<preview>
<type>exterior</type>
<path>thumb-exterior.png</path>
<url>http://foo.bar.com/thumb-exterior.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
<preview>
<path>thumb-something.png</path>
<url>http://foo.bar.com/thumb-something.png</url>
</preview>
<variant>
<id>c172p-2d-panel</id>
<name>C172 with 2d panel only</name>
</variant>
<variant>
<id>c172p-floats</id>
<name>C172 with floats</name>
<description>A plane with floats</description>
<author>Floats variant author</author>
<preview>
<type>exterior</type>
<path>thumb-exterior-floats.png</path>
<url>http://foo.bar.com/thumb-exterior-floats.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
<thumbnail>http://foo.bar.com/thumb-floats.png</thumbnail>
<thumbnail-path>thumb-floats.png</thumbnail-path>
</variant>
<variant>
<id>c172p-skis</id>
<name>C172 with skis</name>
<description>A plane with skis</description>
<variant-of>c172p</variant-of>
<preview>
<type>exterior</type>
<path>thumb-exterior-skis.png</path>
<url>http://foo.bar.com/thumb-exterior-skis.png</url>
</preview>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<variant>
<id>c172r</id>
<name>C172R</name>
<description>Equally good version of the C172</description>
<variant-of>_package_</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<variant>
<id>c172r-floats</id>
<name>C172R-floats</name>
<description>Equally good version of the C172 with floats</description>
<variant-of>c172r</variant-of>
<preview>
<type>panel</type>
<path>thumb-panel.png</path>
<url>http://foo.bar.com/thumb-panel.png</url>
</preview>
</variant>
<md5>ec0e2ffdf98d6a5c05c77445e5447ff5</md5>
<url>http://localhost:2000/catalogTest1/c172p.zip</url>
<thumbnail>http://foo.bar.com/thumb-exterior.png</thumbnail>
<thumbnail-path>exterior.png</thumbnail-path>
</package>
<package>
<id>b737-NG</id>
<name>Boeing 737 NG</name>
<dir>b737NG</dir>
<description>A popular twin-engined narrow body jet</description>
<revision type="int">111</revision>
<file-size-bytes type="int">860</file-size-bytes>
<tag>boeing</tag>
<tag>jet</tag>
<tag>ifr</tag>
<rating>
<FDM type="int">5</FDM>
<systems type="int">5</systems>
<model type="int">4</model>
<cockpit type="int">4</cockpit>
</rating>
<md5>a94ca5704f305b90767f40617d194ed6</md5>
<url>http://localhost:2000/catalogTest1/b737.tar.gz</url>
</package>
<package>
<id>common-sounds</id>
<name>Common sound files for test catalog aircraft</name>
<revision>10</revision>
<dir>sounds</dir>
<url>http://localhost:2000/catalogTest1/common-sounds.zip</url>
<file-size-bytes>360</file-size-bytes>
<md5>acf9eb89cf396eb42f8823d9cdf17584</md5>
</package>
</PropertyList>
+2 -1
View File
@@ -1,4 +1,5 @@
// Base class for property controlled subsystems ///@file
/// Base class for property controlled subsystems
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
+9 -8
View File
@@ -1,4 +1,5 @@
// Base class for property controlled subsystems ///@file
/// Base class for property controlled subsystems
// //
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com> // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
// //
@@ -33,10 +34,10 @@ namespace simgear
public SGPropertyChangeListener public SGPropertyChangeListener
{ {
public: public:
virtual void init(); void init() override;
virtual void shutdown(); void shutdown() override;
virtual void update (double delta_time_sec); void update (double delta_time_sec) override;
/** /**
* Create a new PropertyBasedElement * Create a new PropertyBasedElement
@@ -88,10 +89,10 @@ namespace simgear
ElementFactory element_factory ); ElementFactory element_factory );
virtual ~PropertyBasedMgr() = 0; virtual ~PropertyBasedMgr() = 0;
virtual void childAdded( SGPropertyNode * parent, void childAdded( SGPropertyNode * parent,
SGPropertyNode * child ); SGPropertyNode * child ) override;
virtual void childRemoved( SGPropertyNode * parent, void childRemoved( SGPropertyNode * parent,
SGPropertyNode * child ); SGPropertyNode * child ) override;
virtual void elementCreated(PropertyBasedElementPtr element) {} virtual void elementCreated(PropertyBasedElementPtr element) {}
+1 -1
View File
@@ -23,7 +23,7 @@
// $Id$ // $Id$
/** /**
* \file audio sample.hxx * \file
* Provides a audio sample encapsulation * Provides a audio sample encapsulation
*/ */