Skip to content
Snippets Groups Projects
Commit 09c25a60 authored by Sergey Gorbunov's avatar Sergey Gorbunov Committed by Sergey Gorbunov
Browse files

CbmQaPie class as a TPie wrapper, which prevents crashes

parent 1189808e
No related branches found
No related tags found
1 merge request!150CbmQaPie class as a TPie wrapper, which prevents crashes
......@@ -20,6 +20,7 @@ link_directories( ${LINK_DIRECTORIES})
set(SRCS
CbmQaCanvas.cxx
CbmQaPie.cxx
)
set(LINKDEF CbmQaBaseLinkDef.h)
......
......@@ -5,4 +5,6 @@
#pragma link off all functions;
#pragma link C++ class CbmQaCanvas - ;
#pragma link C++ class CbmQaPieSlice + ;
#pragma link C++ class CbmQaPie - ;
#endif
/// \file CbmQaPie.cxx
/// \brief Implementation of the CbmQaPie class
/// \author Sergey Gorbunov <se.gorbunov@gsi.de>
/// \date 07.11.2020
#include "CbmQaPie.h"
#include "TBrowser.h"
#include "TBuffer.h"
#include "TPad.h"
ClassImp(CbmQaPieSlice);
ClassImp(CbmQaPie);
CbmQaPie::CbmQaPie(const CbmQaPie& cpy)
: TPie(cpy.GetName(), cpy.GetTitle(), cpy.fNvals) {
/// Prevent original copy constructor from a crash
cpy.TAttText::Copy(*this);
fAngularOffset = cpy.fAngularOffset;
fX = cpy.fX;
fY = cpy.fY;
fRadius = cpy.fRadius;
for (Int_t i = 0; i < fNvals; ++i) {
*fPieSlices[i] = *cpy.fPieSlices[i];
((CbmQaPieSlice*) fPieSlices[i])->SetPie(this);
}
}
void CbmQaPie::Browse(TBrowser* b) {
/// Draw CbmQaPie by a mouse click in the TBrowser
Draw(b ? b->GetDrawOption() : "");
gPad->Update();
}
void CbmQaPie::Draw(Option_t* option) {
// Prevents original TPie::Draw() from crashing when there are no entries
double sum = 0.;
for (int i = 0; i < fNvals; i++) {
sum += fabs(GetEntryVal(i));
}
if (sum < 1.e-20) {
for (int i = 0; i < fNvals; i++) {
SetEntryVal(i, 1.e-20);
}
}
TPie::Draw(option);
if (sum < 1.e-20) {
for (int i = 0; i < fNvals; i++) {
SetEntryVal(i, 0.);
}
}
}
void CbmQaPie::Streamer(TBuffer& R__b) {
/// The Streamer is declared by ClassDef() macro
/// Stream an object of class CbmQaPie
///
if (R__b.IsReading()) {
for (int i = 0; i < fNvals; i++) {
if (gPad && gPad->GetListOfPrimitives()) {
gPad->GetListOfPrimitives()->Remove(fPieSlices[i]);
}
delete fPieSlices[i];
fPieSlices[i] = nullptr;
}
delete[] fPieSlices;
fPieSlices = nullptr;
fNvals = 0;
R__b.ReadClassBuffer(CbmQaPie::Class(), this);
fNvals = fSliceStore.size();
fPieSlices = new TPieSlice*[fNvals];
for (int i = 0; i < fNvals; i++) {
fSliceStore[i].SetPie(this);
fPieSlices[i] = new TPieSlice(fSliceStore[i]);
}
fSliceStore.clear();
} else {
fSliceStore.resize(fNvals);
for (int i = 0; i < fNvals; i++) {
fSliceStore[i] = *fPieSlices[i];
fSliceStore[i].SetPie(nullptr);
}
TPieSlice** tmp = fPieSlices;
fPieSlices = nullptr;
fNvals = 0;
R__b.WriteClassBuffer(CbmQaPie::Class(), this);
fPieSlices = tmp;
fNvals = fSliceStore.size();
fSliceStore.clear();
}
}
/// \file CbmQaPie.h
/// \brief Definition of the CbmQaPie class
/// \author Sergey Gorbunov <se.gorbunov@gsi.de>
/// \date 07.11.2020
#ifndef CbmQaPie_H
#define CbmQaPie_H
#include "TPie.h"
#include "TPieSlice.h"
#include <vector>
class TBrowser;
/// A helper class for accessing protected members of TPieSlice
///
class CbmQaPieSlice : public TPieSlice {
public:
/// assignment operator
CbmQaPieSlice& operator=(const TPieSlice& inp) {
return (*this = (const CbmQaPieSlice&) (inp));
}
/// set a TPie pointer
void SetPie(TPie* p) { fPie = p; }
ClassDef(CbmQaPieSlice, 1);
};
/// A modification of TPie which fixes the following issues:
///
/// 1. When a TPie is read from a file as a part of TCanvas, it crashes at the destructor.
/// 2. When a TPie is created via copy constructor it crashes at the destructor.
/// 3. An empty TPie crashes at Draw()
/// 4. When one clicks on a TPie in the TBrowser, the TBrowser crashes.
/// 5. TBrowser dosen't draw a TPie by a mouse click.
///
class CbmQaPie : public TPie {
public:
/// Reimplementation of any existing TPie constructor
template<typename... Types>
CbmQaPie(Types... args) : TPie(args...) {}
/// Prevent original copy constructor from a crash
CbmQaPie(const CbmQaPie& cpy);
/// Destructor
~CbmQaPie() {}
/// Draw TPie by a mouse click in the TBrowser
void Browse(TBrowser* b);
/// Prevents original TPie::Draw() from crashing when there are no entries
void Draw(Option_t* option = "l");
private:
/// a vector for slice streaming. It replaces the original array of pointers.
std::vector<CbmQaPieSlice> fSliceStore;
ClassDef(CbmQaPie, 1);
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment