Mercurial > hg > orthanc-stone
changeset 1203:f3bb9a6dd949 broker
locking abstraction in IViewport
line wrap: on
line diff
--- a/Framework/Scene2DViewport/AngleMeasureTool.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/AngleMeasureTool.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -131,8 +131,10 @@ AngleMeasureTool::AngleHighlightArea AngleMeasureTool::AngleHitTest(ScenePoint2D p) const { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + const double pixelToScene = - GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom(); + lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; { @@ -176,8 +178,10 @@ boost::shared_ptr<IFlexiblePointerTracker> AngleMeasureTool::CreateEditionTracker(const PointerEvent& e) { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetController()->GetScene().GetCanvasToSceneTransform()); + lock->GetScene().GetCanvasToSceneTransform()); if (!HitTest(scenePos)) return boost::shared_ptr<IFlexiblePointerTracker>(); @@ -208,77 +212,82 @@ boost::shared_ptr<ViewportController> controller = GetController(); if (IsEnabled()) { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + layerHolder_->CreateLayersIfNeeded(); { // Fill the polyline layer with the measurement lines PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); - polylineLayer->ClearAllChains(); + if (polylineLayer) + { + polylineLayer->ClearAllChains(); + + const Color color(TOOL_ANGLE_LINES_COLOR_RED, TOOL_ANGLE_LINES_COLOR_GREEN, TOOL_ANGLE_LINES_COLOR_BLUE); + const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, TOOL_ANGLE_LINES_HL_COLOR_GREEN, TOOL_ANGLE_LINES_HL_COLOR_BLUE); + + // sides + { + { + PolylineSceneLayer::Chain chain; + chain.push_back(side1End_); + chain.push_back(center_); - const Color color(TOOL_ANGLE_LINES_COLOR_RED, TOOL_ANGLE_LINES_COLOR_GREEN, TOOL_ANGLE_LINES_COLOR_BLUE); - const Color highlightColor(TOOL_ANGLE_LINES_HL_COLOR_RED, TOOL_ANGLE_LINES_HL_COLOR_GREEN, TOOL_ANGLE_LINES_HL_COLOR_BLUE); + if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) + polylineLayer->AddChain(chain, false, highlightColor); + else + polylineLayer->AddChain(chain, false, color); + } + { + PolylineSceneLayer::Chain chain; + chain.push_back(side2End_); + chain.push_back(center_); + if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) + polylineLayer->AddChain(chain, false, highlightColor); + else + polylineLayer->AddChain(chain, false, color); + } + } - // sides - { + // Create the handles + { + { + PolylineSceneLayer::Chain chain; + //TODO: take DPI into account + AddSquare(chain, lock->GetScene(), side1End_, + GetController()->GetHandleSideLengthS()); + + if (angleHighlightArea_ == AngleHighlightArea_Side1End) + polylineLayer->AddChain(chain, true, highlightColor); + else + polylineLayer->AddChain(chain, true, color); + + } + { + PolylineSceneLayer::Chain chain; + //TODO: take DPI into account + AddSquare(chain, lock->GetScene(), side2End_, + GetController()->GetHandleSideLengthS()); + + if (angleHighlightArea_ == AngleHighlightArea_Side2End) + polylineLayer->AddChain(chain, true, highlightColor); + else + polylineLayer->AddChain(chain, true, color); + } + } + + // Create the arc { PolylineSceneLayer::Chain chain; - chain.push_back(side1End_); - chain.push_back(center_); - if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) - polylineLayer->AddChain(chain, false, highlightColor); - else - polylineLayer->AddChain(chain, false, color); - } - { - PolylineSceneLayer::Chain chain; - chain.push_back(side2End_); - chain.push_back(center_); - if ((angleHighlightArea_ == AngleHighlightArea_Side1) || (angleHighlightArea_ == AngleHighlightArea_Side2)) + AddShortestArc(chain, side1End_, center_, side2End_, + controller->GetAngleToolArcRadiusS()); + if (angleHighlightArea_ == AngleHighlightArea_Center) polylineLayer->AddChain(chain, false, highlightColor); else polylineLayer->AddChain(chain, false, color); } } - - // Create the handles - { - { - PolylineSceneLayer::Chain chain; - //TODO: take DPI into account - AddSquare(chain, GetController()->GetScene(), side1End_, - GetController()->GetHandleSideLengthS()); - - if (angleHighlightArea_ == AngleHighlightArea_Side1End) - polylineLayer->AddChain(chain, true, highlightColor); - else - polylineLayer->AddChain(chain, true, color); - - } - { - PolylineSceneLayer::Chain chain; - //TODO: take DPI into account - AddSquare(chain, GetController()->GetScene(), side2End_, - GetController()->GetHandleSideLengthS()); - - if (angleHighlightArea_ == AngleHighlightArea_Side2End) - polylineLayer->AddChain(chain, true, highlightColor); - else - polylineLayer->AddChain(chain, true, color); - } - } - - // Create the arc - { - PolylineSceneLayer::Chain chain; - - AddShortestArc(chain, side1End_, center_, side2End_, - controller->GetAngleToolArcRadiusS()); - if (angleHighlightArea_ == AngleHighlightArea_Center) - polylineLayer->AddChain(chain, false, highlightColor); - else - polylineLayer->AddChain(chain, false, color); - } } { // Set the text layer @@ -308,10 +317,10 @@ #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 SetTextLayerOutlineProperties( - GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY), 0); + lock->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY), 0); #else SetTextLayerProperties( - GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0); + lock->GetScene(), layerHolder_, buf, ScenePoint2D(pointX, pointY) , 0); #endif #if 0
--- a/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/CreateAngleMeasureTracker.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -31,10 +31,18 @@ : CreateMeasureTracker(controllerW) , state_(CreatingSide1) { - command_.reset( - new CreateAngleMeasureCommand( - controllerW, - e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); + ScenePoint2D point = e.GetMainPosition(); + + { + boost::shared_ptr<ViewportController> controller = controllerW.lock(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + point = e.GetMainPosition().Apply(lock->GetScene().GetCanvasToSceneTransform()); + } + } + + command_.reset(new CreateAngleMeasureCommand(controllerW, point)); } CreateAngleMeasureTracker::~CreateAngleMeasureTracker() @@ -50,24 +58,29 @@ "PointerMove: active_ == false"); } - ScenePoint2D scenePos = event.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); - - switch (state_) + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + if (controller) { - case CreatingSide1: - GetCommand()->SetCenter(scenePos); - break; - case CreatingSide2: - GetCommand()->SetSide2End(scenePos); - break; - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, - "Wrong state in CreateAngleMeasureTracker::" - "PointerMove: state_ invalid"); + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + ScenePoint2D scenePos = event.GetMainPosition().Apply( + lock->GetScene().GetCanvasToSceneTransform()); + + switch (state_) + { + case CreatingSide1: + GetCommand()->SetCenter(scenePos); + break; + case CreatingSide2: + GetCommand()->SetSide2End(scenePos); + break; + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Wrong state in CreateAngleMeasureTracker::" + "PointerMove: state_ invalid"); + } + //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << + // "scenePos.GetY() = " << scenePos.GetY(); } - //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << - // "scenePos.GetY() = " << scenePos.GetY(); } void CreateAngleMeasureTracker::PointerUp(const PointerEvent& e)
--- a/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/CreateLineMeasureTracker.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -30,10 +30,18 @@ const PointerEvent& e) : CreateMeasureTracker(controllerW) { - command_.reset( - new CreateLineMeasureCommand( - controllerW, - e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform()))); + ScenePoint2D point = e.GetMainPosition(); + + { + boost::shared_ptr<ViewportController> controller = controllerW.lock(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + point = e.GetMainPosition().Apply(lock->GetScene().GetCanvasToSceneTransform()); + } + } + + command_.reset(new CreateLineMeasureCommand(controllerW, point)); } CreateLineMeasureTracker::~CreateLineMeasureTracker() @@ -50,16 +58,21 @@ "PointerMove: active_ == false"); } - ScenePoint2D scenePos = event.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); - - //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << - // "scenePos.GetY() = " << scenePos.GetY(); - - CreateLineMeasureTracker* concreteThis = - dynamic_cast<CreateLineMeasureTracker*>(this); - assert(concreteThis != NULL); - GetCommand()->SetEnd(scenePos); + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + ScenePoint2D scenePos = event.GetMainPosition().Apply( + lock->GetScene().GetCanvasToSceneTransform()); + + //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << + // "scenePos.GetY() = " << scenePos.GetY(); + + CreateLineMeasureTracker* concreteThis = + dynamic_cast<CreateLineMeasureTracker*>(this); + assert(concreteThis != NULL); + GetCommand()->SetEnd(scenePos); + } } void CreateLineMeasureTracker::PointerUp(const PointerEvent& e)
--- a/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/EditAngleMeasureTracker.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -31,8 +31,14 @@ const PointerEvent& e) : EditMeasureTracker(controllerW, e) { - ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); + ScenePoint2D scenePos = e.GetMainPosition(); + + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + scenePos = e.GetMainPosition().Apply(lock->GetScene().GetCanvasToSceneTransform()); + } modifiedZone_ = dynamic_cast<AngleMeasureTool&>(*measureTool).AngleHitTest(scenePos); @@ -46,50 +52,55 @@ void EditAngleMeasureTracker::PointerMove(const PointerEvent& e) { - ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); - - ScenePoint2D delta = scenePos - GetOriginalClickPosition(); - - boost::shared_ptr<AngleMeasureToolMemento> memento = - boost::dynamic_pointer_cast<AngleMeasureToolMemento>(command_->mementoOriginal_); - - ORTHANC_ASSERT(memento.get() != NULL); - - switch (modifiedZone_) - { - case AngleMeasureTool::AngleHighlightArea_Center: - { - ScenePoint2D newCenter = memento->center_ + delta; - GetCommand()->SetCenter(newCenter); - } - break; - case AngleMeasureTool::AngleHighlightArea_Side1: - case AngleMeasureTool::AngleHighlightArea_Side2: + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + if (controller) { - ScenePoint2D newCenter = memento->center_ + delta; - ScenePoint2D newSide1End = memento->side1End_ + delta; - ScenePoint2D newSide2End = memento->side2End_ + delta; - GetCommand()->SetCenter(newCenter); - GetCommand()->SetSide1End(newSide1End); - GetCommand()->SetSide2End(newSide2End); - } - break; - case AngleMeasureTool::AngleHighlightArea_Side1End: - { - ScenePoint2D newSide1End = memento->side1End_ + delta; - GetCommand()->SetSide1End(newSide1End); - } - break; - case AngleMeasureTool::AngleHighlightArea_Side2End: - { - ScenePoint2D newSide2End = memento->side2End_ + delta; - GetCommand()->SetSide2End(newSide2End); - } - break; - default: - LOG(WARNING) << "Warning: please retry the measuring tool editing operation!"; - break; + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + ScenePoint2D scenePos = e.GetMainPosition().Apply( + lock->GetScene().GetCanvasToSceneTransform()); + + ScenePoint2D delta = scenePos - GetOriginalClickPosition(); + + boost::shared_ptr<AngleMeasureToolMemento> memento = + boost::dynamic_pointer_cast<AngleMeasureToolMemento>(command_->mementoOriginal_); + + ORTHANC_ASSERT(memento.get() != NULL); + + switch (modifiedZone_) + { + case AngleMeasureTool::AngleHighlightArea_Center: + { + ScenePoint2D newCenter = memento->center_ + delta; + GetCommand()->SetCenter(newCenter); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side1: + case AngleMeasureTool::AngleHighlightArea_Side2: + { + ScenePoint2D newCenter = memento->center_ + delta; + ScenePoint2D newSide1End = memento->side1End_ + delta; + ScenePoint2D newSide2End = memento->side2End_ + delta; + GetCommand()->SetCenter(newCenter); + GetCommand()->SetSide1End(newSide1End); + GetCommand()->SetSide2End(newSide2End); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side1End: + { + ScenePoint2D newSide1End = memento->side1End_ + delta; + GetCommand()->SetSide1End(newSide1End); + } + break; + case AngleMeasureTool::AngleHighlightArea_Side2End: + { + ScenePoint2D newSide2End = memento->side2End_ + delta; + GetCommand()->SetSide2End(newSide2End); + } + break; + default: + LOG(WARNING) << "Warning: please retry the measuring tool editing operation!"; + break; + } } }
--- a/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/EditLineMeasureTracker.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -32,8 +32,16 @@ const PointerEvent& e) : EditMeasureTracker(controllerW, e) { - ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); + ScenePoint2D scenePos = e.GetMainPosition(); + + { + boost::shared_ptr<ViewportController> controller = controllerW.lock(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + scenePos = e.GetMainPosition().Apply(lock->GetScene().GetCanvasToSceneTransform()); + } + } modifiedZone_ = dynamic_cast<LineMeasureTool&>(*measureTool).LineHitTest(scenePos); @@ -47,44 +55,49 @@ void EditLineMeasureTracker::PointerMove(const PointerEvent& e) { - ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetScene().GetCanvasToSceneTransform()); - - ScenePoint2D delta = scenePos - GetOriginalClickPosition(); - - boost::shared_ptr<LineMeasureToolMemento> memento = - boost::dynamic_pointer_cast<LineMeasureToolMemento>(command_->mementoOriginal_); - - ORTHANC_ASSERT(memento.get() != NULL); - - switch (modifiedZone_) - { - case LineMeasureTool::LineHighlightArea_Start: + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + if (controller) { - ScenePoint2D newStart = memento->start_ + delta; - GetCommand()->SetStart(newStart); - } - break; - case LineMeasureTool::LineHighlightArea_End: - { - ScenePoint2D newEnd = memento->end_ + delta; - GetCommand()->SetEnd(newEnd); - } - break; - case LineMeasureTool::LineHighlightArea_Segment: - { - ScenePoint2D newStart = memento->start_ + delta; - ScenePoint2D newEnd = memento->end_ + delta; - GetCommand()->SetStart(newStart); - GetCommand()->SetEnd(newEnd); - } - break; - default: - LOG(WARNING) << "Warning: please retry the measuring tool editing operation!"; + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + ScenePoint2D scenePos = e.GetMainPosition().Apply( + lock->GetScene().GetCanvasToSceneTransform()); + + ScenePoint2D delta = scenePos - GetOriginalClickPosition(); + + boost::shared_ptr<LineMeasureToolMemento> memento = + boost::dynamic_pointer_cast<LineMeasureToolMemento>(command_->mementoOriginal_); + + ORTHANC_ASSERT(memento.get() != NULL); + + switch (modifiedZone_) + { + case LineMeasureTool::LineHighlightArea_Start: + { + ScenePoint2D newStart = memento->start_ + delta; + GetCommand()->SetStart(newStart); + } break; + case LineMeasureTool::LineHighlightArea_End: + { + ScenePoint2D newEnd = memento->end_ + delta; + GetCommand()->SetEnd(newEnd); + } + break; + case LineMeasureTool::LineHighlightArea_Segment: + { + ScenePoint2D newStart = memento->start_ + delta; + ScenePoint2D newEnd = memento->end_ + delta; + GetCommand()->SetStart(newStart); + GetCommand()->SetEnd(newEnd); + } + break; + default: + LOG(WARNING) << "Warning: please retry the measuring tool editing operation!"; + break; + } } } - + void EditLineMeasureTracker::PointerUp(const PointerEvent& e) { alive_ = false;
--- a/Framework/Scene2DViewport/LayerHolder.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/LayerHolder.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -43,24 +43,30 @@ void LayerHolder::CreateLayers() { - assert(baseLayerIndex_ == -1); + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); - baseLayerIndex_ = GetScene().GetMaxDepth() + 100; + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + + assert(baseLayerIndex_ == -1); + + baseLayerIndex_ = lock->GetScene().GetMaxDepth() + 100; - for (int i = 0; i < polylineLayerCount_; ++i) - { - std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); - GetScene().SetLayer(baseLayerIndex_ + i, layer.release()); + for (int i = 0; i < polylineLayerCount_; ++i) + { + std::auto_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer()); + lock->GetScene().SetLayer(baseLayerIndex_ + i, layer.release()); + } + + for (int i = 0; i < textLayerCount_; ++i) + { + std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); + lock->GetScene().SetLayer( + baseLayerIndex_ + polylineLayerCount_ + i, + layer.release()); + } } - - for (int i = 0; i < textLayerCount_; ++i) - { - std::auto_ptr<TextSceneLayer> layer(new TextSceneLayer()); - GetScene().SetLayer( - baseLayerIndex_ + polylineLayerCount_ + i, - layer.release()); - } - } void LayerHolder::CreateLayersIfNeeded() @@ -74,13 +80,6 @@ return (baseLayerIndex_ != -1); } - Scene2D& LayerHolder::GetScene() - { - boost::shared_ptr<ViewportController> controller = controllerW_.lock(); - ORTHANC_ASSERT(controller.get() != 0, "Zombie attack!"); - return controller->GetScene(); - } - void LayerHolder::DeleteLayersIfNeeded() { if (baseLayerIndex_ != -1) @@ -89,42 +88,71 @@ void LayerHolder::DeleteLayers() { - for (int i = 0; i < textLayerCount_ + polylineLayerCount_; ++i) + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + + if (controller) { - ORTHANC_ASSERT(GetScene().HasLayer(baseLayerIndex_ + i), "No layer"); - GetScene().DeleteLayer(baseLayerIndex_ + i); + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + + for (int i = 0; i < textLayerCount_ + polylineLayerCount_; ++i) + { + ORTHANC_ASSERT(lock->GetScene().HasLayer(baseLayerIndex_ + i), "No layer"); + lock->GetScene().DeleteLayer(baseLayerIndex_ + i); + } + baseLayerIndex_ = -1; } - baseLayerIndex_ = -1; } - + PolylineSceneLayer* LayerHolder::GetPolylineLayer(int index /*= 0*/) { - using namespace Orthanc; - ORTHANC_ASSERT(baseLayerIndex_ != -1); - ORTHANC_ASSERT(GetScene().HasLayer(GetPolylineLayerIndex(index))); - ISceneLayer* layer = - &(GetScene().GetLayer(GetPolylineLayerIndex(index))); + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); - PolylineSceneLayer* concreteLayer = - dynamic_cast<PolylineSceneLayer*>(layer); - - ORTHANC_ASSERT(concreteLayer != NULL); - return concreteLayer; + using namespace Orthanc; + ORTHANC_ASSERT(baseLayerIndex_ != -1); + ORTHANC_ASSERT(lock->GetScene().HasLayer(GetPolylineLayerIndex(index))); + ISceneLayer* layer = + &(lock->GetScene().GetLayer(GetPolylineLayerIndex(index))); + + PolylineSceneLayer* concreteLayer = + dynamic_cast<PolylineSceneLayer*>(layer); + + ORTHANC_ASSERT(concreteLayer != NULL); + return concreteLayer; + } + else + { + return NULL; // TODO + } } TextSceneLayer* LayerHolder::GetTextLayer(int index /*= 0*/) { - using namespace Orthanc; - ORTHANC_ASSERT(baseLayerIndex_ != -1); - ORTHANC_ASSERT(GetScene().HasLayer(GetTextLayerIndex(index))); - ISceneLayer* layer = - &(GetScene().GetLayer(GetTextLayerIndex(index))); + boost::shared_ptr<ViewportController> controller = controllerW_.lock(); + + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); - TextSceneLayer* concreteLayer = - dynamic_cast<TextSceneLayer*>(layer); - - ORTHANC_ASSERT(concreteLayer != NULL); - return concreteLayer; + using namespace Orthanc; + ORTHANC_ASSERT(baseLayerIndex_ != -1); + ORTHANC_ASSERT(lock->GetScene().HasLayer(GetTextLayerIndex(index))); + ISceneLayer* layer = + &(lock->GetScene().GetLayer(GetTextLayerIndex(index))); + + TextSceneLayer* concreteLayer = + dynamic_cast<TextSceneLayer*>(layer); + + ORTHANC_ASSERT(concreteLayer != NULL); + return concreteLayer; + } + else + { + return NULL; // TODO + } } int LayerHolder::GetPolylineLayerIndex(int index /*= 0*/)
--- a/Framework/Scene2DViewport/LayerHolder.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/LayerHolder.h Fri Nov 29 21:22:21 2019 +0100 @@ -97,7 +97,6 @@ int GetPolylineLayerIndex(int index = 0); int GetTextLayerIndex(int index = 0); int GetInfoTextLayerIndex(int index = 0); - Scene2D& GetScene(); int textLayerCount_; int polylineLayerCount_;
--- a/Framework/Scene2DViewport/LineMeasureTool.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/LineMeasureTool.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -108,8 +108,10 @@ LineMeasureTool::LineHighlightArea LineMeasureTool::LineHitTest(ScenePoint2D p) const { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + const double pixelToScene = - GetController()->GetScene().GetCanvasToSceneTransform().ComputeZoom(); + lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); const double SQUARED_HIT_TEST_MAX_DISTANCE_SCENE_COORD = pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD * pixelToScene * HIT_TEST_MAX_DISTANCE_CANVAS_COORD; const double sqDistanceFromStart = ScenePoint2D::SquaredDistancePtPt(p, start_); @@ -134,8 +136,10 @@ boost::shared_ptr<IFlexiblePointerTracker> LineMeasureTool::CreateEditionTracker(const PointerEvent& e) { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + ScenePoint2D scenePos = e.GetMainPosition().Apply( - GetController()->GetScene().GetCanvasToSceneTransform()); + lock->GetScene().GetCanvasToSceneTransform()); if (!HitTest(scenePos)) return boost::shared_ptr<IFlexiblePointerTracker>(); @@ -176,61 +180,65 @@ { if (IsEnabled()) { + std::auto_ptr<IViewport::ILock> lock(GetController()->GetViewport().Lock()); + layerHolder_->CreateLayersIfNeeded(); { // Fill the polyline layer with the measurement line PolylineSceneLayer* polylineLayer = layerHolder_->GetPolylineLayer(0); - polylineLayer->ClearAllChains(); - - const Color color(TOOL_LINES_COLOR_RED, - TOOL_LINES_COLOR_GREEN, - TOOL_LINES_COLOR_BLUE); - - const Color highlightColor(TOOL_LINES_HL_COLOR_RED, - TOOL_LINES_HL_COLOR_GREEN, - TOOL_LINES_HL_COLOR_BLUE); - + if (polylineLayer) { - PolylineSceneLayer::Chain chain; - chain.push_back(start_); - chain.push_back(end_); - if(lineHighlightArea_ == LineHighlightArea_Segment) - polylineLayer->AddChain(chain, false, highlightColor); - else - polylineLayer->AddChain(chain, false, color); - } + polylineLayer->ClearAllChains(); - // handles - { - { - PolylineSceneLayer::Chain chain; - - //TODO: take DPI into account - AddSquare(chain, GetController()->GetScene(), start_, - GetController()->GetHandleSideLengthS()); - - if (lineHighlightArea_ == LineHighlightArea_Start) - polylineLayer->AddChain(chain, true, highlightColor); - else - polylineLayer->AddChain(chain, true, color); - } + const Color color(TOOL_LINES_COLOR_RED, + TOOL_LINES_COLOR_GREEN, + TOOL_LINES_COLOR_BLUE); + + const Color highlightColor(TOOL_LINES_HL_COLOR_RED, + TOOL_LINES_HL_COLOR_GREEN, + TOOL_LINES_HL_COLOR_BLUE); { PolylineSceneLayer::Chain chain; + chain.push_back(start_); + chain.push_back(end_); + if(lineHighlightArea_ == LineHighlightArea_Segment) + polylineLayer->AddChain(chain, false, highlightColor); + else + polylineLayer->AddChain(chain, false, color); + } + + // handles + { + { + PolylineSceneLayer::Chain chain; - //TODO: take DPI into account - AddSquare(chain, GetController()->GetScene(), end_, - GetController()->GetHandleSideLengthS()); + //TODO: take DPI into account + AddSquare(chain, lock->GetScene(), start_, + GetController()->GetHandleSideLengthS()); - if (lineHighlightArea_ == LineHighlightArea_End) - polylineLayer->AddChain(chain, true, highlightColor); - else - polylineLayer->AddChain(chain, true, color); + if (lineHighlightArea_ == LineHighlightArea_Start) + polylineLayer->AddChain(chain, true, highlightColor); + else + polylineLayer->AddChain(chain, true, color); + } + + { + PolylineSceneLayer::Chain chain; + + //TODO: take DPI into account + AddSquare(chain, lock->GetScene(), end_, + GetController()->GetHandleSideLengthS()); + + if (lineHighlightArea_ == LineHighlightArea_End) + polylineLayer->AddChain(chain, true, highlightColor); + else + polylineLayer->AddChain(chain, true, color); + } } } - } { // Set the text layer propreties @@ -248,10 +256,10 @@ #if ORTHANC_STONE_ENABLE_OUTLINED_TEXT == 1 SetTextLayerOutlineProperties( - GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY), 0); + lock->GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY), 0); #else SetTextLayerProperties( - GetController()->GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY), 0); + lock->GetScene(), layerHolder_, buf, ScenePoint2D(midX, midY), 0); #endif } }
--- a/Framework/Scene2DViewport/MeasureToolsToolbox.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/MeasureToolsToolbox.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -306,28 +306,30 @@ for (int i = startingLayerIndex; i < startingLayerIndex + 5; ++i) { TextSceneLayer* textLayer = layerHolder->GetTextLayer(i); - ORTHANC_ASSERT(textLayer != NULL); - textLayer->SetText(text); - - if (i == startingLayerIndex + 4) - { - textLayer->SetColor(TEXT_COLOR_RED, - TEXT_COLOR_GREEN, - TEXT_COLOR_BLUE); - } - else + if (textLayer != NULL) { - textLayer->SetColor(TEXT_OUTLINE_COLOR_RED, - TEXT_OUTLINE_COLOR_GREEN, - TEXT_OUTLINE_COLOR_BLUE); - } + textLayer->SetText(text); - ScenePoint2D textAnchor; - int offIndex = i - startingLayerIndex; - ORTHANC_ASSERT(offIndex >= 0 && offIndex < 5); - textLayer->SetPosition( - p.GetX() + xoffsets[offIndex] * pixelToScene, - p.GetY() + yoffsets[offIndex] * pixelToScene); + if (i == startingLayerIndex + 4) + { + textLayer->SetColor(TEXT_COLOR_RED, + TEXT_COLOR_GREEN, + TEXT_COLOR_BLUE); + } + else + { + textLayer->SetColor(TEXT_OUTLINE_COLOR_RED, + TEXT_OUTLINE_COLOR_GREEN, + TEXT_OUTLINE_COLOR_BLUE); + } + + ScenePoint2D textAnchor; + int offIndex = i - startingLayerIndex; + ORTHANC_ASSERT(offIndex >= 0 && offIndex < 5); + textLayer->SetPosition( + p.GetX() + xoffsets[offIndex] * pixelToScene, + p.GetY() + yoffsets[offIndex] * pixelToScene); + } } } #else @@ -339,20 +341,21 @@ , int layerIndex) { TextSceneLayer* textLayer = layerHolder->GetTextLayer(layerIndex); - ORTHANC_ASSERT(textLayer != NULL); - textLayer->SetText(text); + if (textLayer != NULL) + { + textLayer->SetText(text); + textLayer->SetColor(TEXT_COLOR_RED, TEXT_COLOR_GREEN, TEXT_COLOR_BLUE); - textLayer->SetColor(TEXT_COLOR_RED, TEXT_COLOR_GREEN, TEXT_COLOR_BLUE); - - ScenePoint2D textAnchor; - textLayer->SetPosition(p.GetX(), p.GetY()); + ScenePoint2D textAnchor; + textLayer->SetPosition(p.GetX(), p.GetY()); + } } #endif - std::ostream& operator<<(std::ostream& os, const ScenePoint2D& p) - { - os << "x = " << p.GetX() << " , y = " << p.GetY(); - return os; - } + std::ostream& operator<<(std::ostream& os, const ScenePoint2D& p) + { + os << "x = " << p.GetX() << " , y = " << p.GetY(); + return os; + } }
--- a/Framework/Scene2DViewport/MeasureTrackers.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/MeasureTrackers.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -53,23 +53,18 @@ command_->Undo(); } - Scene2D& CreateMeasureTracker::GetScene() - { - return controllerW_.lock()->GetScene(); - } - EditMeasureTracker::EditMeasureTracker(boost::weak_ptr<ViewportController> controllerW, const PointerEvent& e) : controllerW_(controllerW) , alive_(true) , commitResult_(true) { boost::shared_ptr<ViewportController> controller = controllerW.lock(); - originalClickPosition_ = e.GetMainPosition().Apply(controller->GetScene().GetCanvasToSceneTransform()); - } - Scene2D& EditMeasureTracker::GetScene() - { - return controllerW_.lock()->GetScene(); + if (controller) + { + std::auto_ptr<IViewport::ILock> lock(controller->GetViewport().Lock()); + originalClickPosition_ = e.GetMainPosition().Apply(lock->GetScene().GetCanvasToSceneTransform()); + } } void EditMeasureTracker::Cancel()
--- a/Framework/Scene2DViewport/MeasureTrackers.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/MeasureTrackers.h Fri Nov 29 21:22:21 2019 +0100 @@ -48,7 +48,6 @@ boost::shared_ptr<CreateMeasureCommand> command_; boost::weak_ptr<ViewportController> controllerW_; bool alive_; - Scene2D& GetScene(); private: bool commitResult_; @@ -68,7 +67,6 @@ boost::shared_ptr<EditMeasureCommand> command_; boost::weak_ptr<ViewportController> controllerW_; bool alive_; - Scene2D& GetScene(); ScenePoint2D GetOriginalClickPosition() const {
--- a/Framework/Scene2DViewport/ViewportController.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/ViewportController.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -136,20 +136,26 @@ } } - const OrthancStone::AffineTransform2D& ViewportController::GetCanvasToSceneTransform() const + OrthancStone::AffineTransform2D ViewportController::GetCanvasToSceneTransform() const { - return GetScene().GetCanvasToSceneTransform(); + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + return lock->GetScene().GetCanvasToSceneTransform(); } - const OrthancStone::AffineTransform2D& ViewportController::GetSceneToCanvasTransform() const + OrthancStone::AffineTransform2D ViewportController::GetSceneToCanvasTransform() const { - return GetScene().GetSceneToCanvasTransform(); + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + return lock->GetScene().GetSceneToCanvasTransform(); } void ViewportController::SetSceneToCanvasTransform( const AffineTransform2D& transform) { - viewport_.GetScene().SetSceneToCanvasTransform(transform); + { + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + lock->GetScene().SetSceneToCanvasTransform(transform); + } + BroadcastMessage(SceneTransformChanged(*this)); // update the canvas to scene factor @@ -160,16 +166,22 @@ void ViewportController::FitContent( unsigned int canvasWidth, unsigned int canvasHeight) { - viewport_.GetScene().FitContent(canvasWidth, canvasHeight); + { + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + lock->GetScene().FitContent(canvasWidth, canvasHeight); + } + BroadcastMessage(SceneTransformChanged(*this)); } void ViewportController::FitContent() { - if (viewport_.HasCompositor()) + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + + if (lock->HasCompositor()) { - const ICompositor& compositor = viewport_.GetCompositor(); - viewport_.GetScene().FitContent(compositor.GetCanvasWidth(), compositor.GetCanvasHeight()); + const ICompositor& compositor = lock->GetCompositor(); + lock->GetScene().FitContent(compositor.GetCanvasWidth(), compositor.GetCanvasHeight()); BroadcastMessage(SceneTransformChanged(*this)); } } @@ -195,8 +207,8 @@ { if (canvasToSceneFactor_ == 0) { - canvasToSceneFactor_ = - GetScene().GetCanvasToSceneTransform().ComputeZoom(); + std::auto_ptr<IViewport::ILock> lock(viewport_.Lock()); + canvasToSceneFactor_ = lock->GetScene().GetCanvasToSceneTransform().ComputeZoom(); } return canvasToSceneFactor_; }
--- a/Framework/Scene2DViewport/ViewportController.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Scene2DViewport/ViewportController.h Fri Nov 29 21:22:21 2019 +0100 @@ -112,10 +112,10 @@ void SetActiveTracker(boost::shared_ptr<IFlexiblePointerTracker> tracker); /** Forwarded to the underlying scene */ - const AffineTransform2D& GetCanvasToSceneTransform() const; + AffineTransform2D GetCanvasToSceneTransform() const; /** Forwarded to the underlying scene */ - const AffineTransform2D& GetSceneToCanvasTransform() const; + AffineTransform2D GetSceneToCanvasTransform() const; /** Forwarded to the underlying scene, and broadcasted to the observers */ void SetSceneToCanvasTransform(const AffineTransform2D& transform); @@ -172,14 +172,9 @@ /** forwarded to the UndoStack */ bool CanRedo() const; - Scene2D& GetScene() + IViewport& GetViewport() const { - return viewport_.GetScene(); - } - - const Scene2D& GetScene() const - { - return const_cast<IViewport&>(viewport_).GetScene(); + return viewport_; } private:
--- a/Framework/Viewport/IViewport.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Viewport/IViewport.h Fri Nov 29 21:22:21 2019 +0100 @@ -29,25 +29,39 @@ /** * Class that combines a Scene2D with a canvas where to draw the * scene. A call to "Refresh()" will update the content of the - * canvas. + * canvas. A "IViewport" can possibly be accessed from several + * threads depending on the rendering back-end (e.g. in SDL or Qt): + * The "ILock" subclass implements the locking mechanism to modify + * the content of the scene. + * + * NB: The lock must be a "recursive_mutex", as the viewport + * controller can lock it a second time (TODO - Why so?). **/ class IViewport : public boost::noncopyable { public: + class ILock : public boost::noncopyable + { + public: + virtual ~ILock() + { + } + + virtual Scene2D& GetScene() = 0; + + virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) = 0; + + virtual bool HasCompositor() const = 0; + + virtual ICompositor& GetCompositor() = 0; + }; + virtual ~IViewport() { } - virtual Scene2D& GetScene() = 0; - virtual void Refresh() = 0; - virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const = 0; - - virtual bool HasCompositor() const = 0; - - virtual ICompositor& GetCompositor() = 0; - - virtual const ICompositor& GetCompositor() const = 0; + virtual ILock* Lock() = 0; }; }
--- a/Framework/Viewport/SdlViewport.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Viewport/SdlViewport.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -22,8 +22,6 @@ #include <Core/OrthancException.h> -#include <boost/make_shared.hpp> - namespace OrthancStone { SdlOpenGLViewport::SdlOpenGLViewport(const char* title, @@ -35,19 +33,9 @@ compositor_.reset(new OpenGLCompositor(context_, GetScene())); } - SdlOpenGLViewport::SdlOpenGLViewport(const char* title, - unsigned int width, - unsigned int height, - boost::shared_ptr<Scene2D>& scene, - bool allowDpiScaling) : - SdlViewport(scene), - context_(title, width, height, allowDpiScaling) - { - compositor_.reset(new OpenGLCompositor(context_, GetScene())); - } - void SdlOpenGLViewport::Refresh() { + boost::mutex::scoped_lock lock(mutex_); compositor_->Refresh(); } @@ -70,22 +58,29 @@ } } - void SdlCairoViewport::Refresh() + void SdlCairoViewport::RefreshInternal() // Assumes that the mutex is locked { compositor_.Refresh(); window_.Render(sdlSurface_); } + void SdlCairoViewport::Refresh() + { + boost::mutex::scoped_lock lock(mutex_); + RefreshInternal(); + } + void SdlCairoViewport::UpdateSize(unsigned int width, unsigned int height) { + boost::mutex::scoped_lock lock(mutex_); compositor_.UpdateSize(width, height); UpdateSdlSurfaceSize(width, height); - Refresh(); + RefreshInternal(); } void SdlCairoViewport::UpdateSdlSurfaceSize(unsigned int width, - unsigned int height) + unsigned int height) // Assumes that the mutex is locked { static const uint32_t rmask = 0x00ff0000; static const uint32_t gmask = 0x0000ff00;
--- a/Framework/Viewport/SdlViewport.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Viewport/SdlViewport.h Fri Nov 29 21:22:21 2019 +0100 @@ -45,18 +45,14 @@ { class SdlViewport : public ViewportBase { + protected: + boost::mutex mutex_; + public: SdlViewport() { } - SdlViewport(boost::shared_ptr<Scene2D>& scene) : - ViewportBase(scene) - { - } - - virtual SdlWindow& GetWindow() = 0; - virtual void UpdateSize(unsigned int width, unsigned int height) = 0; }; @@ -66,52 +62,87 @@ { private: SdlOpenGLContext context_; - std::auto_ptr<OpenGLCompositor> compositor_; + std::auto_ptr<OpenGLCompositor> compositor_; + class SdlLock : public LockBase + { + private: + SdlOpenGLViewport& that_; + boost::mutex::scoped_lock lock_; + + public: + SdlLock(SdlOpenGLViewport& viewport) : + LockBase(viewport), + that_(viewport), + lock_(viewport.mutex_) + { + } + + virtual bool HasCompositor() const ORTHANC_OVERRIDE + { + return true; + } + + virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE + { + return *that_.compositor_; + } + }; + public: SdlOpenGLViewport(const char* title, unsigned int width, unsigned int height, bool allowDpiScaling = true); - SdlOpenGLViewport(const char* title, - unsigned int width, - unsigned int height, - boost::shared_ptr<Scene2D>& scene, - bool allowDpiScaling = true); + virtual void Refresh() ORTHANC_OVERRIDE; - virtual SdlWindow& GetWindow() ORTHANC_OVERRIDE + virtual ILock* Lock() ORTHANC_OVERRIDE { - return context_.GetWindow(); + return new SdlLock(*this); } - virtual void Refresh() ORTHANC_OVERRIDE; - virtual void UpdateSize(unsigned int width, unsigned int height) ORTHANC_OVERRIDE { // nothing to do in OpenGL, the OpenGLCompositor::UpdateSize will be called automatically } - - virtual bool HasCompositor() const ORTHANC_OVERRIDE - { - return true; - } - - virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE - { - return *compositor_.get(); - } }; class SdlCairoViewport : public SdlViewport { private: + class SdlLock : public LockBase + { + private: + SdlCairoViewport& that_; + boost::mutex::scoped_lock lock_; + + public: + SdlLock(SdlCairoViewport& viewport) : + LockBase(viewport), + that_(viewport), + lock_(viewport.mutex_) + { + } + + virtual bool HasCompositor() const ORTHANC_OVERRIDE + { + return true; + } + + virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE + { + return that_.compositor_; + } + }; + SdlWindow window_; CairoCompositor compositor_; SDL_Surface* sdlSurface_; - private: + void RefreshInternal(); + void UpdateSdlSurfaceSize(unsigned int width, unsigned int height); @@ -121,32 +152,11 @@ unsigned int height, bool allowDpiScaling = true); - SdlCairoViewport(const char* title, - unsigned int width, - unsigned int height, - boost::shared_ptr<Scene2D>& scene, - bool allowDpiScaling = true); - ~SdlCairoViewport(); - virtual SdlWindow& GetWindow() ORTHANC_OVERRIDE - { - return window_; - } - virtual void Refresh() ORTHANC_OVERRIDE; virtual void UpdateSize(unsigned int width, unsigned int height) ORTHANC_OVERRIDE; - - virtual bool HasCompositor() const ORTHANC_OVERRIDE - { - return true; - } - - virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE - { - return compositor_; - } }; }
--- a/Framework/Viewport/ViewportBase.cpp Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Viewport/ViewportBase.cpp Fri Nov 29 21:22:21 2019 +0100 @@ -26,27 +26,11 @@ namespace OrthancStone { - ViewportBase::ViewportBase() : - scene_(boost::make_shared<Scene2D>()) - { - } - - - ViewportBase::ViewportBase(boost::shared_ptr<Scene2D>& scene) : - scene_(scene) - { - if (scene.get() == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); - } - } - - - ScenePoint2D ViewportBase::GetPixelCenterCoordinates(int x, int y) const + ScenePoint2D ViewportBase::LockBase::GetPixelCenterCoordinates(int x, int y) { if (HasCompositor()) { - const ICompositor& compositor = GetCompositor(); + ICompositor& compositor = GetCompositor(); return ScenePoint2D( static_cast<double>(x) + 0.5 - static_cast<double>(compositor.GetCanvasWidth()) / 2.0, static_cast<double>(y) + 0.5 - static_cast<double>(compositor.GetCanvasHeight()) / 2.0);
--- a/Framework/Viewport/ViewportBase.h Fri Nov 29 11:03:41 2019 +0100 +++ b/Framework/Viewport/ViewportBase.h Fri Nov 29 21:22:21 2019 +0100 @@ -29,25 +29,31 @@ class ViewportBase : public IViewport { private: - boost::shared_ptr<Scene2D> scene_; + Scene2D scene_; - public: - ViewportBase(); - - ViewportBase(boost::shared_ptr<Scene2D>& scene); - - virtual Scene2D& GetScene() ORTHANC_OVERRIDE + protected: + class LockBase : public ILock { - return *scene_; - } + private: + ViewportBase& that_; - virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const ORTHANC_OVERRIDE; + public: + LockBase(ViewportBase& that) : + that_(that) + { + } - virtual const ICompositor& GetCompositor() const ORTHANC_OVERRIDE + virtual Scene2D& GetScene() ORTHANC_OVERRIDE + { + return that_.scene_; + } + + virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) ORTHANC_OVERRIDE; + }; + + Scene2D& GetScene() { - IViewport* mutableThis = - const_cast<IViewport*>(static_cast<const IViewport*>(this)); - return mutableThis->GetCompositor(); + return scene_; } }; }