<commit_before>// @(#)root/base:$Name:  $:$Id: TBrowser.cxx,v 1.5 2001/09/18 21:58:39 rdm Exp $
// Author: Fons Rademakers   25/10/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Using a TBrowser one can browse all ROOT objects. It shows in a list //
// on the left side of the window all browsable ROOT classes. Selecting //
// one of the classes displays, in the iconbox on the right side, all   //
// objects in the class. Selecting one of the objects in the iconbox,   //
// will place all browsable objects in a new list and draws the         //
// contents of the selected class in the iconbox. And so on....         //
//                                                                      //
//Begin_Html  End_Html                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TBrowser.h"
#include "TGuiFactory.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TStyle.h"
#include "TTimer.h"
#include "TContextMenu.h"
#include "TInterpreter.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TBrowserTimer                                                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TBrowserTimer : public TTimer {

protected:
   TBrowser *fBrowser;
   Bool_t    fActivate;

public:
   TBrowserTimer(TBrowser *b, Long_t ms = 1000)
      : TTimer(ms, kTRUE), fBrowser(b), fActivate(kFALSE) { }
   Bool_t Notify();
};

ClassImp(TBrowser)

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title)
   : TNamed(name, title)
{
   // Create a new browser with a name, title. Width and height are by
   // default set to 640x400 and (optionally) adjusted by the screen factor
   // (depending on Rint.Canvas.UseScreenFactor to be true or false, default
   // is true).

   Float_t cx = gStyle->GetScreenFactor();
   UInt_t w = UInt_t(cx*640);
   UInt_t h = UInt_t(cx*400);

   fImp = gGuiFactory->CreateBrowserImp(this, title, w, h);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height.

   fImp = gGuiFactory->CreateBrowserImp(this, title, width, height);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title, Int_t x, Int_t y, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, position, width and height.

   fImp = gGuiFactory->CreateBrowserImp(this, title, x, y, width, height);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   Float_t cx = gStyle->GetScreenFactor();
   UInt_t w = UInt_t(cx*640);
   UInt_t h = UInt_t(cx*400);

   fImp = gGuiFactory->CreateBrowserImp(this, title, w, h);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   fImp = gGuiFactory->CreateBrowserImp(this, title, width, height);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title, Int_t x, Int_t y, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   fImp = gGuiFactory->CreateBrowserImp(this, title, x, y, width, height);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::~TBrowser()
{
   // Delete the browser.

   gROOT->GetListOfBrowsers()->Remove(this);
   delete fContextMenu;
   delete fTimer;
   delete fImp;
}

//______________________________________________________________________________
void TBrowser::Add(TObject *obj, const char *name)
{
   // Add object with name to browser. If name not set the objects GetName()
   // is used.

   if (obj && fImp) {
      fImp->Add(obj, name);
      obj->SetBit(kMustCleanup);
   }
}

//______________________________________________________________________________
void TBrowser::Create(TObject *obj)
{
   // Create the browser, called by the ctors.

   fNeedRefresh = kFALSE;

   fTimer = new TBrowserTimer(this);
   gSystem->AddTimer(fTimer);

   gROOT->GetListOfBrowsers()->Add(this);

   // Get the list of globals
   gROOT->GetListOfGlobals(kTRUE);
   gROOT->GetListOfGlobalFunctions(kTRUE);

   fContextMenu = new TContextMenu("BrowserContextMenu") ;

   // Fill the first list from the present TObject obj
   if (obj) {
      Add(obj);
#ifndef WIN32
      if (fImp) fImp->BrowseObj(obj);
#else
#ifdef GDK_WIN32
      if (fImp) fImp->BrowseObj(obj);
#endif
 //     obj->Browse(this);
#endif
   }
   // Fill the first list with all browsable classes from TROOT
#ifndef WIN32
   else if (fImp) fImp->BrowseObj(gROOT);
#else
#ifdef GDK_WIN32
   else if (fImp) fImp->BrowseObj(gROOT);
#endif
   // The first list will be filled by TWin32BrowserImp ctor
   // with all browsable classes from TROOT
#endif
}

//______________________________________________________________________________
void TBrowser::ExecuteDefaultAction(TObject *obj)
{
   // Execute default action for selected object (action is specified
   // in the $HOME/.root.mimes or $ROOTSYS/etc/root.mimes file.

   if (obj && fImp)
      fImp->ExecuteDefaultAction(obj);
}

//______________________________________________________________________________
void TBrowser::RecursiveRemove(TObject *obj)
{
   // Recursively remove obj from browser.

   if (fImp && obj) {
      fImp->RecursiveRemove(obj);
      fNeedRefresh = kTRUE;
   }
}

//______________________________________________________________________________
void TBrowser::Refresh()
{
   // Refresh browser contents.

   fNeedRefresh = kTRUE;
   if (fImp) fImp->Refresh();
   fNeedRefresh = kFALSE;
}

//______________________________________________________________________________
void TBrowser::SetSelected(TObject *clickedObject)
{
   // Assign the last selected object.

   fLastSelectedObject = clickedObject;
}

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TBrowserTimer                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
Bool_t TBrowserTimer::Notify()
{
   // Called whenever timer times out.

   if (fBrowser) {
      if (fBrowser->GetRefreshFlag()) {
         fBrowser->SetRefreshFlag(kFALSE);
         fActivate = kTRUE;
      } else if (fActivate) {
         fActivate = kFALSE;
         fBrowser->Refresh();
      }
   }
   Reset();

   return kFALSE;
}
<commit_msg>Remove win32 conditional code, now that we have TWin32BrowserImp::BrowseObj<commit_after>// @(#)root/base:$Name:  $:$Id: TBrowser.cxx,v 1.6 2001/11/28 15:58:13 rdm Exp $
// Author: Fons Rademakers   25/10/95

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Using a TBrowser one can browse all ROOT objects. It shows in a list //
// on the left side of the window all browsable ROOT classes. Selecting //
// one of the classes displays, in the iconbox on the right side, all   //
// objects in the class. Selecting one of the objects in the iconbox,   //
// will place all browsable objects in a new list and draws the         //
// contents of the selected class in the iconbox. And so on....         //
//                                                                      //
//Begin_Html  End_Html                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TBrowser.h"
#include "TGuiFactory.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TStyle.h"
#include "TTimer.h"
#include "TContextMenu.h"
#include "TInterpreter.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TBrowserTimer                                                        //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TBrowserTimer : public TTimer {

protected:
   TBrowser *fBrowser;
   Bool_t    fActivate;

public:
   TBrowserTimer(TBrowser *b, Long_t ms = 1000)
      : TTimer(ms, kTRUE), fBrowser(b), fActivate(kFALSE) { }
   Bool_t Notify();
};

ClassImp(TBrowser)

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title)
   : TNamed(name, title)
{
   // Create a new browser with a name, title. Width and height are by
   // default set to 640x400 and (optionally) adjusted by the screen factor
   // (depending on Rint.Canvas.UseScreenFactor to be true or false, default
   // is true).

   Float_t cx = gStyle->GetScreenFactor();
   UInt_t w = UInt_t(cx*640);
   UInt_t h = UInt_t(cx*400);

   fImp = gGuiFactory->CreateBrowserImp(this, title, w, h);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height.

   fImp = gGuiFactory->CreateBrowserImp(this, title, width, height);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, const char *title, Int_t x, Int_t y, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, position, width and height.

   fImp = gGuiFactory->CreateBrowserImp(this, title, x, y, width, height);
   Create();
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   Float_t cx = gStyle->GetScreenFactor();
   UInt_t w = UInt_t(cx*640);
   UInt_t h = UInt_t(cx*400);

   fImp = gGuiFactory->CreateBrowserImp(this, title, w, h);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   fImp = gGuiFactory->CreateBrowserImp(this, title, width, height);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::TBrowser(const char *name, TObject *obj, const char *title, Int_t x, Int_t y, UInt_t width, UInt_t height)
   : TNamed(name, title)
{
   // Create a new browser with a name, title, width and height for TObject *obj.

   fImp = gGuiFactory->CreateBrowserImp(this, title, x, y, width, height);
   Create(obj);
}

//______________________________________________________________________________
TBrowser::~TBrowser()
{
   // Delete the browser.

   gROOT->GetListOfBrowsers()->Remove(this);
   delete fContextMenu;
   delete fTimer;
   delete fImp;
}

//______________________________________________________________________________
void TBrowser::Add(TObject *obj, const char *name)
{
   // Add object with name to browser. If name not set the objects GetName()
   // is used.

   if (obj && fImp) {
      fImp->Add(obj, name);
      obj->SetBit(kMustCleanup);
   }
}

//______________________________________________________________________________
void TBrowser::Create(TObject *obj)
{
   // Create the browser, called by the ctors.

   fNeedRefresh = kFALSE;

   fTimer = new TBrowserTimer(this);
   gSystem->AddTimer(fTimer);

   gROOT->GetListOfBrowsers()->Add(this);

   // Get the list of globals
   gROOT->GetListOfGlobals(kTRUE);
   gROOT->GetListOfGlobalFunctions(kTRUE);

   fContextMenu = new TContextMenu("BrowserContextMenu") ;

   // Fill the first list from the present TObject obj
   if (obj) {
      Add(obj);
      if (fImp) fImp->BrowseObj(obj);
   }
   // Fill the first list with all browsable classes from TROOT
   else if (fImp) fImp->BrowseObj(gROOT);
   // The first list will be filled by TWin32BrowserImp ctor
   // with all browsable classes from TROOT
}

//______________________________________________________________________________
void TBrowser::ExecuteDefaultAction(TObject *obj)
{
   // Execute default action for selected object (action is specified
   // in the $HOME/.root.mimes or $ROOTSYS/etc/root.mimes file.

   if (obj && fImp)
      fImp->ExecuteDefaultAction(obj);
}

//______________________________________________________________________________
void TBrowser::RecursiveRemove(TObject *obj)
{
   // Recursively remove obj from browser.

   if (fImp && obj) {
      fImp->RecursiveRemove(obj);
      fNeedRefresh = kTRUE;
   }
}

//______________________________________________________________________________
void TBrowser::Refresh()
{
   // Refresh browser contents.

   fNeedRefresh = kTRUE;
   if (fImp) fImp->Refresh();
   fNeedRefresh = kFALSE;
}

//______________________________________________________________________________
void TBrowser::SetSelected(TObject *clickedObject)
{
   // Assign the last selected object.

   fLastSelectedObject = clickedObject;
}

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TBrowserTimer                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
Bool_t TBrowserTimer::Notify()
{
   // Called whenever timer times out.

   if (fBrowser) {
      if (fBrowser->GetRefreshFlag()) {
         fBrowser->SetRefreshFlag(kFALSE);
         fActivate = kTRUE;
      } else if (fActivate) {
         fActivate = kFALSE;
         fBrowser->Refresh();
      }
   }
   Reset();

   return kFALSE;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkAAClip.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkString.h"
#include "SkCanvas.h"
#include "SkRandom.h"

////////////////////////////////////////////////////////////////////////////////
// This bench tests out AA/BW clipping via canvas' clipPath and clipRect calls
class AAClipBench : public SkBenchmark {
    SkString fName;
    SkPath   fClipPath;
    SkRect   fClipRect;
    SkRect   fDrawRect;
    bool     fDoPath;
    bool     fDoAA;

    enum {
        N = SkBENCHLOOP(200),
    };

public:
    AAClipBench(void* param, bool doPath, bool doAA)
        : INHERITED(param)
        , fDoPath(doPath)
        , fDoAA(doAA) {

        fName.printf("aaclip_%s_%s",
                     doPath ? "path" : "rect",
                     doAA ? "AA" : "BW");

        fClipRect.set(SkFloatToScalar(10.5), SkFloatToScalar(10.5),
                      SkFloatToScalar(50.5), SkFloatToScalar(50.5));
        fClipPath.addRoundRect(fClipRect, SkIntToScalar(10), SkIntToScalar(10));
        fDrawRect.set(SkIntToScalar(0), SkIntToScalar(0),
                      SkIntToScalar(100), SkIntToScalar(100));

        SkASSERT(fClipPath.isConvex());
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }
    virtual void onDraw(SkCanvas* canvas) {

        SkPaint paint;
        this->setupPaint(&paint);

        for (int i = 0; i < N; ++i) {
            // jostle the clip regions each time to prevent caching
            fClipRect.offset((i % 2) == 0 ? SkIntToScalar(10) : SkIntToScalar(-10), 0);
            fClipPath.reset();
            fClipPath.addRoundRect(fClipRect,
                                   SkIntToScalar(5), SkIntToScalar(5));
            SkASSERT(fClipPath.isConvex());

            canvas->save();
#if 1
            if (fDoPath) {
                canvas->clipPath(fClipPath, SkRegion::kReplace_Op, fDoAA);
            } else {
                canvas->clipRect(fClipRect, SkRegion::kReplace_Op, fDoAA);
            }

            canvas->drawRect(fDrawRect, paint);
#else
            // this path tests out directly draw the clip primitive
            // use it to comparing just drawing the clip vs. drawing using
            // the clip
            if (fDoPath) {
                canvas->drawPath(fClipPath, paint);
            } else {
                canvas->drawRect(fClipRect, paint);
            }
#endif
            canvas->restore();
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
// This bench tests out nested clip stacks. It is intended to simulate
// how WebKit nests clips.
class NestedAAClipBench : public SkBenchmark {
    SkString fName;
    bool     fDoAA;
    SkRect   fDrawRect;
    SkRandom fRandom;

    static const int kNumDraws = SkBENCHLOOP(200);
    static const int kNestingDepth = 4;
    static const int kImageSize = 400;

    SkPoint fSizes[kNestingDepth+1];

public:
    NestedAAClipBench(void* param, bool doAA)
        : INHERITED(param)
        , fDoAA(doAA) {

        fName.printf("nested_aaclip_%s", doAA ? "AA" : "BW");

        fDrawRect = SkRect::MakeLTRB(0, 0,
                                     SkIntToScalar(kImageSize),
                                     SkIntToScalar(kImageSize));

        fSizes[0].set(SkIntToScalar(kImageSize), SkIntToScalar(kImageSize));

        for (int i = 1; i < kNestingDepth+1; ++i) {
            fSizes[i].set(fSizes[i-1].fX/2, fSizes[i-1].fY/2);
        }
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }

    void recurse(SkCanvas* canvas,
                 int depth,
                 const SkPoint& offset) {

            canvas->save();

            SkRect temp = SkRect::MakeLTRB(0, 0,
                                           fSizes[depth].fX, fSizes[depth].fY);
            temp.offset(offset);

            SkPath path;
            path.addRoundRect(temp, SkIntToScalar(3), SkIntToScalar(3));
            SkASSERT(path.isConvex());

            canvas->clipPath(path,
                             0 == depth ? SkRegion::kReplace_Op :
                                          SkRegion::kIntersect_Op,
                             fDoAA);

            if (kNestingDepth == depth) {
                // we only draw the draw rect at the lowest nesting level
                SkPaint paint;
                paint.setColor(0xff000000 | fRandom.nextU());
                canvas->drawRect(fDrawRect, paint);
            } else {
                SkPoint childOffset = offset;
                this->recurse(canvas, depth+1, childOffset);

                childOffset += fSizes[depth+1];
                this->recurse(canvas, depth+1, childOffset);

                childOffset.fX = offset.fX + fSizes[depth+1].fX;
                childOffset.fY = offset.fY;
                this->recurse(canvas, depth+1, childOffset);

                childOffset.fX = offset.fX;
                childOffset.fY = offset.fY + fSizes[depth+1].fY;
                this->recurse(canvas, depth+1, childOffset);
            }

            canvas->restore();
    }

    virtual void onDraw(SkCanvas* canvas) {

        for (int i = 0; i < kNumDraws; ++i) {
            SkPoint offset = SkPoint::Make(0, 0);
            this->recurse(canvas, 0, offset);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
class AAClipBuilderBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkRect   fRect;
    SkRegion fRegion;
    bool     fDoPath;
    bool     fDoAA;

    enum {
        N = SkBENCHLOOP(200),
    };

public:
    AAClipBuilderBench(void* param, bool doPath, bool doAA) : INHERITED(param) {
        fDoPath = doPath;
        fDoAA = doAA;

        fName.printf("aaclip_build_%s_%s", doPath ? "path" : "rect",
                     doAA ? "AA" : "BW");

        fRegion.setRect(0, 0, 640, 480);
        fRect.set(fRegion.getBounds());
        fRect.inset(SK_Scalar1/4, SK_Scalar1/4);
        fPath.addRoundRect(fRect, SkIntToScalar(20), SkIntToScalar(20));
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        for (int i = 0; i < N; ++i) {
            SkAAClip clip;
            if (fDoPath) {
                clip.setPath(fPath, &fRegion, fDoAA);
            } else {
                clip.setRect(fRect, fDoAA);
            }
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
class AAClipRegionBench : public SkBenchmark {
public:
    AAClipRegionBench(void* param) : INHERITED(param) {
        SkPath path;
        // test conversion of a complex clip to a aaclip
        path.addCircle(0, 0, SkIntToScalar(200));
        path.addCircle(0, 0, SkIntToScalar(180));
        // evenodd means we've constructed basically a stroked circle
        path.setFillType(SkPath::kEvenOdd_FillType);

        SkIRect bounds;
        path.getBounds().roundOut(&bounds);
        fRegion.setPath(path, SkRegion(bounds));
    }

protected:
    virtual const char* onGetName() { return "aaclip_setregion"; }
    virtual void onDraw(SkCanvas* canvas) {
        for (int i = 0; i < N; ++i) {
            SkAAClip clip;
            clip.setRegion(fRegion);
        }
    }

private:
    enum {
        N = SkBENCHLOOP(400),
    };
    SkRegion fRegion;
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////

static SkBenchmark* Fact0(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, false, false)); }
static SkBenchmark* Fact1(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, false, true)); }
static SkBenchmark* Fact2(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, true, false)); }
static SkBenchmark* Fact3(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, true, true)); }

static BenchRegistry gReg0(Fact0);
static BenchRegistry gReg1(Fact1);
static BenchRegistry gReg2(Fact2);
static BenchRegistry gReg3(Fact3);

static SkBenchmark* Fact01(void* p) { return SkNEW_ARGS(AAClipRegionBench, (p)); }
static BenchRegistry gReg01(Fact01);

static SkBenchmark* Fact000(void* p) { return SkNEW_ARGS(AAClipBench, (p, false, false)); }
static SkBenchmark* Fact001(void* p) { return SkNEW_ARGS(AAClipBench, (p, false, true)); }
static SkBenchmark* Fact002(void* p) { return SkNEW_ARGS(AAClipBench, (p, true, false)); }
static SkBenchmark* Fact003(void* p) { return SkNEW_ARGS(AAClipBench, (p, true, true)); }

static BenchRegistry gReg000(Fact000);
static BenchRegistry gReg001(Fact001);
static BenchRegistry gReg002(Fact002);
static BenchRegistry gReg003(Fact003);

static SkBenchmark* Fact004(void* p) { return SkNEW_ARGS(NestedAAClipBench, (p, false)); }
static SkBenchmark* Fact005(void* p) { return SkNEW_ARGS(NestedAAClipBench, (p, true)); }

static BenchRegistry gReg004(Fact004);
static BenchRegistry gReg005(Fact005);
<commit_msg>Dialed back complexity of nested clip bench to bring time down to a reasonable level<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkAAClip.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkString.h"
#include "SkCanvas.h"
#include "SkRandom.h"

////////////////////////////////////////////////////////////////////////////////
// This bench tests out AA/BW clipping via canvas' clipPath and clipRect calls
class AAClipBench : public SkBenchmark {
    SkString fName;
    SkPath   fClipPath;
    SkRect   fClipRect;
    SkRect   fDrawRect;
    bool     fDoPath;
    bool     fDoAA;

    enum {
        N = SkBENCHLOOP(200),
    };

public:
    AAClipBench(void* param, bool doPath, bool doAA)
        : INHERITED(param)
        , fDoPath(doPath)
        , fDoAA(doAA) {

        fName.printf("aaclip_%s_%s",
                     doPath ? "path" : "rect",
                     doAA ? "AA" : "BW");

        fClipRect.set(SkFloatToScalar(10.5), SkFloatToScalar(10.5),
                      SkFloatToScalar(50.5), SkFloatToScalar(50.5));
        fClipPath.addRoundRect(fClipRect, SkIntToScalar(10), SkIntToScalar(10));
        fDrawRect.set(SkIntToScalar(0), SkIntToScalar(0),
                      SkIntToScalar(100), SkIntToScalar(100));

        SkASSERT(fClipPath.isConvex());
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }
    virtual void onDraw(SkCanvas* canvas) {

        SkPaint paint;
        this->setupPaint(&paint);

        for (int i = 0; i < N; ++i) {
            // jostle the clip regions each time to prevent caching
            fClipRect.offset((i % 2) == 0 ? SkIntToScalar(10) : SkIntToScalar(-10), 0);
            fClipPath.reset();
            fClipPath.addRoundRect(fClipRect,
                                   SkIntToScalar(5), SkIntToScalar(5));
            SkASSERT(fClipPath.isConvex());

            canvas->save();
#if 1
            if (fDoPath) {
                canvas->clipPath(fClipPath, SkRegion::kReplace_Op, fDoAA);
            } else {
                canvas->clipRect(fClipRect, SkRegion::kReplace_Op, fDoAA);
            }

            canvas->drawRect(fDrawRect, paint);
#else
            // this path tests out directly draw the clip primitive
            // use it to comparing just drawing the clip vs. drawing using
            // the clip
            if (fDoPath) {
                canvas->drawPath(fClipPath, paint);
            } else {
                canvas->drawRect(fClipRect, paint);
            }
#endif
            canvas->restore();
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
// This bench tests out nested clip stacks. It is intended to simulate
// how WebKit nests clips.
class NestedAAClipBench : public SkBenchmark {
    SkString fName;
    bool     fDoAA;
    SkRect   fDrawRect;
    SkRandom fRandom;

    static const int kNumDraws = SkBENCHLOOP(2);
    static const int kNestingDepth = 3;
    static const int kImageSize = 400;

    SkPoint fSizes[kNestingDepth+1];

public:
    NestedAAClipBench(void* param, bool doAA)
        : INHERITED(param)
        , fDoAA(doAA) {

        fName.printf("nested_aaclip_%s", doAA ? "AA" : "BW");

        fDrawRect = SkRect::MakeLTRB(0, 0,
                                     SkIntToScalar(kImageSize),
                                     SkIntToScalar(kImageSize));

        fSizes[0].set(SkIntToScalar(kImageSize), SkIntToScalar(kImageSize));

        for (int i = 1; i < kNestingDepth+1; ++i) {
            fSizes[i].set(fSizes[i-1].fX/2, fSizes[i-1].fY/2);
        }
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }

    void recurse(SkCanvas* canvas,
                 int depth,
                 const SkPoint& offset) {

            canvas->save();

            SkRect temp = SkRect::MakeLTRB(0, 0,
                                           fSizes[depth].fX, fSizes[depth].fY);
            temp.offset(offset);

            SkPath path;
            path.addRoundRect(temp, SkIntToScalar(3), SkIntToScalar(3));
            SkASSERT(path.isConvex());

            canvas->clipPath(path,
                             0 == depth ? SkRegion::kReplace_Op :
                                          SkRegion::kIntersect_Op,
                             fDoAA);

            if (kNestingDepth == depth) {
                // we only draw the draw rect at the lowest nesting level
                SkPaint paint;
                paint.setColor(0xff000000 | fRandom.nextU());
                canvas->drawRect(fDrawRect, paint);
            } else {
                SkPoint childOffset = offset;
                this->recurse(canvas, depth+1, childOffset);

                childOffset += fSizes[depth+1];
                this->recurse(canvas, depth+1, childOffset);

                childOffset.fX = offset.fX + fSizes[depth+1].fX;
                childOffset.fY = offset.fY;
                this->recurse(canvas, depth+1, childOffset);

                childOffset.fX = offset.fX;
                childOffset.fY = offset.fY + fSizes[depth+1].fY;
                this->recurse(canvas, depth+1, childOffset);
            }

            canvas->restore();
    }

    virtual void onDraw(SkCanvas* canvas) {

        for (int i = 0; i < kNumDraws; ++i) {
            SkPoint offset = SkPoint::Make(0, 0);
            this->recurse(canvas, 0, offset);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
class AAClipBuilderBench : public SkBenchmark {
    SkString fName;
    SkPath   fPath;
    SkRect   fRect;
    SkRegion fRegion;
    bool     fDoPath;
    bool     fDoAA;

    enum {
        N = SkBENCHLOOP(200),
    };

public:
    AAClipBuilderBench(void* param, bool doPath, bool doAA) : INHERITED(param) {
        fDoPath = doPath;
        fDoAA = doAA;

        fName.printf("aaclip_build_%s_%s", doPath ? "path" : "rect",
                     doAA ? "AA" : "BW");

        fRegion.setRect(0, 0, 640, 480);
        fRect.set(fRegion.getBounds());
        fRect.inset(SK_Scalar1/4, SK_Scalar1/4);
        fPath.addRoundRect(fRect, SkIntToScalar(20), SkIntToScalar(20));
    }

protected:
    virtual const char* onGetName() { return fName.c_str(); }
    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        for (int i = 0; i < N; ++i) {
            SkAAClip clip;
            if (fDoPath) {
                clip.setPath(fPath, &fRegion, fDoAA);
            } else {
                clip.setRect(fRect, fDoAA);
            }
        }
    }
private:
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////
class AAClipRegionBench : public SkBenchmark {
public:
    AAClipRegionBench(void* param) : INHERITED(param) {
        SkPath path;
        // test conversion of a complex clip to a aaclip
        path.addCircle(0, 0, SkIntToScalar(200));
        path.addCircle(0, 0, SkIntToScalar(180));
        // evenodd means we've constructed basically a stroked circle
        path.setFillType(SkPath::kEvenOdd_FillType);

        SkIRect bounds;
        path.getBounds().roundOut(&bounds);
        fRegion.setPath(path, SkRegion(bounds));
    }

protected:
    virtual const char* onGetName() { return "aaclip_setregion"; }
    virtual void onDraw(SkCanvas* canvas) {
        for (int i = 0; i < N; ++i) {
            SkAAClip clip;
            clip.setRegion(fRegion);
        }
    }

private:
    enum {
        N = SkBENCHLOOP(400),
    };
    SkRegion fRegion;
    typedef SkBenchmark INHERITED;
};

////////////////////////////////////////////////////////////////////////////////

static SkBenchmark* Fact0(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, false, false)); }
static SkBenchmark* Fact1(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, false, true)); }
static SkBenchmark* Fact2(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, true, false)); }
static SkBenchmark* Fact3(void* p) { return SkNEW_ARGS(AAClipBuilderBench, (p, true, true)); }

static BenchRegistry gReg0(Fact0);
static BenchRegistry gReg1(Fact1);
static BenchRegistry gReg2(Fact2);
static BenchRegistry gReg3(Fact3);

static SkBenchmark* Fact01(void* p) { return SkNEW_ARGS(AAClipRegionBench, (p)); }
static BenchRegistry gReg01(Fact01);

static SkBenchmark* Fact000(void* p) { return SkNEW_ARGS(AAClipBench, (p, false, false)); }
static SkBenchmark* Fact001(void* p) { return SkNEW_ARGS(AAClipBench, (p, false, true)); }
static SkBenchmark* Fact002(void* p) { return SkNEW_ARGS(AAClipBench, (p, true, false)); }
static SkBenchmark* Fact003(void* p) { return SkNEW_ARGS(AAClipBench, (p, true, true)); }

static BenchRegistry gReg000(Fact000);
static BenchRegistry gReg001(Fact001);
static BenchRegistry gReg002(Fact002);
static BenchRegistry gReg003(Fact003);

static SkBenchmark* Fact004(void* p) { return SkNEW_ARGS(NestedAAClipBench, (p, false)); }
static SkBenchmark* Fact005(void* p) { return SkNEW_ARGS(NestedAAClipBench, (p, true)); }

static BenchRegistry gReg004(Fact004);
static BenchRegistry gReg005(Fact005);
<|endoftext|>


<commit_before>///
/// @file   main.cpp
/// @brief  This file contains the main() function of the primesieve
///         console (terminal) application.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/soe/ParallelPrimeSieve.h>
#include "cmdoptions.h"

#include <iostream>
#include <exception>
#include <iomanip>
#include <algorithm>
#include <string>

using namespace std;

void printResults(const ParallelPrimeSieve& pps)
{
  const string primeLabels[7] =
  {
    "Prime numbers",
    "Twin primes",
    "Prime triplets",
    "Prime quadruplets",
    "Prime quintuplets",
    "Prime sextuplets",
    "Prime septuplets"
  };

  int size = 0;
  for (int i = 0; i < 7; i++) {
    if (pps.isCount(i))
      size = max(size, static_cast<int>(primeLabels[i].size()));
  }

  for (int i = 0; i < 7; i++) {
    if (pps.isCount(i))
      cout << setw(size) << primeLabels[i] << " : "
           << pps.getCount(i)
           << endl;
  }

  if (!pps.isPrint())
    cout << setw(size) << "Time elapsed" << " : "
         << pps.getSeconds() << " sec"
         << endl;
}

int main(int argc, char** argv)
{
  PrimeSieveOptions options = parseOptions(argc, argv);
  ParallelPrimeSieve pps;
  cout << left;

  try
  {
    // needed to print the number of threads
    if (options.nthPrime)
    {
      if (options.n.size() == 1)
        options.n.push_back(0);
      pps.setStart(options.n[1]);
      pps.setStop(options.n[1]+ options.n[0] * 30);
    }
    else
    {
      if (options.n.size() == 1)
        options.n.push_front(0);
      pps.setStart(options.n[0]);
      pps.setStop(options.n[1]);
    }

    if (options.flags     != 0) pps.setFlags(options.flags);
    if (options.sieveSize != 0) pps.setSieveSize(options.sieveSize);
    if (options.threads   != 0) pps.setNumThreads(options.threads);
    else if (pps.isPrint())     pps.setNumThreads(1);

    if (!options.quiet)
    {
      cout << "Sieve size = " << pps.getSieveSize() << " kilobytes" << endl;
      cout << "Threads    = " << pps.getNumThreads() << endl;
      if (!pps.isPrint())
        pps.addFlags(pps.PRINT_STATUS);
    }

    if (options.nthPrime)
    {
      uint64_t nthPrime = pps.nthPrime(options.n[0], options.n[1]);
      cout << "Nth prime    : " << nthPrime << endl;
      cout << "Time elapsed : " << pps.getSeconds() << " sec" << endl;
    }
    else
    {
      pps.sieve();
      printResults(pps);
    }
  }
  catch (exception& e)
  {
    cerr << "Error: " << e.what() << "." << endl
         << "Try `primesieve --help' for more information." << endl;
    return 1;
  }
  return 0;
}
<commit_msg>Refactoring<commit_after>///
/// @file   main.cpp
/// @brief  This file contains the main() function of the primesieve
///         console (terminal) application.
///
/// Copyright (C) 2013 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/soe/ParallelPrimeSieve.h>
#include "cmdoptions.h"

#include <iostream>
#include <exception>
#include <iomanip>
#include <algorithm>
#include <string>

using namespace std;

void printResults(const ParallelPrimeSieve& pps)
{
  const string primeLabels[7] =
  {
    "Prime numbers",
    "Twin primes",
    "Prime triplets",
    "Prime quadruplets",
    "Prime quintuplets",
    "Prime sextuplets",
    "Prime septuplets"
  };

  int size = 0;
  for (int i = 0; i < 7; i++) {
    if (pps.isCount(i))
      size = max(size, static_cast<int>(primeLabels[i].size()));
  }

  for (int i = 0; i < 7; i++) {
    if (pps.isCount(i))
      cout << setw(size) << primeLabels[i] << " : "
           << pps.getCount(i)
           << endl;
  }

  if (!pps.isPrint())
    cout << setw(size) << "Time elapsed" << " : "
         << pps.getSeconds() << " sec"
         << endl;
}

int main(int argc, char** argv)
{
  PrimeSieveOptions options = parseOptions(argc, argv);
  ParallelPrimeSieve pps;
  cout << left;

  try
  {
    // needed to print the number of threads
    if (options.nthPrime)
    {
      if (options.n.size() == 1)
        options.n.push_back(0);
      pps.setStart(options.n[1]);
      pps.setStop(options.n[1] + options.n[0] * 30);
    }
    else
    {
      if (options.n.size() == 1)
        options.n.push_front(0);
      pps.setStart(options.n[0]);
      pps.setStop(options.n[1]);
    }

    if (options.flags     != 0) pps.setFlags(options.flags);
    if (options.sieveSize != 0) pps.setSieveSize(options.sieveSize);
    if (options.threads   != 0) pps.setNumThreads(options.threads);
    else if (pps.isPrint())     pps.setNumThreads(1);

    if (!options.quiet)
    {
      cout << "Sieve size = " << pps.getSieveSize() << " kilobytes" << endl;
      cout << "Threads    = " << pps.getNumThreads() << endl;
      if (!pps.isPrint())
        pps.addFlags(pps.PRINT_STATUS);
    }

    if (options.nthPrime)
    {
      uint64_t nthPrime = pps.nthPrime(options.n[0], options.n[1]);
      cout << "Nth prime    : " << nthPrime << endl;
      cout << "Time elapsed : " << pps.getSeconds() << " sec" << endl;
    }
    else
    {
      pps.sieve();
      printResults(pps);
    }
  }
  catch (exception& e)
  {
    cerr << "Error: " << e.what() << "." << endl
         << "Try `primesieve --help' for more information." << endl;
    return 1;
  }
  return 0;
}
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/float_v>
#include <Vc/uint_v>
#include <Vc/IO>
#include "benchmark.h"

using namespace Vc;

// to benchmark the performance of gathers there are some different interesting cases:
// 1) gathers from the same memory location (basically broadcasts)
// 2) gathers from the same cache line (random access but localized to 64 or 128 bytes) (64 on
//    most CPUs)
// 3) random access on memory that fits into L1 but is larger than a cache line
// 4) random access on memory that fits into L2 (per core) but is larger than L1
// 4b) random access on memory that fits into all of L2 but is larger than the per core L2
// 5) random access on memory that fits into L3 but is larger than L2
// 6) random access on memory that fits into memory but is larger than L3
// 7) random access on memory that fits into virtual memory but is larger than physical memory
//
// of those the last 3 are probably not interesting because they basically measure memory
// latency.

// Intel Core 2 Quad (Q6600) has 8MB L2

enum {
    Repetitions = 2,
    Factor = 160000 / float_v::Size,
    MaxArraySize = 16 * 1024 * 1024 / sizeof(float), //  16 MB
    L2ArraySize = 256 * 1024 / sizeof(float),        // 256 KB
    L1ArraySize = 32 * 1024 / sizeof(float),         //  32 KB
    CacheLineArraySize = 64 / sizeof(float),         //  64 B
    SingleArraySize = 1                              //   4 B
};

// this is not a random number generator
class PseudoRandom
{
    public:
        PseudoRandom() : state(IndexesFromZero) {}
        uint_v next();

    private:
        uint_v state;
};

uint_v PseudoRandom::next()
{
    state = (state * 1103515245 + 12345);
    return state >> 10;
}

void nextIndexes(uint_v &i, const unsigned int size)
{
    static PseudoRandom r;
    i = r.next() & (size - 1);
}

int doGather(const char *name, const unsigned int size, const float *data)
{
    int blackHole = 0;
    Benchmark timer(name, 2. * float_v::Size * Factor * sizeof(float), "B");
    uint_v indexes1(IndexesFromZero);
    uint_v indexes2(indexes1 + 1);
    nextIndexes(indexes1, size);
    nextIndexes(indexes2, size);
    for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
        float_v aa(Zero);
        float_v bb(Zero);
        timer.Start();
        for (int i = 0; i < Factor; ++i) {
            nextIndexes(indexes1, size);
            nextIndexes(indexes2, size);
            float_v a(data, indexes1);
            float_v b(data, indexes2);
            aa += a;
            bb += b;
        }
        timer.Stop();
        const int k = (aa < 20.f) && (bb < 20.f);
        blackHole += k;
    }
    timer.Print();
    return blackHole;
}

int main()
{
    int blackHole = 1;

    float *data = new float[MaxArraySize];
    for (int i = 0; i < MaxArraySize; ++i) {
        data[i] = static_cast<float>(static_cast<double>(rand()) / static_cast<double>(RAND_MAX));
    }

    blackHole += doGather("Broadcast Gather", SingleArraySize, data);
    blackHole += doGather("Cacheline Gather", CacheLineArraySize, data);
    blackHole += doGather("L1 Gather", L1ArraySize, data);
    blackHole += doGather("L2 Gather", L2ArraySize, data);
    blackHole += doGather("Memory Gather", MaxArraySize, data);

    if (blackHole < 10) {
        std::cout << std::endl;
    }
    return 0;
}
<commit_msg>compile with icc<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/float_v>
#include <Vc/uint_v>
#include <Vc/IO>
#include "benchmark.h"

#include <cstdlib>

using namespace Vc;

// to benchmark the performance of gathers there are some different interesting cases:
// 1) gathers from the same memory location (basically broadcasts)
// 2) gathers from the same cache line (random access but localized to 64 or 128 bytes) (64 on
//    most CPUs)
// 3) random access on memory that fits into L1 but is larger than a cache line
// 4) random access on memory that fits into L2 (per core) but is larger than L1
// 4b) random access on memory that fits into all of L2 but is larger than the per core L2
// 5) random access on memory that fits into L3 but is larger than L2
// 6) random access on memory that fits into memory but is larger than L3
// 7) random access on memory that fits into virtual memory but is larger than physical memory
//
// of those the last 3 are probably not interesting because they basically measure memory
// latency.

// Intel Core 2 Quad (Q6600) has 8MB L2

enum {
    Repetitions = 2,
    Factor = 160000 / float_v::Size,
    MaxArraySize = 16 * 1024 * 1024 / sizeof(float), //  16 MB
    L2ArraySize = 256 * 1024 / sizeof(float),        // 256 KB
    L1ArraySize = 32 * 1024 / sizeof(float),         //  32 KB
    CacheLineArraySize = 64 / sizeof(float),         //  64 B
    SingleArraySize = 1                              //   4 B
};

// this is not a random number generator
class PseudoRandom
{
    public:
        PseudoRandom() : state(IndexesFromZero) {}
        uint_v next();

    private:
        uint_v state;
};

uint_v PseudoRandom::next()
{
    state = (state * 1103515245 + 12345);
    return state >> 10;
}

void nextIndexes(uint_v &i, const unsigned int size)
{
    static PseudoRandom r;
    i = r.next() & (size - 1);
}

int doGather(const char *name, const unsigned int size, const float *data)
{
    int blackHole = 0;
    Benchmark timer(name, 2. * float_v::Size * Factor * sizeof(float), "B");
    uint_v indexes1(IndexesFromZero);
    uint_v indexes2(indexes1 + 1);
    nextIndexes(indexes1, size);
    nextIndexes(indexes2, size);
    for (int repetitions = 0; repetitions < Repetitions; ++repetitions) {
        float_v aa(Zero);
        float_v bb(Zero);
        timer.Start();
        for (int i = 0; i < Factor; ++i) {
            nextIndexes(indexes1, size);
            nextIndexes(indexes2, size);
            float_v a(data, indexes1);
            float_v b(data, indexes2);
            aa += a;
            bb += b;
        }
        timer.Stop();
        const int k = (aa < 20.f) && (bb < 20.f);
        blackHole += k;
    }
    timer.Print();
    return blackHole;
}

int main()
{
    int blackHole = 1;

    float *data = new float[MaxArraySize];
    for (int i = 0; i < MaxArraySize; ++i) {
        data[i] = static_cast<float>(static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX));
    }

    blackHole += doGather("Broadcast Gather", SingleArraySize, data);
    blackHole += doGather("Cacheline Gather", CacheLineArraySize, data);
    blackHole += doGather("L1 Gather", L1ArraySize, data);
    blackHole += doGather("L2 Gather", L2ArraySize, data);
    blackHole += doGather("Memory Gather", MaxArraySize, data);

    if (blackHole < 10) {
        std::cout << std::endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//  Copyright (c) 2006-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NASA Vision Workbench is licensed under the Apache License,
//  Version 2.0 (the "License"); you may not use this file except in
//  compliance with the License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__

/// \file stereo_gui_MainWindow.cc
///
/// The Vision Workbench image viewer main window class.
///
#include <QtGui>
#include <asp/GUI/MainWindow.h>
#include <asp/GUI/MainWidget.h>
#include <asp/GUI/Utils.h>
using namespace vw::gui;

#include <vw/config.h>
#include <vw/Image/MaskViews.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/FileIO/DiskImageResource.h>
#include <vw/Image/Statistics.h>
#include <vw/Image/PixelMask.h>
#include <boost/filesystem/path.hpp>

#include <sstream>
namespace po = boost::program_options;

MainWindow::MainWindow(std::vector<std::string> const& images,
                       std::string const& geom,
                       bool ignore_georef, bool hillshade, int argc,  char ** argv) :
  m_images(images), m_widRatio(0.3), m_main_widget(NULL),
  m_chooseFiles(NULL), m_argc(argc), m_argv(argv) {

  int windowWidX, windowWidY;
  extractWindowDims(geom, windowWidX, windowWidY);
  resize(windowWidX, windowWidY);

  // Set the window title and add tabs
  std::string window_title = "Stereo GUI";
  this->setWindowTitle(window_title.c_str());

  // Set up the basic layout of the window and its menus.
  create_menus();

  if (images.size() > 1){

    // Split the window into two, with the sidebar on the left

    QWidget * centralFrame;
    centralFrame = new QWidget(this);
    setCentralWidget(centralFrame);

    QSplitter *splitter = new QSplitter(centralFrame);
#if 0
    m_chooseFiles = new chooseFilesDlg(this);
    m_chooseFiles->setMaximumSize(int(m_widRatio*size().width()), size().height());
    m_main_widget = new MainWidget(centralFrame, images, m_chooseFiles,
                                   ignore_georef, hillshade);
    splitter->addWidget(m_chooseFiles);
    splitter->addWidget(m_main_widget);
#else
    // for doing stereo
    std::vector<std::string> left_images, right_images;
    // TODO: Verify that these are valid images.
    // TODO: Invoke here asp's handle_arguments().
    if (images.size() >= 1)
      left_images.push_back(images[0]);
    if (images.size() >= 2)
      right_images.push_back(images[1]);

    m_left_widget = new MainWidget(centralFrame, left_images, m_chooseFiles,
                                   ignore_georef, hillshade);
    splitter->addWidget(m_left_widget);

    if (images.size() >= 2) {
      m_right_widget = new MainWidget(centralFrame, right_images, m_chooseFiles,
                                      ignore_georef, hillshade);
      splitter->addWidget(m_right_widget);
    }

#endif
    QGridLayout *layout = new QGridLayout(centralFrame);
    layout->addWidget (splitter, 0, 0, 0);
    centralFrame->setLayout (layout);
  }else{
    // Set up MainWidget
    m_main_widget = new MainWidget(this, images, NULL, ignore_georef, hillshade);
    setCentralWidget(m_main_widget);
  }

}

//********************************************************************
//                      MAIN WINDOW SETUP
//********************************************************************

void MainWindow::create_menus() {

  QMenuBar* menu = menuBar();

  // Exit or Quit
  m_exit_action = new QAction(tr("Exit"), this);
  m_exit_action->setShortcut(tr("Q"));
  m_exit_action->setStatusTip(tr("Exit the application"));
  connect(m_exit_action, SIGNAL(triggered()), this, SLOT(forceQuit()));

  // Run stereo
  m_run_stereo_action = new QAction(tr("Run stereo"), this);
  m_run_stereo_action->setStatusTip(tr("Run stereo on selected clips."));
  connect(m_run_stereo_action, SIGNAL(triggered()), this, SLOT(run_stereo()));
  m_run_stereo_action->setShortcut(tr("R"));

  // Size to fit
  m_size_to_fit_action = new QAction(tr("Size to fit"), this);
  m_size_to_fit_action->setStatusTip(tr("Change the view to encompass the images."));
  connect(m_size_to_fit_action, SIGNAL(triggered()), this, SLOT(size_to_fit()));
  m_size_to_fit_action->setShortcut(tr("F"));

  // The About Box
  m_about_action = new QAction(tr("About stereo_gui"), this);
  m_about_action->setStatusTip(tr("Show the stereo_gui about box."));
  connect(m_about_action, SIGNAL(triggered()), this, SLOT(about()));

  // File menu
  m_file_menu = menu->addMenu(tr("&File"));
  m_file_menu->addAction(m_exit_action);

  // Run menu
  m_file_menu = menu->addMenu(tr("&Run"));
  m_file_menu->addAction(m_run_stereo_action);

  // View menu
  menu->addSeparator();
  m_view_menu = menu->addMenu(tr("&View"));
  m_view_menu->addAction(m_size_to_fit_action);

  // Help menu
  menu->addSeparator();
  m_help_menu = menu->addMenu(tr("&Help"));
  m_help_menu->addAction(m_about_action);
}

void MainWindow::resizeEvent(QResizeEvent *){
  if (m_chooseFiles)
    m_chooseFiles->setMaximumSize(int(m_widRatio*size().width()), size().height());
}

void MainWindow::closeEvent(QCloseEvent *){
  forceQuit();
}

void MainWindow::forceQuit(){
  exit(0); // A fix for an older buggy version of Qt
}

void MainWindow::size_to_fit(){
  if (m_main_widget)
    m_main_widget->size_to_fit();
  if (m_left_widget)
    m_left_widget->size_to_fit();
  if (m_right_widget)
    m_right_widget->size_to_fit();
}

void MainWindow::run_stereo(){

  if (m_left_widget && m_right_widget) {
    QRect left_win = m_left_widget->get_crop_win();
    QRect right_win = m_right_widget->get_crop_win();

    int left_x = left_win.x();
    int left_y = left_win.y();
    int left_wx = left_win.width();
    int left_wy = left_win.height();

    int right_x = right_win.x();
    int right_y = right_win.y();
    int right_wx = right_win.width();
    int right_wy = right_win.height();

    // Run stereo
    std::string run_cmd = "stereo ";
    for (int i = 1; i < m_argc; i++) {
      run_cmd += std::string(m_argv[i]) + " ";
    }
    std::ostringstream os;
    os << "--left-image-crop-win " << left_x << " " << left_y << " "
       << left_wx << " " << left_wy << " ";
    os << "--right-image-crop-win " << right_x << " " << right_y << " "
       << right_wx << " " << right_wy << " ";
    run_cmd += os.str();
    std::cout << "Running: " << run_cmd << std::endl;
    system(run_cmd.c_str());
    QMessageBox::about(this, tr("Error"), tr("Done running stereo"));

  } else {
    QMessageBox::about(this, tr("Error"), tr("Not ready to run stereo"));
  }
}

void MainWindow::about() {
  std::ostringstream about_text;
  about_text << "
stereo_gui
"
             << "
Copyright © 2015 NASA Ames Research Center. See the manual for documentation.
";
  QMessageBox::about(this, tr("About stereo_gui"),
                     tr(about_text.str().c_str()));

}

void MainWindow::keyPressEvent(QKeyEvent *event) {

  std::ostringstream s;

  switch (event->key()) {
  case Qt::Key_Escape:  // Quit
    close();
    break;
  }
}
<commit_msg>stereo_gui: Minor robusness tweaks<commit_after>// __BEGIN_LICENSE__
//  Copyright (c) 2006-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NASA Vision Workbench is licensed under the Apache License,
//  Version 2.0 (the "License"); you may not use this file except in
//  compliance with the License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__

/// \file stereo_gui_MainWindow.cc
///
/// The Vision Workbench image viewer main window class.
///
#include <QtGui>
#include <asp/GUI/MainWindow.h>
#include <asp/GUI/MainWidget.h>
#include <asp/GUI/Utils.h>
using namespace vw::gui;

#include <vw/config.h>
#include <vw/Image/MaskViews.h>
#include <vw/FileIO/DiskImageView.h>
#include <vw/FileIO/DiskImageResource.h>
#include <vw/Image/Statistics.h>
#include <vw/Image/PixelMask.h>
#include <boost/filesystem/path.hpp>

#include <sstream>
namespace po = boost::program_options;

MainWindow::MainWindow(std::vector<std::string> const& images,
                       std::string const& geom,
                       bool ignore_georef, bool hillshade,
                       int argc,  char ** argv) :
  m_images(images), m_widRatio(0.3), m_main_widget(NULL),
  m_left_widget(NULL), m_right_widget(NULL),
  m_chooseFiles(NULL), m_argc(argc), m_argv(argv) {

  int windowWidX, windowWidY;
  extractWindowDims(geom, windowWidX, windowWidY);
  resize(windowWidX, windowWidY);

  // Set the window title and add tabs
  std::string window_title = "Stereo GUI";
  this->setWindowTitle(window_title.c_str());

  // Set up the basic layout of the window and its menus.
  create_menus();

  if (images.size() > 1){

    // Split the window into two, with the sidebar on the left

    QWidget * centralFrame;
    centralFrame = new QWidget(this);
    setCentralWidget(centralFrame);

    QSplitter *splitter = new QSplitter(centralFrame);
#if 0
    m_chooseFiles = new chooseFilesDlg(this);
    m_chooseFiles->setMaximumSize(int(m_widRatio*size().width()), size().height());
    m_main_widget = new MainWidget(centralFrame, images, m_chooseFiles,
                                   ignore_georef, hillshade);
    splitter->addWidget(m_chooseFiles);
    splitter->addWidget(m_main_widget);
#else
    // for doing stereo
    std::vector<std::string> left_images, right_images;
    // TODO: Verify that these are valid images.
    // TODO: Invoke here asp's handle_arguments().
    if (images.size() >= 1)
      left_images.push_back(images[0]);
    if (images.size() >= 2)
      right_images.push_back(images[1]);

    m_left_widget = new MainWidget(centralFrame, left_images, m_chooseFiles,
                                   ignore_georef, hillshade);
    splitter->addWidget(m_left_widget);

    if (images.size() >= 2) {
      m_right_widget = new MainWidget(centralFrame, right_images, m_chooseFiles,
                                      ignore_georef, hillshade);
      splitter->addWidget(m_right_widget);
    }

#endif
    QGridLayout *layout = new QGridLayout(centralFrame);
    layout->addWidget (splitter, 0, 0, 0);
    centralFrame->setLayout (layout);
  }else{
    // Set up MainWidget
    m_main_widget = new MainWidget(this, images, NULL, ignore_georef, hillshade);
    setCentralWidget(m_main_widget);
  }

}

//********************************************************************
//                      MAIN WINDOW SETUP
//********************************************************************

void MainWindow::create_menus() {

  QMenuBar* menu = menuBar();

  // Exit or Quit
  m_exit_action = new QAction(tr("Exit"), this);
  m_exit_action->setShortcut(tr("Q"));
  m_exit_action->setStatusTip(tr("Exit the application"));
  connect(m_exit_action, SIGNAL(triggered()), this, SLOT(forceQuit()));

  // Run stereo
  m_run_stereo_action = new QAction(tr("Run stereo"), this);
  m_run_stereo_action->setStatusTip(tr("Run stereo on selected clips."));
  connect(m_run_stereo_action, SIGNAL(triggered()), this, SLOT(run_stereo()));
  m_run_stereo_action->setShortcut(tr("R"));

  // Size to fit
  m_size_to_fit_action = new QAction(tr("Size to fit"), this);
  m_size_to_fit_action->setStatusTip(tr("Change the view to encompass the images."));
  connect(m_size_to_fit_action, SIGNAL(triggered()), this, SLOT(size_to_fit()));
  m_size_to_fit_action->setShortcut(tr("F"));

  // The About Box
  m_about_action = new QAction(tr("About stereo_gui"), this);
  m_about_action->setStatusTip(tr("Show the stereo_gui about box."));
  connect(m_about_action, SIGNAL(triggered()), this, SLOT(about()));

  // File menu
  m_file_menu = menu->addMenu(tr("&File"));
  m_file_menu->addAction(m_exit_action);

  // Run menu
  m_file_menu = menu->addMenu(tr("&Run"));
  m_file_menu->addAction(m_run_stereo_action);

  // View menu
  menu->addSeparator();
  m_view_menu = menu->addMenu(tr("&View"));
  m_view_menu->addAction(m_size_to_fit_action);

  // Help menu
  menu->addSeparator();
  m_help_menu = menu->addMenu(tr("&Help"));
  m_help_menu->addAction(m_about_action);
}

void MainWindow::resizeEvent(QResizeEvent *){
  if (m_chooseFiles)
    m_chooseFiles->setMaximumSize(int(m_widRatio*size().width()), size().height());
}

void MainWindow::closeEvent(QCloseEvent *){
  forceQuit();
}

void MainWindow::forceQuit(){
  exit(0); // A fix for an older buggy version of Qt
}

void MainWindow::size_to_fit(){
  if (m_main_widget)
    m_main_widget->size_to_fit();
  if (m_left_widget)
    m_left_widget->size_to_fit();
  if (m_right_widget)
    m_right_widget->size_to_fit();
}

void MainWindow::run_stereo(){

  if (m_left_widget && m_right_widget) {
    QRect left_win = m_left_widget->get_crop_win();
    QRect right_win = m_right_widget->get_crop_win();

    int left_x = left_win.x();
    int left_y = left_win.y();
    int left_wx = left_win.width();
    int left_wy = left_win.height();

    int right_x = right_win.x();
    int right_y = right_win.y();
    int right_wx = right_win.width();
    int right_wy = right_win.height();

    // Run stereo
    std::string run_cmd = "stereo ";
    for (int i = 1; i < m_argc; i++) {
      run_cmd += std::string(m_argv[i]) + " ";
    }
    std::ostringstream os;
    os << "--left-image-crop-win " << left_x << " " << left_y << " "
       << left_wx << " " << left_wy << " ";
    os << "--right-image-crop-win " << right_x << " " << right_y << " "
       << right_wx << " " << right_wy << " ";
    run_cmd += os.str();
    std::cout << "Running: " << run_cmd << std::endl;
    system(run_cmd.c_str());
    QMessageBox::about(this, tr("Error"), tr("Done running stereo"));

  } else {
    QMessageBox::about(this, tr("Error"), tr("Not ready to run stereo"));
  }
}

void MainWindow::about() {
  std::ostringstream about_text;
  about_text << "
stereo_gui
"
             << "
Copyright © 2015 NASA Ames Research Center. See the manual for documentation.
";
  QMessageBox::about(this, tr("About stereo_gui"),
                     tr(about_text.str().c_str()));

}

void MainWindow::keyPressEvent(QKeyEvent *event) {

  std::ostringstream s;

  switch (event->key()) {
  case Qt::Key_Escape:  // Quit
    close();
    break;
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Real Logic Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdint>
#include <cstdio>
#include <signal.h>
#include <util/CommandOptionParser.h>
#include <thread>
#include <Aeron.h>
#include <array>
#include <concurrent/BusySpinIdleStrategy.h>
#include "Configuration.h"
#include "RateReporter.h"

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

using namespace aeron::util;
using namespace aeron;

std::atomic<bool> running (true);

void sigIntHandler (int param)
{
    running = false;
}

static const char optHelp     = 'h';
static const char optPrefix   = 'p';
static const char optChannel  = 'c';
static const char optStreamId = 's';
static const char optMessages = 'm';
static const char optLinger   = 'l';
static const char optLength   = 'L';
static const char optRandLen  = 'r';

struct Settings
{
    std::string dirPrefix = "";
    std::string channel = samples::configuration::DEFAULT_CHANNEL;
    std::int32_t streamId = samples::configuration::DEFAULT_STREAM_ID;
    long numberOfMessages = samples::configuration::DEFAULT_NUMBER_OF_MESSAGES;
    int messageLength = samples::configuration::DEFAULT_MESSAGE_LENGTH;
    int lingerTimeoutMs = samples::configuration::DEFAULT_LINGER_TIMEOUT_MS;
    bool randomMessageLength = samples::configuration::DEFAULT_RANDOM_MESSAGE_LENGTH;
};

Settings parseCmdLine(CommandOptionParser& cp, int argc, char** argv)
{
    cp.parse(argc, argv);
    if (cp.getOption(optHelp).isPresent())
    {
        cp.displayOptionsHelp(std::cout);
        exit(0);
    }

    Settings s;

    s.dirPrefix = cp.getOption(optPrefix).getParam(0, s.dirPrefix);
    s.channel = cp.getOption(optChannel).getParam(0, s.channel);
    s.streamId = cp.getOption(optStreamId).getParamAsInt(0, 1, INT32_MAX, s.streamId);
    s.numberOfMessages = cp.getOption(optMessages).getParamAsLong(0, 0, INT64_MAX, s.numberOfMessages);
    s.messageLength = cp.getOption(optLength).getParamAsInt(0, sizeof(std::int64_t), INT32_MAX, s.messageLength);
    s.lingerTimeoutMs = cp.getOption(optLinger).getParamAsInt(0, 0, 60 * 60 * 1000, s.lingerTimeoutMs);
    s.randomMessageLength = cp.getOption(optRandLen).isPresent();
    return s;
}

std::atomic<bool> printingActive;

void printRate(double messagesPerSec, double bytesPerSec, long totalFragments, long totalBytes)
{
    if (printingActive)
    {
        std::printf(
            "%.02g msgs/sec, %.02g bytes/sec, totals %ld messages %ld MB\n",
            messagesPerSec, bytesPerSec, totalFragments, totalBytes / (1024 * 1024));
    }
}

typedef std::function<int()> on_new_length_t;

static std::random_device randomDevice;
static std::default_random_engine randomEngine(randomDevice());
static std::uniform_int_distribution<int> uniformLengthDistribution;

on_new_length_t composeLengthGenerator(bool random, int max)
{
    if (random)
    {
        std::uniform_int_distribution<int>::param_type param(sizeof(std::int64_t), max);
        uniformLengthDistribution.param(param);

        return [&]()
        {
            return uniformLengthDistribution(randomEngine);
        };
    }
    else
    {
        return [&]() { return max; };
    }
}

int main(int argc, char **argv)
{
    CommandOptionParser cp;
    cp.addOption(CommandOption (optHelp,     0, 0, "                Displays help information."));
    cp.addOption(CommandOption (optRandLen,  0, 0, "                Random Message Length."));
    cp.addOption(CommandOption (optPrefix,   1, 1, "dir             Prefix directory for aeron driver."));
    cp.addOption(CommandOption (optChannel,  1, 1, "channel         Channel."));
    cp.addOption(CommandOption (optStreamId, 1, 1, "streamId        Stream ID."));
    cp.addOption(CommandOption (optMessages, 1, 1, "number          Number of Messages."));
    cp.addOption(CommandOption (optLength,   1, 1, "length          Length of Messages."));
    cp.addOption(CommandOption (optLinger,   1, 1, "milliseconds    Linger timeout in milliseconds."));

    signal (SIGINT, sigIntHandler);

    try
    {
        Settings settings = parseCmdLine(cp, argc, argv);

        ::setlocale(LC_NUMERIC, "");

        std::printf(
            "Streaming %'ld messages of%s size %d bytes to %s on stream ID %d\n",
            settings.numberOfMessages,
            settings.randomMessageLength ? " random" : "",
            settings.messageLength,
            settings.channel.c_str(),
            settings.streamId);

        aeron::Context context;

        if (settings.dirPrefix != "")
        {
            context.aeronDir(settings.dirPrefix);
        }

        context.newPublicationHandler(
            [](const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t correlationId)
            {
                std::cout << "Publication: " << channel << " " << correlationId << ":" << streamId << ":" << sessionId << std::endl;
            });

        Aeron aeron(context);

        // add the publication to start the process
        std::int64_t id = aeron.addPublication(settings.channel, settings.streamId);

        std::shared_ptr<Publication> publication = aeron.findPublication(id);
        // wait for the publication to be valid
        while (!publication)
        {
            std::this_thread::yield();
            publication = aeron.findPublication(id);
        }

        std::unique_ptr<std::uint8_t[]> buffer(new std::uint8_t[settings.messageLength]);
        concurrent::AtomicBuffer srcBuffer(buffer.get(), settings.messageLength);
        BusySpinIdleStrategy offerIdleStrategy;
        on_new_length_t lengthGenerator = composeLengthGenerator(settings.randomMessageLength, settings.messageLength);
        RateReporter rateReporter(std::chrono::seconds(1), printRate);

        std::thread rateReporterThread([&](){ rateReporter.run(); });

        do
        {
            printingActive = true;

            for (long i = 0; i < settings.numberOfMessages && running; i++)
            {
                const int length = lengthGenerator();
                srcBuffer.putInt64(0, i);

                while (publication->offer(srcBuffer, 0, length) < 0L)
                {
                    offerIdleStrategy.idle(0);
                }

                rateReporter.onMessage(1, length);
            }

            std::cout << "Done streaming." << std::endl;

            if (running && settings.lingerTimeoutMs > 0)
            {
                std::cout << "Lingering for " << settings.lingerTimeoutMs << " milliseconds." << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(settings.lingerTimeoutMs));
            }

            printingActive = false;
        }
        while (running && continuationBarrier("Execute again?"));

        rateReporter.halt();
        rateReporterThread.join();
    }
    catch (CommandOptionException& e)
    {
        std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
        cp.displayOptionsHelp(std::cerr);
        return -1;
    }
    catch (SourcedException& e)
    {
        std::cerr << "FAILED: " << e.what() << " : " << e.where() << std::endl;
        return -1;
    }
    catch (std::exception& e)
    {
        std::cerr << "FAILED: " << e.what() << " : " << std::endl;
        return -1;
    }

    return 0;
}
<commit_msg>[C++]: add back pressure ratio to StreamingPublisher<commit_after>/*
 * Copyright 2015 Real Logic Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdint>
#include <cstdio>
#include <signal.h>
#include <util/CommandOptionParser.h>
#include <thread>
#include <Aeron.h>
#include <array>
#include <concurrent/BusySpinIdleStrategy.h>
#include "Configuration.h"
#include "RateReporter.h"

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

using namespace aeron::util;
using namespace aeron;

std::atomic<bool> running (true);

void sigIntHandler (int param)
{
    running = false;
}

static const char optHelp     = 'h';
static const char optPrefix   = 'p';
static const char optChannel  = 'c';
static const char optStreamId = 's';
static const char optMessages = 'm';
static const char optLinger   = 'l';
static const char optLength   = 'L';
static const char optRandLen  = 'r';

struct Settings
{
    std::string dirPrefix = "";
    std::string channel = samples::configuration::DEFAULT_CHANNEL;
    std::int32_t streamId = samples::configuration::DEFAULT_STREAM_ID;
    long numberOfMessages = samples::configuration::DEFAULT_NUMBER_OF_MESSAGES;
    int messageLength = samples::configuration::DEFAULT_MESSAGE_LENGTH;
    int lingerTimeoutMs = samples::configuration::DEFAULT_LINGER_TIMEOUT_MS;
    bool randomMessageLength = samples::configuration::DEFAULT_RANDOM_MESSAGE_LENGTH;
};

Settings parseCmdLine(CommandOptionParser& cp, int argc, char** argv)
{
    cp.parse(argc, argv);
    if (cp.getOption(optHelp).isPresent())
    {
        cp.displayOptionsHelp(std::cout);
        exit(0);
    }

    Settings s;

    s.dirPrefix = cp.getOption(optPrefix).getParam(0, s.dirPrefix);
    s.channel = cp.getOption(optChannel).getParam(0, s.channel);
    s.streamId = cp.getOption(optStreamId).getParamAsInt(0, 1, INT32_MAX, s.streamId);
    s.numberOfMessages = cp.getOption(optMessages).getParamAsLong(0, 0, INT64_MAX, s.numberOfMessages);
    s.messageLength = cp.getOption(optLength).getParamAsInt(0, sizeof(std::int64_t), INT32_MAX, s.messageLength);
    s.lingerTimeoutMs = cp.getOption(optLinger).getParamAsInt(0, 0, 60 * 60 * 1000, s.lingerTimeoutMs);
    s.randomMessageLength = cp.getOption(optRandLen).isPresent();
    return s;
}

std::atomic<bool> printingActive;

void printRate(double messagesPerSec, double bytesPerSec, long totalFragments, long totalBytes)
{
    if (printingActive)
    {
        std::printf(
            "%.02g msgs/sec, %.02g bytes/sec, totals %ld messages %ld MB\n",
            messagesPerSec, bytesPerSec, totalFragments, totalBytes / (1024 * 1024));
    }
}

typedef std::function<int()> on_new_length_t;

static std::random_device randomDevice;
static std::default_random_engine randomEngine(randomDevice());
static std::uniform_int_distribution<int> uniformLengthDistribution;

on_new_length_t composeLengthGenerator(bool random, int max)
{
    if (random)
    {
        std::uniform_int_distribution<int>::param_type param(sizeof(std::int64_t), max);
        uniformLengthDistribution.param(param);

        return [&]()
        {
            return uniformLengthDistribution(randomEngine);
        };
    }
    else
    {
        return [&]() { return max; };
    }
}

int main(int argc, char **argv)
{
    CommandOptionParser cp;
    cp.addOption(CommandOption (optHelp,     0, 0, "                Displays help information."));
    cp.addOption(CommandOption (optRandLen,  0, 0, "                Random Message Length."));
    cp.addOption(CommandOption (optPrefix,   1, 1, "dir             Prefix directory for aeron driver."));
    cp.addOption(CommandOption (optChannel,  1, 1, "channel         Channel."));
    cp.addOption(CommandOption (optStreamId, 1, 1, "streamId        Stream ID."));
    cp.addOption(CommandOption (optMessages, 1, 1, "number          Number of Messages."));
    cp.addOption(CommandOption (optLength,   1, 1, "length          Length of Messages."));
    cp.addOption(CommandOption (optLinger,   1, 1, "milliseconds    Linger timeout in milliseconds."));

    signal (SIGINT, sigIntHandler);

    try
    {
        Settings settings = parseCmdLine(cp, argc, argv);

        ::setlocale(LC_NUMERIC, "");

        std::printf(
            "Streaming %'ld messages of%s size %d bytes to %s on stream ID %d\n",
            settings.numberOfMessages,
            settings.randomMessageLength ? " random" : "",
            settings.messageLength,
            settings.channel.c_str(),
            settings.streamId);

        aeron::Context context;

        if (settings.dirPrefix != "")
        {
            context.aeronDir(settings.dirPrefix);
        }

        context.newPublicationHandler(
            [](const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t correlationId)
            {
                std::cout << "Publication: " << channel << " " << correlationId << ":" << streamId << ":" << sessionId << std::endl;
            });

        Aeron aeron(context);

        // add the publication to start the process
        std::int64_t id = aeron.addPublication(settings.channel, settings.streamId);

        std::shared_ptr<Publication> publication = aeron.findPublication(id);
        // wait for the publication to be valid
        while (!publication)
        {
            std::this_thread::yield();
            publication = aeron.findPublication(id);
        }

        std::unique_ptr<std::uint8_t[]> buffer(new std::uint8_t[settings.messageLength]);
        concurrent::AtomicBuffer srcBuffer(buffer.get(), settings.messageLength);
        BusySpinIdleStrategy offerIdleStrategy;
        on_new_length_t lengthGenerator = composeLengthGenerator(settings.randomMessageLength, settings.messageLength);
        RateReporter rateReporter(std::chrono::seconds(1), printRate);

        std::thread rateReporterThread([&](){ rateReporter.run(); });

        do
        {
            printingActive = true;

            long backPressureCount = 0;

            for (long i = 0; i < settings.numberOfMessages && running; i++)
            {
                const int length = lengthGenerator();
                srcBuffer.putInt64(0, i);

                while (publication->offer(srcBuffer, 0, length) < 0L)
                {
                    backPressureCount++;
                    offerIdleStrategy.idle(0);
                }

                rateReporter.onMessage(1, length);
            }

            std::cout << "Done streaming. Back pressure ratio ";
            std::cout << ((double)backPressureCount / (double)settings.numberOfMessages) << std::endl;

            if (running && settings.lingerTimeoutMs > 0)
            {
                std::cout << "Lingering for " << settings.lingerTimeoutMs << " milliseconds." << std::endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(settings.lingerTimeoutMs));
            }

            printingActive = false;
        }
        while (running && continuationBarrier("Execute again?"));

        rateReporter.halt();
        rateReporterThread.join();
    }
    catch (CommandOptionException& e)
    {
        std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
        cp.displayOptionsHelp(std::cerr);
        return -1;
    }
    catch (SourcedException& e)
    {
        std::cerr << "FAILED: " << e.what() << " : " << e.where() << std::endl;
        return -1;
    }
    catch (std::exception& e)
    {
        std::cerr << "FAILED: " << e.what() << " : " << std::endl;
        return -1;
    }

    return 0;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2010, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

// This include needs to be the very first to prevent problems with warnings
// regarding redefinition of _POSIX_C_SOURCE
#include "boost/python.hpp"

#include "IECore/Group.h"
#include "IECorePython/GroupBinding.h"
#include "IECorePython/RunTimeTypedBinding.h"

using namespace boost::python;
using namespace IECore;

namespace IECorePython
{

/// \todo: this should return a tuple rather than a list
static list children( Group &g )
{
	list result;
	for( Group::ChildContainer::const_iterator it=g.children().begin(); it!=g.children().end(); it++ )
	{
		result.append( *it );
	}
	return result;
}

/// \todo: this should return a tuple rather than a list
static list state( Group &g )
{
	list result;
	for( Group::StateContainer::const_iterator it=g.state().begin(); it!=g.state().end(); it++ )
	{
		result.append( *it );
	}
	return result;
}

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( transformMatrixOverloads, transformMatrix, 0, 1 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( globalTransformMatrixOverloads, globalTransformMatrix, 0, 1 );

void bindGroup()
{
	RunTimeTypedClass<Group>()
		.def( init<>() )
		.def( "children", &children, "Returns all the children in a list - note that modifying the list will not add or remove children." )
		.def( "addChild", &Group::addChild )
		.def( "removeChild", &Group::removeChild )
		.def( "clearChildren", &Group::clearChildren )
		.def( "state", &state, "Returns all the state in a list - note that modifying the list will not add or remove state." )
		.def( "addState", &Group::addState )
		.def( "removeState", &Group::removeState )
		.def( "clearState", &Group::clearState )
		.def( "getTransform", (TransformPtr (Group::*)())&Group::getTransform )
		.def( "setTransform", &Group::setTransform )
		.def( "transformMatrix", &Group::transformMatrix, transformMatrixOverloads() )
		.def( "globalTransformMatrix", &Group::globalTransformMatrix, globalTransformMatrixOverloads() )
		.def( "parent", (GroupPtr (Group::*)())&Group::parent )
	;
}

}
<commit_msg>Adding binding changes which should have been with previous commit.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2010, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

// This include needs to be the very first to prevent problems with warnings
// regarding redefinition of _POSIX_C_SOURCE
#include "boost/python.hpp"

#include "IECore/Group.h"
#include "IECore/Renderer.h"

#include "IECorePython/GroupBinding.h"
#include "IECorePython/RunTimeTypedBinding.h"
#include "IECorePython/ScopedGILRelease.h"

using namespace boost::python;
using namespace IECore;

namespace IECorePython
{

/// \todo: this should return a tuple rather than a list
static list children( Group &g )
{
	list result;
	for( Group::ChildContainer::const_iterator it=g.children().begin(); it!=g.children().end(); it++ )
	{
		result.append( *it );
	}
	return result;
}

/// \todo: this should return a tuple rather than a list
static list state( Group &g )
{
	list result;
	for( Group::StateContainer::const_iterator it=g.state().begin(); it!=g.state().end(); it++ )
	{
		result.append( *it );
	}
	return result;
}

static void render( const Group &group, Renderer *renderer )
{
	IECorePython::ScopedGILRelease gilRelease;
	group.render( renderer );
}

static void render2( const Group &group, Renderer *renderer, bool inAttributeBlock )
{
	IECorePython::ScopedGILRelease gilRelease;
	group.render( renderer, inAttributeBlock );
}

static void renderState( const Group &group, Renderer *renderer )
{
	IECorePython::ScopedGILRelease gilRelease;
	group.renderState( renderer );
}

static void renderChildren( const Group &group, Renderer *renderer )
{
	IECorePython::ScopedGILRelease gilRelease;
	group.renderChildren( renderer );
}

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( transformMatrixOverloads, transformMatrix, 0, 1 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( globalTransformMatrixOverloads, globalTransformMatrix, 0, 1 );

void bindGroup()
{
	RunTimeTypedClass<Group>()
		.def( init<>() )
		.def( "children", &children, "Returns all the children in a list - note that modifying the list will not add or remove children." )
		.def( "addChild", &Group::addChild )
		.def( "removeChild", &Group::removeChild )
		.def( "clearChildren", &Group::clearChildren )
		.def( "state", &state, "Returns all the state in a list - note that modifying the list will not add or remove state." )
		.def( "addState", &Group::addState )
		.def( "removeState", &Group::removeState )
		.def( "clearState", &Group::clearState )
		.def( "getTransform", (TransformPtr (Group::*)())&Group::getTransform )
		.def( "setTransform", &Group::setTransform )
		.def( "transformMatrix", &Group::transformMatrix, transformMatrixOverloads() )
		.def( "globalTransformMatrix", &Group::globalTransformMatrix, globalTransformMatrixOverloads() )
		.def( "parent", (GroupPtr (Group::*)())&Group::parent )
		.def( "render", &render )
		.def( "render", &render2 )
		.def( "renderState", &renderState )
		.def( "renderChildren", &renderChildren )
	;
}

}
<|endoftext|>