<commit_before>#include <stdio.h>
#include <stdarg.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <memory>
#include <algorithm>
#include <vector>

#include "platform_tizen.h"
#include "platform_gl.h"
#include "urlWorker.h"

#include "log.h"

#include <libgen.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/syscall.h>

#include <fontconfig.h>
#include <dlog.h>

#define NUM_WORKERS 4

static bool s_isContinuousRendering = false;
static std::function<void()> s_renderCallbackFunction = nullptr;

static std::vector<std::string> s_fallbackFonts;
static FcConfig* s_fcConfig = nullptr;

static UrlWorker s_workers;

bool startUrlRequest(const std::string& _url, UrlCallback _callback) {
    s_workers.enqueue(std::make_unique<UrlTask>(_url, _callback));
    return true;
}

void cancelUrlRequest(const std::string& _url) {
    s_workers.cancel(_url);
}

void initUrlRequests(const char* proxyAddress) {
    s_workers.start(4, proxyAddress);
}

void stopUrlRequests() {
    s_workers.stop();
}

static bool s_update = false;
#ifdef  LOG_TAG
#undef  LOG_TAG
#endif
#define LOG_TAG "Tangram"

void logMsg(const char* fmt, ...) {

    va_list vl;
    va_start(vl, fmt);
    dlog_vprint(DLOG_WARN, LOG_TAG, fmt, vl);
    va_end(vl);
}

void setRenderCallbackFunction(std::function<void()> callback) {
    s_renderCallbackFunction = callback;
}

void setEvasGlAPI(Evas_GL_API *glApi) {
    __evas_gl_glapi = glApi;
}

void requestRender() {
    s_update = true;
    if (s_renderCallbackFunction) {
        s_renderCallbackFunction();
    }
}

bool shouldRender() {
    bool update = s_update;
    s_update = false;
    return update;
}

void setContinuousRendering(bool _isContinuous) {

    s_isContinuousRendering = _isContinuous;

}

bool isContinuousRendering() {

    return s_isContinuousRendering;

}

void initPlatformFontSetup() {

    static bool s_platformFontsInit = false;
    if (s_platformFontsInit) { return; }

    s_fcConfig = FcInitLoadConfigAndFonts();

    std::string style = "Regular";

    FcStrSet* fcLangs = FcGetLangs();
    FcStrList* fcLangList = FcStrListCreate(fcLangs);
    FcChar8* fcLang;
    while ((fcLang = FcStrListNext(fcLangList))) {
        FcValue fcStyleValue, fcLangValue;

        fcStyleValue.type = fcLangValue.type = FcType::FcTypeString;
        fcStyleValue.u.s = reinterpret_cast<const FcChar8*>(style.c_str());
        fcLangValue.u.s = fcLang;

        // create a pattern with style and family font properties
        FcPattern* pat = FcPatternCreate();

        FcPatternAdd(pat, FC_STYLE, fcStyleValue, true);
        FcPatternAdd(pat, FC_LANG, fcLangValue, true);
        //FcPatternPrint(pat);

        FcConfigSubstitute(s_fcConfig, pat, FcMatchPattern);
        FcDefaultSubstitute(pat);

        FcResult res;
        FcPattern* font = FcFontMatch(s_fcConfig, pat, &res);
        if (font) {
            FcChar8* file = nullptr;
            if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
                // Make sure this font file is not previously added.
                if (std::find(s_fallbackFonts.begin(), s_fallbackFonts.end(),
                              reinterpret_cast<char*>(file)) == s_fallbackFonts.end()) {
                    s_fallbackFonts.emplace_back(reinterpret_cast<char*>(file));
                }
            }
            FcPatternDestroy(font);
        }
        FcPatternDestroy(pat);
    }
    FcStrListDone(fcLangList);
    s_platformFontsInit = true;
}

std::vector<FontSourceHandle> systemFontFallbacksHandle() {

    initPlatformFontSetup();

    std::vector<FontSourceHandle> handles;

    for (auto& path : s_fallbackFonts) {
        FontSourceHandle fontSourceHandle = [&](size_t* _size) -> unsigned char* {
            LOG("Loading font %s", path.c_str());

            auto cdata = bytesFromFile(path.c_str(), *_size);

            return cdata;
        };

        handles.push_back(fontSourceHandle);
    }

    return handles;
}

std::string fontPath(const std::string& _name, const std::string& _weight,
                           const std::string& _face) {

    initPlatformFontSetup();

    if (!s_fcConfig) {
        return "";
    }

    std::string fontFile = "";
    FcValue fcFamily, fcFace, fcWeight;

    fcFamily.type = fcFace.type = fcWeight.type = FcType::FcTypeString;
    fcFamily.u.s = reinterpret_cast<const FcChar8*>(_name.c_str());
    fcWeight.u.s = reinterpret_cast<const FcChar8*>(_weight.c_str());
    fcFace.u.s = reinterpret_cast<const FcChar8*>(_face.c_str());

    // Create a pattern with family, style and weight font properties
    FcPattern* pattern = FcPatternCreate();

    FcPatternAdd(pattern, FC_FAMILY, fcFamily, true);
    FcPatternAdd(pattern, FC_STYLE, fcFace, true);
    FcPatternAdd(pattern, FC_WEIGHT, fcWeight, true);
    //FcPatternPrint(pattern);

    FcConfigSubstitute(s_fcConfig, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult res;
    FcPattern* font = FcFontMatch(s_fcConfig, pattern, &res);
    if (font) {
        FcChar8* file = nullptr;
        FcChar8* fontFamily = nullptr;
        if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch &&
            FcPatternGetString(font, FC_FAMILY, 0, &fontFamily) == FcResultMatch) {
            // We do not want the "best" match, but an "exact" or at least the same "family" match
            // We have fallbacks to cover rest here.
            if (strcmp(reinterpret_cast<const char*>(fontFamily), _name.c_str()) == 0) {
                fontFile = reinterpret_cast<const char*>(file);
            }
        }
        FcPatternDestroy(font);
    }

    FcPatternDestroy(pattern);

    return fontFile;
}

unsigned char* systemFont(const std::string& _name, const std::string& _weight, const std::string& _face, size_t* _size) {
    std::string path = fontPath(_name, _weight, _face);

    if (path.empty()) { return nullptr; }

    return bytesFromFile(path.c_str(), *_size);
}

unsigned char* bytesFromFile(const char* _path, size_t& _size) {

    if (!_path || strlen(_path) == 0) { return nullptr; }

    std::ifstream resource(_path, std::ifstream::ate | std::ifstream::binary);

    if(!resource.is_open()) {
        logMsg("Failed to read file at path: %s\n", _path);
        _size = 0;
        return nullptr;
    }

    _size = resource.tellg();

    resource.seekg(std::ifstream::beg);

    char* cdata = (char*) malloc(sizeof(char) * (_size));

    resource.read(cdata, _size);
    resource.close();

    return reinterpret_cast<unsigned char *>(cdata);
}

std::string stringFromFile(const char* _path) {

    std::string out;
    if (!_path || strlen(_path) == 0) { return out; }

    std::ifstream resource(_path, std::ifstream::ate | std::ifstream::binary);

    if(!resource.is_open()) {
        logMsg("Failed to read file at path: %s\n", _path);
        return out;
    }

    resource.seekg(0, std::ios::end);
    out.resize(resource.tellg());
    resource.seekg(0, std::ios::beg);
    resource.read(&out[0], out.size());
    resource.close();

    return out;
}

void setCurrentThreadPriority(int priority){
    int tid = syscall(SYS_gettid);
    //int  p1 = getpriority(PRIO_PROCESS, tid);

    setpriority(PRIO_PROCESS, tid, priority);

    //int  p2 = getpriority(PRIO_PROCESS, tid);
    //logMsg("set niceness: %d -> %d\n", p1, p2);
}

void initGLExtensions() {
     // glBindVertexArrayOESEXT = (PFNGLBINDVERTEXARRAYPROC)glfwGetProcAddress("glBindVertexArray");
     // glDeleteVertexArraysOESEXT = (PFNGLDELETEVERTEXARRAYSPROC)glfwGetProcAddress("glDeleteVertexArrays");
     // glGenVertexArraysOESEXT = (PFNGLGENVERTEXARRAYSPROC)glfwGetProcAddress("glGenVertexArrays");
}
<commit_msg>Fix tizen fontfallback loading<commit_after>#include <stdio.h>
#include <stdarg.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <memory>
#include <algorithm>
#include <vector>

#include "platform_tizen.h"
#include "platform_gl.h"
#include "urlWorker.h"

#include "log.h"

#include <libgen.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/syscall.h>

#include <fontconfig.h>
#include <dlog.h>

#define NUM_WORKERS 4

static bool s_isContinuousRendering = false;
static std::function<void()> s_renderCallbackFunction = nullptr;

static std::vector<std::string> s_fallbackFonts;
static FcConfig* s_fcConfig = nullptr;

static UrlWorker s_workers;

bool startUrlRequest(const std::string& _url, UrlCallback _callback) {
    s_workers.enqueue(std::make_unique<UrlTask>(_url, _callback));
    return true;
}

void cancelUrlRequest(const std::string& _url) {
    s_workers.cancel(_url);
}

void initUrlRequests(const char* proxyAddress) {
    s_workers.start(4, proxyAddress);
}

void stopUrlRequests() {
    s_workers.stop();
}

static bool s_update = false;
#ifdef  LOG_TAG
#undef  LOG_TAG
#endif
#define LOG_TAG "Tangram"

void logMsg(const char* fmt, ...) {

    va_list vl;
    va_start(vl, fmt);
    dlog_vprint(DLOG_WARN, LOG_TAG, fmt, vl);
    va_end(vl);
}

void setRenderCallbackFunction(std::function<void()> callback) {
    s_renderCallbackFunction = callback;
}

void setEvasGlAPI(Evas_GL_API *glApi) {
    __evas_gl_glapi = glApi;
}

void requestRender() {
    s_update = true;
    if (s_renderCallbackFunction) {
        s_renderCallbackFunction();
    }
}

bool shouldRender() {
    bool update = s_update;
    s_update = false;
    return update;
}

void setContinuousRendering(bool _isContinuous) {

    s_isContinuousRendering = _isContinuous;

}

bool isContinuousRendering() {

    return s_isContinuousRendering;

}

void initPlatformFontSetup() {

    static bool s_platformFontsInit = false;
    if (s_platformFontsInit) { return; }

    s_fcConfig = FcInitLoadConfigAndFonts();

    std::string style = "Regular";

    FcStrSet* fcLangs = FcGetLangs();
    FcStrList* fcLangList = FcStrListCreate(fcLangs);
    FcChar8* fcLang;
    while ((fcLang = FcStrListNext(fcLangList))) {
        FcValue fcStyleValue, fcLangValue;

        fcStyleValue.type = fcLangValue.type = FcType::FcTypeString;
        fcStyleValue.u.s = reinterpret_cast<const FcChar8*>(style.c_str());
        fcLangValue.u.s = fcLang;

        // create a pattern with style and family font properties
        FcPattern* pat = FcPatternCreate();

        FcPatternAdd(pat, FC_STYLE, fcStyleValue, true);
        FcPatternAdd(pat, FC_LANG, fcLangValue, true);
        //FcPatternPrint(pat);

        FcConfigSubstitute(s_fcConfig, pat, FcMatchPattern);
        FcDefaultSubstitute(pat);

        FcResult res;
        FcPattern* font = FcFontMatch(s_fcConfig, pat, &res);
        if (font) {
            FcChar8* file = nullptr;
            if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch) {
                // Make sure this font file is not previously added.
                if (std::find(s_fallbackFonts.begin(), s_fallbackFonts.end(),
                              reinterpret_cast<char*>(file)) == s_fallbackFonts.end()) {
                    s_fallbackFonts.emplace_back(reinterpret_cast<char*>(file));
                }
            }
            FcPatternDestroy(font);
        }
        FcPatternDestroy(pat);
    }
    FcStrListDone(fcLangList);
    s_platformFontsInit = true;
}

std::vector<FontSourceHandle> systemFontFallbacksHandle() {

    initPlatformFontSetup();

    std::vector<FontSourceHandle> handles;

    for (auto& path : s_fallbackFonts) {
        handles.emplace_back(path);
    }

    return handles;
}

std::string fontPath(const std::string& _name, const std::string& _weight,
                           const std::string& _face) {

    initPlatformFontSetup();

    if (!s_fcConfig) {
        return "";
    }

    std::string fontFile = "";
    FcValue fcFamily, fcFace, fcWeight;

    fcFamily.type = fcFace.type = fcWeight.type = FcType::FcTypeString;
    fcFamily.u.s = reinterpret_cast<const FcChar8*>(_name.c_str());
    fcWeight.u.s = reinterpret_cast<const FcChar8*>(_weight.c_str());
    fcFace.u.s = reinterpret_cast<const FcChar8*>(_face.c_str());

    // Create a pattern with family, style and weight font properties
    FcPattern* pattern = FcPatternCreate();

    FcPatternAdd(pattern, FC_FAMILY, fcFamily, true);
    FcPatternAdd(pattern, FC_STYLE, fcFace, true);
    FcPatternAdd(pattern, FC_WEIGHT, fcWeight, true);
    //FcPatternPrint(pattern);

    FcConfigSubstitute(s_fcConfig, pattern, FcMatchPattern);
    FcDefaultSubstitute(pattern);

    FcResult res;
    FcPattern* font = FcFontMatch(s_fcConfig, pattern, &res);
    if (font) {
        FcChar8* file = nullptr;
        FcChar8* fontFamily = nullptr;
        if (FcPatternGetString(font, FC_FILE, 0, &file) == FcResultMatch &&
            FcPatternGetString(font, FC_FAMILY, 0, &fontFamily) == FcResultMatch) {
            // We do not want the "best" match, but an "exact" or at least the same "family" match
            // We have fallbacks to cover rest here.
            if (strcmp(reinterpret_cast<const char*>(fontFamily), _name.c_str()) == 0) {
                fontFile = reinterpret_cast<const char*>(file);
            }
        }
        FcPatternDestroy(font);
    }

    FcPatternDestroy(pattern);

    return fontFile;
}

unsigned char* systemFont(const std::string& _name, const std::string& _weight, const std::string& _face, size_t* _size) {
    std::string path = fontPath(_name, _weight, _face);

    if (path.empty()) { return nullptr; }

    return bytesFromFile(path.c_str(), *_size);
}

unsigned char* bytesFromFile(const char* _path, size_t& _size) {

    if (!_path || strlen(_path) == 0) { return nullptr; }

    std::ifstream resource(_path, std::ifstream::ate | std::ifstream::binary);

    if(!resource.is_open()) {
        logMsg("Failed to read file at path: %s\n", _path);
        _size = 0;
        return nullptr;
    }

    _size = resource.tellg();

    resource.seekg(std::ifstream::beg);

    char* cdata = (char*) malloc(sizeof(char) * (_size));

    resource.read(cdata, _size);
    resource.close();

    return reinterpret_cast<unsigned char *>(cdata);
}

std::string stringFromFile(const char* _path) {

    std::string out;
    if (!_path || strlen(_path) == 0) { return out; }

    std::ifstream resource(_path, std::ifstream::ate | std::ifstream::binary);

    if(!resource.is_open()) {
        logMsg("Failed to read file at path: %s\n", _path);
        return out;
    }

    resource.seekg(0, std::ios::end);
    out.resize(resource.tellg());
    resource.seekg(0, std::ios::beg);
    resource.read(&out[0], out.size());
    resource.close();

    return out;
}

void setCurrentThreadPriority(int priority){
    int tid = syscall(SYS_gettid);
    //int  p1 = getpriority(PRIO_PROCESS, tid);

    setpriority(PRIO_PROCESS, tid, priority);

    //int  p2 = getpriority(PRIO_PROCESS, tid);
    //logMsg("set niceness: %d -> %d\n", p1, p2);
}

void initGLExtensions() {
     // glBindVertexArrayOESEXT = (PFNGLBINDVERTEXARRAYPROC)glfwGetProcAddress("glBindVertexArray");
     // glDeleteVertexArraysOESEXT = (PFNGLDELETEVERTEXARRAYSPROC)glfwGetProcAddress("glDeleteVertexArrays");
     // glGenVertexArraysOESEXT = (PFNGLGENVERTEXARRAYSPROC)glfwGetProcAddress("glGenVertexArrays");
}
<|endoftext|>


<commit_before>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer   28/07/2008

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

//_________________________________________________
/*
BEGIN_HTML

ProfileLikelihoodCalculator is a concrete implementation of CombinedCalculator
(the interface class for a tools which can produce both RooStats HypoTestResults and ConfIntervals).
The tool uses the profile likelihood ratio as a test statistic, and assumes that Wilks' theorem is valid.
Wilks' theorem states that -2* log (profile likelihood ratio) is asymptotically distributed as a chi^2 distribution
with N-dof, where N is the number of degrees of freedom.  Thus, p-values can be constructed and the profile likelihood ratio
can be used to construct a LikelihoodInterval.
(In the future, this class could be extended to use toy Monte Carlo to calibrate the distribution of the test statistic).

 Usage: It uses the interface of the CombinedCalculator, so that it can be configured by specifying:

a model common model (eg. a family of specific models which includes both the null and alternate),

a data set,

a set of parameters of interest. The nuisance parameters will be all other parameters of the model

a set of parameters of which specify the null hypothesis (including values and const/non-const status)

The interface allows one to pass the model, data, and parameters either directly or via a ModelConfig class.
The alternate hypothesis leaves the parameter free to take any value other than those specified by the null hypotesis. There is therefore no need to
specify the alternate parameters.

After configuring the calculator, one only needs to ask GetHypoTest() (which will return a HypoTestResult pointer) or GetInterval() (which will return an ConfInterval pointer).

The concrete implementations of this interface should deal with the details of how the nuisance parameters are
dealt with (eg. integration vs. profiling) and which test-statistic is used (perhaps this should be added to the interface).

The motivation for this interface is that we hope to be able to specify the problem in a common way for several concrete calculators.

END_HTML
*/
//

#ifndef RooStats_ProfileLikelihoodCalculator
#include "RooStats/ProfileLikelihoodCalculator.h"
#endif

#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif

#include "RooStats/LikelihoodInterval.h"
#include "RooStats/HypoTestResult.h"

#include "RooFitResult.h"
#include "RooRealVar.h"
#include "RooProfileLL.h"
#include "RooNLLVar.h"
#include "RooGlobalFunc.h"
#include "RooMsgService.h"

#include "Math/MinimizerOptions.h"
//#include "RooProdPdf.h"

using namespace std;

ClassImp(RooStats::ProfileLikelihoodCalculator) ;

using namespace RooFit;
using namespace RooStats;

//_______________________________________________________
ProfileLikelihoodCalculator::ProfileLikelihoodCalculator() :
   CombinedCalculator(), fFitResult(0)
{
   // default constructor
}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooAbsData& data, RooAbsPdf& pdf, const RooArgSet& paramsOfInterest,
                                                         Double_t size, const RooArgSet* nullParams ) :
   CombinedCalculator(data,pdf, paramsOfInterest, size, nullParams ),
   fFitResult(0)
{
   // constructor from pdf and parameters
   // the pdf must contain eventually the nuisance parameters
}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooAbsData& data,  ModelConfig& model, Double_t size) :
   CombinedCalculator(data, model, size),
   fFitResult(0)
{
   // construct from a ModelConfig. Assume data model.GetPdf() will provide full description of model including
   // constraint term on the nuisances parameters
   assert(model.GetPdf() );
}

//_______________________________________________________
ProfileLikelihoodCalculator::~ProfileLikelihoodCalculator(){
   // destructor
   // cannot delete prod pdf because it will delete all the composing pdf's
//    if (fOwnPdf) delete fPdf;
//    fPdf = 0;
   if (fFitResult) delete fFitResult;
}

void ProfileLikelihoodCalculator::DoReset() const {
   // reset and clear fit result
   // to be called when a new model or data are set in the calculator
   if (fFitResult) delete fFitResult;
   fFitResult = 0;
}

void  ProfileLikelihoodCalculator::DoGlobalFit() const {
   // perform a global fit of the likelihood letting with all parameter of interest and
   // nuisance parameters
   // keep the list of fitted parameters

   DoReset();
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();
   if (!data || !pdf ) return;

   // get all non-const parameters
   RooArgSet* constrainedParams = pdf->getParameters(*data);
   if (!constrainedParams) return ;
   RemoveConstantParameters(constrainedParams);

   // calculate MLE
   const char * minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
   const char * minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str();
   int strategy = ROOT::Math::MinimizerOptions::DefaultStrategy();
   int level = ROOT::Math::MinimizerOptions::DefaultPrintLevel() -1;// RooFit level starts from  -1
   oocoutP((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::DoGlobalFit - using " << minimType << " / " << minimAlgo << " with strategy " << strategy << std::endl;
   // do global fit and store fit result for further use
   fFitResult = pdf->fitTo(*data, Constrain(*constrainedParams),ConditionalObservables(fConditionalObs),
                           Strategy(strategy),PrintLevel(level),
                           Hesse(kFALSE),Save(kTRUE),Minimizer(minimType,minimAlgo));

   // print fit result
   if (fFitResult)
      fFitResult->printStream( oocoutI((TObject*)0,Minimization), fFitResult->defaultPrintContents(0), fFitResult->defaultPrintStyle(0) );

   if (fFitResult->status() != 0)
      oocoutW((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::DoGlobalFit -  Global fit failed - status = " << fFitResult->status() << std::endl;

   delete constrainedParams;

}

//_______________________________________________________
LikelihoodInterval* ProfileLikelihoodCalculator::GetInterval() const {
   // Main interface to get a RooStats::ConfInterval.
   // It constructs a profile likelihood ratio and uses that to construct a RooStats::LikelihoodInterval.

//    RooAbsPdf* pdf   = fWS->pdf(fPdfName);
//    RooAbsData* data = fWS->data(fDataName);
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();
   if (!data || !pdf || fPOI.getSize() == 0) return 0;

   RooArgSet* constrainedParams = pdf->getParameters(*data);
   RemoveConstantParameters(constrainedParams);

   /*
   RooNLLVar* nll = new RooNLLVar("nll","",*pdf,*data, Extended(),Constrain(*constrainedParams));
   RooProfileLL* profile = new RooProfileLL("pll","",*nll, *fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak
   */

   RooAbsReal *  nll = pdf->createNLL(*data, CloneData(kTRUE), Constrain(*constrainedParams),ConditionalObservables(fConditionalObs));

   RooAbsReal* profile = nll->createProfile(fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak

   //RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
   // perform a Best Fit
   if (!fFitResult) DoGlobalFit();
   // if fit fails return
   if (!fFitResult)   return 0;

   // t.b.f. " RooProfileLL should keep and provide possibility to query on global minimum
   // set POI to fit value (this will speed up profileLL calculation of global minimum)
   const RooArgList & fitParams = fFitResult->floatParsFinal();
   for (int i = 0; i < fitParams.getSize(); ++i) {
      RooRealVar & fitPar =  (RooRealVar &) fitParams[i];
      RooRealVar * par = (RooRealVar*) fPOI.find( fitPar.GetName() );
      if (par) {
         par->setVal( fitPar.getVal() );
         par->setError( fitPar.getError() );
      }
   }

   // do this so profile will cache inside the absolute minimum and
   // minimum values of nuisance parameters
   // (no need to this here)
   // profile->getVal();
   //RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
   //  profile->Print();

   TString name = TString("LikelihoodInterval_");// + TString(GetName() );

   // make a list of fPOI with fit result values and pass to LikelihoodInterval class
   // bestPOI is a cloned list of POI only with their best fit values
   TIter iter = fPOI.createIterator();
   RooArgSet fitParSet(fitParams);
   RooArgSet * bestPOI = new RooArgSet();
   while (RooAbsArg * arg =  (RooAbsArg*) iter.Next() ) {
      RooAbsArg * p  =  fitParSet.find( arg->GetName() );
      if (p) bestPOI->addClone(*p);
      else bestPOI->addClone(*arg);
   }
   // fPOI contains the paramter of interest of the PL object
   // and bestPOI contains a snapshot with the best fit values
   LikelihoodInterval* interval = new LikelihoodInterval(name, profile, &fPOI, bestPOI);
   interval->SetConfidenceLevel(1.-fSize);
   delete constrainedParams;
   return interval;
}

//_______________________________________________________
HypoTestResult* ProfileLikelihoodCalculator::GetHypoTest() const {
   // Main interface to get a HypoTestResult.
   // It does two fits:
   // the first lets the null parameters float, so it's a maximum likelihood estimate
   // the second is to the null (fixing null parameters to their specified values): eg. a conditional maximum likelihood
   // the ratio of the likelihood at the conditional MLE to the MLE is the profile likelihood ratio.
   // Wilks' theorem is used to get p-values

//    RooAbsPdf* pdf   = fWS->pdf(fPdfName);
//    RooAbsData* data = fWS->data(fDataName);
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();

   if (!data || !pdf) return 0;

   if (fNullParams.getSize() == 0) return 0;

   // make a clone and ordered list since a vector will be associated to keep parameter values
   // clone the list since first fit will changes the fNullParams values
   RooArgList poiList;
   poiList.addClone(fNullParams); // make a clone list

   // do a global fit
   if (!fFitResult) DoGlobalFit();
   if (!fFitResult) return 0;

   RooArgSet* constrainedParams = pdf->getParameters(*data);
   RemoveConstantParameters(constrainedParams);

   // perform a global fit if it is not done before
   if (!fFitResult) DoGlobalFit();
   Double_t NLLatMLE= fFitResult->minNll();

   // set POI to given values, set constant, calculate conditional MLE
   std::vector<double> oldValues(poiList.getSize() );
   for (unsigned int i = 0; i < oldValues.size(); ++i) {
      RooRealVar * mytarget = (RooRealVar*) constrainedParams->find(poiList[i].GetName());
      if (mytarget) {
         oldValues[i] = mytarget->getVal();
         mytarget->setVal( ( (RooRealVar&) poiList[i] ).getVal() );
         mytarget->setConstant(kTRUE);
      }
   }

   // perform the fit only if nuisance parameters are available
   // get nuisance parameters
   // nuisance parameters are the non const parameters from the likelihood parameters
   RooArgSet nuisParams(*constrainedParams);

   // need to remove the parameter of interest
   RemoveConstantParameters(&nuisParams);

   // check there are variable parameter in order to do a fit
   bool existVarParams = false;
   TIter it = nuisParams.createIterator();
   RooRealVar * myarg = 0;
   while ((myarg = (RooRealVar *)it.Next())) {
      if ( !myarg->isConstant() ) {
         existVarParams = true;
         break;
      }
   }

   Double_t NLLatCondMLE = NLLatMLE;
   if (existVarParams) {

      const char * minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
      const char * minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
      int level = ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1; // RooFit levels starts from -1
      oocoutP((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::GetHypoTest - do conditional fit " << std::endl;
      RooFitResult* fit2 = pdf->fitTo(*data,Constrain(*constrainedParams),ConditionalObservables(fConditionalObs),
                                      Hesse(kFALSE),Strategy(0), Minos(kFALSE),
                                      Minimizer(minimType,minimAlgo), Save(kTRUE),PrintLevel(level));

      // print fit result
      if (fit2) {
         NLLatCondMLE = fit2->minNll();
         fit2->printStream( oocoutI((TObject*)0,Minimization), fit2->defaultPrintContents(0), fit2->defaultPrintStyle(0) );

         if (fit2->status() != 0)
            oocoutW((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::GetHypotest -  Conditional fit failed - status = " << fit2->status() << std::endl;
      }

   }
   else {
      // get just the likelihood value (no need to do a fit since the likelihood is a constant function)
      RooAbsReal* nll = pdf->createNLL(*data, CloneData(kTRUE), Constrain(*constrainedParams),ConditionalObservables(fConditionalObs));
      NLLatCondMLE = nll->getVal();
      delete nll;
   }

   // Use Wilks' theorem to translate -2 log lambda into a signifcance/p-value
   Double_t deltaNLL = std::max( NLLatCondMLE-NLLatMLE, 0.);

   // get number of free parameter of interest
   RemoveConstantParameters(poiList);
   int ndf = poiList.getSize();

   Double_t pvalue = ROOT::Math::chisquared_cdf_c( 2* deltaNLL, ndf);

   TString name = TString("ProfileLRHypoTestResult_");// + TString(GetName() );
   HypoTestResult* htr = new HypoTestResult(name, pvalue, 0 );

   // restore previous value of poi
   for (unsigned int i = 0; i < oldValues.size(); ++i) {
      RooRealVar * mytarget = (RooRealVar*) constrainedParams->find(poiList[i].GetName());
      if (mytarget) {
         mytarget->setVal(oldValues[i] );
         mytarget->setConstant(false);
      }
   }

   delete constrainedParams;
   return htr;

}

<commit_msg>Re-revert r46690<commit_after>// @(#)root/roostats:$Id$
// Author: Kyle Cranmer   28/07/2008

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

//_________________________________________________
/*
BEGIN_HTML

ProfileLikelihoodCalculator is a concrete implementation of CombinedCalculator
(the interface class for a tools which can produce both RooStats HypoTestResults and ConfIntervals).
The tool uses the profile likelihood ratio as a test statistic, and assumes that Wilks' theorem is valid.
Wilks' theorem states that -2* log (profile likelihood ratio) is asymptotically distributed as a chi^2 distribution
with N-dof, where N is the number of degrees of freedom.  Thus, p-values can be constructed and the profile likelihood ratio
can be used to construct a LikelihoodInterval.
(In the future, this class could be extended to use toy Monte Carlo to calibrate the distribution of the test statistic).

 Usage: It uses the interface of the CombinedCalculator, so that it can be configured by specifying:

a model common model (eg. a family of specific models which includes both the null and alternate),

a data set,

a set of parameters of interest. The nuisance parameters will be all other parameters of the model

a set of parameters of which specify the null hypothesis (including values and const/non-const status)

The interface allows one to pass the model, data, and parameters either directly or via a ModelConfig class.
The alternate hypothesis leaves the parameter free to take any value other than those specified by the null hypotesis. There is therefore no need to
specify the alternate parameters.

After configuring the calculator, one only needs to ask GetHypoTest() (which will return a HypoTestResult pointer) or GetInterval() (which will return an ConfInterval pointer).

The concrete implementations of this interface should deal with the details of how the nuisance parameters are
dealt with (eg. integration vs. profiling) and which test-statistic is used (perhaps this should be added to the interface).

The motivation for this interface is that we hope to be able to specify the problem in a common way for several concrete calculators.

END_HTML
*/
//

#ifndef RooStats_ProfileLikelihoodCalculator
#include "RooStats/ProfileLikelihoodCalculator.h"
#endif

#ifndef RooStats_RooStatsUtils
#include "RooStats/RooStatsUtils.h"
#endif

#include "RooStats/LikelihoodInterval.h"
#include "RooStats/HypoTestResult.h"

#include "RooFitResult.h"
#include "RooRealVar.h"
#include "RooProfileLL.h"
#include "RooNLLVar.h"
#include "RooGlobalFunc.h"
#include "RooMsgService.h"

#include "Math/MinimizerOptions.h"
//#include "RooProdPdf.h"

using namespace std;

ClassImp(RooStats::ProfileLikelihoodCalculator) ;

using namespace RooFit;
using namespace RooStats;

//_______________________________________________________
ProfileLikelihoodCalculator::ProfileLikelihoodCalculator() :
   CombinedCalculator(), fFitResult(0)
{
   // default constructor
}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooAbsData& data, RooAbsPdf& pdf, const RooArgSet& paramsOfInterest,
                                                         Double_t size, const RooArgSet* nullParams ) :
   CombinedCalculator(data,pdf, paramsOfInterest, size, nullParams ),
   fFitResult(0)
{
   // constructor from pdf and parameters
   // the pdf must contain eventually the nuisance parameters
}

ProfileLikelihoodCalculator::ProfileLikelihoodCalculator(RooAbsData& data,  ModelConfig& model, Double_t size) :
   CombinedCalculator(data, model, size),
   fFitResult(0)
{
   // construct from a ModelConfig. Assume data model.GetPdf() will provide full description of model including
   // constraint term on the nuisances parameters
   assert(model.GetPdf() );
}

//_______________________________________________________
ProfileLikelihoodCalculator::~ProfileLikelihoodCalculator(){
   // destructor
   // cannot delete prod pdf because it will delete all the composing pdf's
//    if (fOwnPdf) delete fPdf;
//    fPdf = 0;
   if (fFitResult) delete fFitResult;
}

void ProfileLikelihoodCalculator::DoReset() const {
   // reset and clear fit result
   // to be called when a new model or data are set in the calculator
   if (fFitResult) delete fFitResult;
   fFitResult = 0;
}

void  ProfileLikelihoodCalculator::DoGlobalFit() const {
   // perform a global fit of the likelihood letting with all parameter of interest and
   // nuisance parameters
   // keep the list of fitted parameters

   DoReset();
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();
   if (!data || !pdf ) return;

   // get all non-const parameters
   RooArgSet* constrainedParams = pdf->getParameters(*data);
   if (!constrainedParams) return ;
   RemoveConstantParameters(constrainedParams);

   // calculate MLE
   const char * minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
   const char * minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str();
   int strategy = ROOT::Math::MinimizerOptions::DefaultStrategy();
   int level = ROOT::Math::MinimizerOptions::DefaultPrintLevel() -1;// RooFit level starts from  -1
   oocoutP((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::DoGlobalFit - using " << minimType << " / " << minimAlgo << " with strategy " << strategy << std::endl;
   // do global fit and store fit result for further use
   fFitResult = pdf->fitTo(*data, Constrain(*constrainedParams),ConditionalObservables(fConditionalObs),
                           Strategy(strategy),PrintLevel(level),
                           Hesse(kFALSE),Save(kTRUE),Minimizer(minimType,minimAlgo));

   // print fit result
   if (fFitResult)
      fFitResult->printStream( oocoutI((TObject*)0,Minimization), fFitResult->defaultPrintContents(0), fFitResult->defaultPrintStyle(0) );

   if (fFitResult->status() != 0)
      oocoutW((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::DoGlobalFit -  Global fit failed - status = " << fFitResult->status() << std::endl;

   delete constrainedParams;

}

//_______________________________________________________
LikelihoodInterval* ProfileLikelihoodCalculator::GetInterval() const {
   // Main interface to get a RooStats::ConfInterval.
   // It constructs a profile likelihood ratio and uses that to construct a RooStats::LikelihoodInterval.

//    RooAbsPdf* pdf   = fWS->pdf(fPdfName);
//    RooAbsData* data = fWS->data(fDataName);
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();
   if (!data || !pdf || fPOI.getSize() == 0) return 0;

   RooArgSet* constrainedParams = pdf->getParameters(*data);
   RemoveConstantParameters(constrainedParams);

   /*
   RooNLLVar* nll = new RooNLLVar("nll","",*pdf,*data, Extended(),Constrain(*constrainedParams));
   RooProfileLL* profile = new RooProfileLL("pll","",*nll, *fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak
   */

   RooAbsReal *  nll = pdf->createNLL(*data, CloneData(kTRUE), Constrain(*constrainedParams),ConditionalObservables(fConditionalObs));

   RooAbsReal* profile = nll->createProfile(fPOI);
   profile->addOwnedComponents(*nll) ;  // to avoid memory leak

   //RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL) ;
   // perform a Best Fit
   if (!fFitResult) DoGlobalFit();
   // if fit fails return
   if (!fFitResult)   return 0;

   // t.b.f. " RooProfileLL should keep and provide possibility to query on global minimum
   // set POI to fit value (this will speed up profileLL calculation of global minimum)
   const RooArgList & fitParams = fFitResult->floatParsFinal();
   for (int i = 0; i < fitParams.getSize(); ++i) {
      RooRealVar & fitPar =  (RooRealVar &) fitParams[i];
      RooRealVar * par = (RooRealVar*) fPOI.find( fitPar.GetName() );
      if (par) {
         par->setVal( fitPar.getVal() );
         par->setError( fitPar.getError() );
      }
   }

   // do this so profile will cache inside the absolute minimum and
   // minimum values of nuisance parameters
   // (no need to this here)
   // profile->getVal();
   //RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
   //  profile->Print();

   TString name = TString("LikelihoodInterval_");// + TString(GetName() );

   // make a list of fPOI with fit result values and pass to LikelihoodInterval class
   // bestPOI is a cloned list of POI only with their best fit values
   TIter iter = fPOI.createIterator();
   RooArgSet fitParSet(fitParams);
   RooArgSet * bestPOI = new RooArgSet();
   while (RooAbsArg * arg =  (RooAbsArg*) iter.Next() ) {
      RooAbsArg * p  =  fitParSet.find( arg->GetName() );
      if (p) bestPOI->addClone(*p);
      else bestPOI->addClone(*arg);
   }
   // fPOI contains the paramter of interest of the PL object
   // and bestPOI contains a snapshot with the best fit values
   LikelihoodInterval* interval = new LikelihoodInterval(name, profile, &fPOI, bestPOI);
   interval->SetConfidenceLevel(1.-fSize);
   delete constrainedParams;
   return interval;
}

//_______________________________________________________
HypoTestResult* ProfileLikelihoodCalculator::GetHypoTest() const {
   // Main interface to get a HypoTestResult.
   // It does two fits:
   // the first lets the null parameters float, so it's a maximum likelihood estimate
   // the second is to the null (fixing null parameters to their specified values): eg. a conditional maximum likelihood
   // the ratio of the likelihood at the conditional MLE to the MLE is the profile likelihood ratio.
   // Wilks' theorem is used to get p-values

//    RooAbsPdf* pdf   = fWS->pdf(fPdfName);
//    RooAbsData* data = fWS->data(fDataName);
   RooAbsPdf * pdf = GetPdf();
   RooAbsData* data = GetData();

   if (!data || !pdf) return 0;

   if (fNullParams.getSize() == 0) return 0;

   // make a clone and ordered list since a vector will be associated to keep parameter values
   // clone the list since first fit will changes the fNullParams values
   RooArgList poiList;
   poiList.addClone(fNullParams); // make a clone list

   // do a global fit
   if (!fFitResult) DoGlobalFit();
   if (!fFitResult) return 0;

   RooArgSet* constrainedParams = pdf->getParameters(*data);
   RemoveConstantParameters(constrainedParams);

   // perform a global fit if it is not done before
   if (!fFitResult) DoGlobalFit();
   Double_t NLLatMLE= fFitResult->minNll();

   // set POI to given values, set constant, calculate conditional MLE
   std::vector<double> oldValues(poiList.getSize() );
   for (unsigned int i = 0; i < oldValues.size(); ++i) {
      RooRealVar * mytarget = (RooRealVar*) constrainedParams->find(poiList[i].GetName());
      if (mytarget) {
         oldValues[i] = mytarget->getVal();
         mytarget->setVal( ( (RooRealVar&) poiList[i] ).getVal() );
         mytarget->setConstant(kTRUE);
      }
   }

   // perform the fit only if nuisance parameters are available
   // get nuisance parameters
   // nuisance parameters are the non const parameters from the likelihood parameters
   RooArgSet nuisParams(*constrainedParams);

   // need to remove the parameter of interest
   RemoveConstantParameters(&nuisParams);

   // check there are variable parameter in order to do a fit
   bool existVarParams = false;
   TIter it = nuisParams.createIterator();
   RooRealVar * myarg = 0;
   while ((myarg = (RooRealVar *)it.Next())) {
      if ( !myarg->isConstant() ) {
         existVarParams = true;
         break;
      }
   }

   Double_t NLLatCondMLE = NLLatMLE;
   if (existVarParams) {

      const char * minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
      const char * minimAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerType().c_str();
      int level = ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1; // RooFit levels starts from -1
      oocoutP((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::GetHypoTest - do conditional fit " << std::endl;
      RooFitResult* fit2 = pdf->fitTo(*data,Constrain(*constrainedParams),ConditionalObservables(fConditionalObs),
                                      Hesse(kFALSE),Strategy(0), Minos(kFALSE),
                                      Minimizer(minimType,minimAlgo), Save(kTRUE),PrintLevel(level));

      // print fit result
      if (fit2) {
         NLLatCondMLE = fit2->minNll();
         fit2->printStream( oocoutI((TObject*)0,Minimization), fit2->defaultPrintContents(0), fit2->defaultPrintStyle(0) );

         if (fit2->status() != 0)
            oocoutW((TObject*)0,Minimization) << "ProfileLikelihoodCalcultor::GetHypotest -  Conditional fit failed - status = " << fit2->status() << std::endl;
      }

   }
   else {
      // get just the likelihood value (no need to do a fit since the likelihood is a constant function)
      RooAbsReal* nll = pdf->createNLL(*data, CloneData(kTRUE), Constrain(*constrainedParams),ConditionalObservables(fConditionalObs));
      NLLatCondMLE = nll->getVal();
      delete nll;
   }

   // Use Wilks' theorem to translate -2 log lambda into a signifcance/p-value
   Double_t deltaNLL = std::max( NLLatCondMLE-NLLatMLE, 0.);

   // get number of free parameter of interest
   RemoveConstantParameters(poiList);
   int ndf = poiList.getSize();

   Double_t pvalue = ROOT::Math::chisquared_cdf_c( 2* deltaNLL, ndf);

   // in case of one dimenension (1 poi) do the one-sided p-value (need to divide by 2)
   if (ndf == 1) pvalue = 0.5 * pvalue;

   TString name = TString("ProfileLRHypoTestResult_");// + TString(GetName() );
   HypoTestResult* htr = new HypoTestResult(name, pvalue, 0 );

   // restore previous value of poi
   for (unsigned int i = 0; i < oldValues.size(); ++i) {
      RooRealVar * mytarget = (RooRealVar*) constrainedParams->find(poiList[i].GetName());
      if (mytarget) {
         mytarget->setVal(oldValues[i] );
         mytarget->setConstant(false);
      }
   }

   delete constrainedParams;
   return htr;

}

<|endoftext|>


<commit_before>#include "LolaAdaptor.h"

using namespace naoth;

LolaAdaptor::LolaAdaptor()
{
    // open semaphore to synchronize with NaoController
    if((sem = sem_open("motion_trigger", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0)) == SEM_FAILED)
    {
        perror("[LolaAdaptor] sem_open");
        ::exit(-1);
    }

    openSharedMemory(naoSensorData, "/nao_sensor_data");
    openSharedMemory(naoCommandMotorJointData, "/nao_command.MotorJointData");
    openSharedMemory(naoCommandUltraSoundSendData, "/nao_command.UltraSoundSendData");
    openSharedMemory(naoCommandLEDData, "/nao_command.LEDData");
}

LolaAdaptor::~LolaAdaptor()
{
    // stop the thread before anything else
    stop();

    // close semaphore
    if(sem != SEM_FAILED)
    {
        sem_close(sem);
        sem = SEM_FAILED;
    }
}

template<typename T>
void LolaAdaptor::openSharedMemory(SharedMemory<T> &sm, const std::string &path)
{
    std::cout<< "[LolaAdaptor] Opening Shared Memory: "<<path<<std::endl;
    sm.open(path);
}

void LolaAdaptor::writeNaoInfo(const std::string& theBodyID, const std::string& /*theHeadID*/) const
{
    // save the body ID
    std::cout << "[LolaAdaptor] bodyID: " << theBodyID << std::endl;

    // save the nick name
    std::string theBodyNickName = "error";
    if(theBodyID.length() >= 4) {
      theBodyNickName = "Nao" + theBodyID.substr( theBodyID.length() - 4 ); //theDCMHandler.getBodyNickName();
    }
    std::cout << "[LolaAdaptor] nickName: "<< theBodyNickName << std::endl;

    // save the value to file
    // FIXME: fixed path "Config/nao.info"
    {
        std::string staticMemberPath("Config/nao.info");
        std::ofstream os(staticMemberPath.c_str());
        ASSERT(os.good());
        os << theBodyID << "\n" << theBodyNickName << std::endl;
        os.close();
    }
}//end writeNaoInfo()

void LolaAdaptor::start()
{
    exiting = false;
    lolaThread = std::thread(&LolaAdaptor::run, this);
    //ThreadUtil::setPriority(lolaThread, ThreadUtil::Priority::highest);
    ThreadUtil::setName(lolaThread, "LOLA");

    // NOTE: SCHED_FIFO is a real time sheduler
    //       max priority for a FIFO thread is 99
    sched_param param;
    param.sched_priority = 50;
    if(pthread_setschedparam(lolaThread.native_handle(), SCHED_FIFO, &param)) {
        std::cerr << "[LolaAdaptor] error setting thread priority" << std::endl;
        assert(false);
    }

    // int tryCount = 0;
    while(waitingForLola && ! exiting)
    {
        fprintf(stderr, "[LolaAdaptor] Waiting for LoLA socket.\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(125));
        // if(tryCount > 40 )
        // {
        //   fprintf(stderr, "[LolaAdaptor] Waiting for LoLA socket failed after %d ms.\n", tryCount * 125);
        //   waitingForLola = false;
        //   assert(false);
        // }
        // tryCount++;
    }
    fprintf(stderr, "[LolaAdaptor] LoLA socket connection established.\n");
    //HACK: pulseaudio is not initialized correctly, but after playing a sound as no it works?!?
}//end start()

void LolaAdaptor::stop()
{
    std::cout << "[LolaAdaptor] stop wait" << std::endl;

    // request the thread to stop
    exiting = true;

    if(lolaThread.joinable()) {
        lolaThread.join();
    }
    std::cout << "[LolaAdaptor] stop done" << std::endl;
}

bool LolaAdaptor::isRunning() const
{
    return running;
}

void LolaAdaptor::run()
{
    waitForLolaSocket();

    Lola lola;
    lola.connectSocket();
    if(lola.hasError())
    {
        fprintf(stderr, "[LolaAdaptor] Error while attemting to connect to LoLa socket.\n");
        assert(false);
    }

    waitingForLola = false;
    running = true;
    SensorData sensors;
    ActuatorData actuators;

    bool firstRun = true;

    while(!exiting)
    {
        lola.readSensors(sensors);

        if(firstRun) {
          writeNaoInfo(sensors.RobotConfig.Body.BodyId, sensors.RobotConfig.Head.FullHeadId);
          firstRun = false;
        }

        // like old DCM motionCallbackPre
        if(!runEmergencyMotion(actuators))
        {
            setMotorJoints(actuators);
        }
        lola.writeActuators(actuators);

        // like old DCM motionCallbackPost
        DCMSensorData* sensorData = naoSensorData.writing();

        // current system time (System time, not nao time (!))
        sensorData->timeStamp = NaoTime::getSystemTimeInMilliSeconds();

        // copy sensor data to shared memory
        LolaDataConverter::readSensorData(sensors, *sensorData);

        // check if chest button was pressed as a request to shutdown
        // each cycle needs 12ms so if the button was pressed for 3 seconds
        // these are 250 frames
        sensorData->get(theButtonData);
        if(!shutdown_requested && theButtonData.numOfFramesPressed[ButtonData::Chest] > 250)
        {
            shutdown_requested = true;
            //exit(-1);
            // break;
            shutdownCallbackThread = std::thread(&LolaAdaptor::shutdownCallback, this);
        }

        // save the data for the emergency case
        if(state == DISCONNECTED) {
            std::cout << "get inertial sensor data" << std::endl;
            sensorData->get(theInertialSensorData);
            sensor_data_available = true;
        } else {
            sensor_data_available = false;
        }

        // push the data to shared memory
        naoSensorData.swapWriting();

        // notify cognition
        notify();
    }

    running = false;
}//end run()

void LolaAdaptor::waitForLolaSocket()
{
    int tryCount = 0;

    // end the thread if the lola (unix) socket doesn't exists (after 5s)!
    while(!fileExists("/tmp/robocup"))
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
        if(tryCount > 20 )
        {
            fprintf(stderr, "[LolaAdaptor] Waiting for LoLa %d ms.\n", tryCount * 250);
            assert(false);
        }
        tryCount++;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(900));
}//end waitForLolaSocket()

bool LolaAdaptor::fileExists(const std::string& filename)
{
    struct stat buffer;
    return (stat (filename.c_str(), &buffer) == 0);
}

void LolaAdaptor::setMotorJoints(ActuatorData &actuators)
{
    // get the MotorJointData from the shared memory and put them to the DCM
    if ( naoCommandMotorJointData.swapReading() )
    {
        const Accessor<MotorJointData>* motorData = naoCommandMotorJointData.reading();

        // write MotorJointData to LolaActuatorData
        LolaDataConverter::set(actuators, motorData->get());

        // TODO: why do we need this? It is never resetted ...
        //drop_count = 0;
        command_data_available = true;
    }

    if(naoCommandLEDData.swapReading())
    {
        const Accessor<LEDData>* commandData = naoCommandLEDData.reading();
        LolaDataConverter::set(actuators, commandData->get());
    }
}//end setMotorJoints()

void LolaAdaptor::setWarningLED(ActuatorData& actuators, bool red)
{
    static naoth::LEDData theLEDData;
    static int count = 0;

    int begin = ((++count)/10)%10;
    theLEDData.theMonoLED[LEDData::EarRight0 + begin] = 0;
    theLEDData.theMonoLED[LEDData::EarLeft0 + begin] = 0;
    int end = (begin+2)%10;
    theLEDData.theMonoLED[LEDData::EarRight0 + end] = 1;
    theLEDData.theMonoLED[LEDData::EarLeft0 + end] = 1;

    for(int i=0; i<LEDData::numOfMultiLED; i++)
    {
        theLEDData.theMultiLED[i][LEDData::RED] = red ? 1 : 0;
        theLEDData.theMultiLED[i][LEDData::GREEN] = 0;
        theLEDData.theMultiLED[i][LEDData::BLUE] = red ? 0 : 1;
    }
    LolaDataConverter::set(actuators, theLEDData);
}//end setWarningLED

bool LolaAdaptor::runEmergencyMotion(ActuatorData& actuators)
{
    if(state == DISCONNECTED)
    {
        if(initialMotion == NULL && command_data_available && sensor_data_available)
        {
            std::cout << "emerg: start init motion" << std::endl;
            // take the last command data
            const Accessor<MotorJointData>* commandData = naoCommandMotorJointData.reading();
            initialMotion = new BasicMotion(theMotorJointData, commandData->get(), theInertialSensorData);
        }

        setWarningLED(actuators, state == DISCONNECTED);
    }//end if

    // after reconnect: wait until the init motion is finished
    if(initialMotion != NULL)
    {
        if(state == CONNECTED && initialMotion->isFinish())
        {
            std::cout << "emerg: stop init motion" << std::endl;
            delete initialMotion;
            initialMotion = NULL;
        }
        else
        {
            // execute the emergency motion
            // (the resulting joint commands are written to theMotorJointData)
            initialMotion->execute();

            // write MotorJointData to LolaActuatorData
            LolaDataConverter::set(actuators, theMotorJointData);
        }
    }//end if

    return initialMotion != NULL;
}//end runEmergencyMotion

void LolaAdaptor::notify()
{
    static int drop_count = 10;

    // raise the semaphore: triggers core
    if(sem != SEM_FAILED)
    {
        int sval;
        if(sem_getvalue(sem, &sval) == 0)
        {
            if(sval < 1)
            {
                sem_post(sem);

                // until now we were disconnected, but now we're alive and connected ...
                if(state == DISCONNECTED) {
                    fprintf(stderr, "[LolaAdaptor] I think the core is alive.\n");
                }

                drop_count = 0;
                state = CONNECTED;
            }
            else
            {
                if(drop_count == 0) {
                    fprintf(stderr, "[LolaAdaptor] dropped sensor data.\n");
                } else if(drop_count == 10) {
                    fprintf(stderr, "[LolaAdaptor] I think the core is dead.\n");
                    state = DISCONNECTED;
                }

                // don't count more than 11
                drop_count += (drop_count < 11);
            }//end if
        }
        else
        {
            fprintf(stderr, "[LolaAdaptor] I couldn't get value by sem_getvalue.\n");
        }
    }//end if SEM_FAILED
}//end notify()

void LolaAdaptor::shutdownCallback()
{
    // play a sound that the user knows we recognized his shutdown request
    system("paplay /opt/aldebaran/share/naoqi/wav/bip_power_off.wav");

    // stop the user program
    std::cout << "[LolaAdaptor] stopping naoth" << std::endl;
    // stop naoth to trigger emergency motion
    system("killall naoth");
    // in NaoSMAL it's like this
    //system("naoth stop");

    sleep(5);

    // we are the child process, do a blocking call to shutdown
    std::cout << "[LolaAdaptor] System shutdown requested" << std::endl;
    system("/sbin/shutdown -h now");

    // await termination
    while(true) {
        sleep(100);
    }
}//end shutdownCallback
<commit_msg>fix: use full path for writing in nao info. This helps for running it locally. We can use full path here because we will only run it on the nao anyways<commit_after>#include "LolaAdaptor.h"

using namespace naoth;

LolaAdaptor::LolaAdaptor()
{
    // open semaphore to synchronize with NaoController
    if((sem = sem_open("motion_trigger", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, 0)) == SEM_FAILED)
    {
        perror("[LolaAdaptor] sem_open");
        ::exit(-1);
    }

    openSharedMemory(naoSensorData, "/nao_sensor_data");
    openSharedMemory(naoCommandMotorJointData, "/nao_command.MotorJointData");
    openSharedMemory(naoCommandUltraSoundSendData, "/nao_command.UltraSoundSendData");
    openSharedMemory(naoCommandLEDData, "/nao_command.LEDData");
}

LolaAdaptor::~LolaAdaptor()
{
    // stop the thread before anything else
    stop();

    // close semaphore
    if(sem != SEM_FAILED)
    {
        sem_close(sem);
        sem = SEM_FAILED;
    }
}

template<typename T>
void LolaAdaptor::openSharedMemory(SharedMemory<T> &sm, const std::string &path)
{
    std::cout<< "[LolaAdaptor] Opening Shared Memory: "<<path<<std::endl;
    sm.open(path);
}

void LolaAdaptor::writeNaoInfo(const std::string& theBodyID, const std::string& /*theHeadID*/) const
{
    // save the body ID
    std::cout << "[LolaAdaptor] bodyID: " << theBodyID << std::endl;

    // save the nick name
    std::string theBodyNickName = "error";
    if(theBodyID.length() >= 4) {
      theBodyNickName = "Nao" + theBodyID.substr( theBodyID.length() - 4 ); //theDCMHandler.getBodyNickName();
    }
    std::cout << "[LolaAdaptor] nickName: "<< theBodyNickName << std::endl;

    // save the value to file
    // FIXME: fixed path "Config/nao.info"
    {
        std::string staticMemberPath("/home/nao/Config/nao.info");
        std::ofstream os(staticMemberPath.c_str());
        ASSERT(os.good());
        os << theBodyID << "\n" << theBodyNickName << std::endl;
        os.close();
    }
}//end writeNaoInfo()

void LolaAdaptor::start()
{
    exiting = false;
    lolaThread = std::thread(&LolaAdaptor::run, this);
    //ThreadUtil::setPriority(lolaThread, ThreadUtil::Priority::highest);
    ThreadUtil::setName(lolaThread, "LOLA");

    // NOTE: SCHED_FIFO is a real time sheduler
    //       max priority for a FIFO thread is 99
    sched_param param;
    param.sched_priority = 50;
    if(pthread_setschedparam(lolaThread.native_handle(), SCHED_FIFO, &param)) {
        std::cerr << "[LolaAdaptor] error setting thread priority" << std::endl;
        assert(false);
    }

    // int tryCount = 0;
    while(waitingForLola && ! exiting)
    {
        fprintf(stderr, "[LolaAdaptor] Waiting for LoLA socket.\n");
        std::this_thread::sleep_for(std::chrono::milliseconds(125));
        // if(tryCount > 40 )
        // {
        //   fprintf(stderr, "[LolaAdaptor] Waiting for LoLA socket failed after %d ms.\n", tryCount * 125);
        //   waitingForLola = false;
        //   assert(false);
        // }
        // tryCount++;
    }
    fprintf(stderr, "[LolaAdaptor] LoLA socket connection established.\n");
    //HACK: pulseaudio is not initialized correctly, but after playing a sound as no it works?!?
}//end start()

void LolaAdaptor::stop()
{
    std::cout << "[LolaAdaptor] stop wait" << std::endl;

    // request the thread to stop
    exiting = true;

    if(lolaThread.joinable()) {
        lolaThread.join();
    }
    std::cout << "[LolaAdaptor] stop done" << std::endl;
}

bool LolaAdaptor::isRunning() const
{
    return running;
}

void LolaAdaptor::run()
{
    waitForLolaSocket();

    Lola lola;
    lola.connectSocket();
    if(lola.hasError())
    {
        fprintf(stderr, "[LolaAdaptor] Error while attemting to connect to LoLa socket.\n");
        assert(false);
    }

    waitingForLola = false;
    running = true;
    SensorData sensors;
    ActuatorData actuators;

    bool firstRun = true;

    while(!exiting)
    {
        lola.readSensors(sensors);

        if(firstRun) {
          writeNaoInfo(sensors.RobotConfig.Body.BodyId, sensors.RobotConfig.Head.FullHeadId);
          firstRun = false;
        }

        // like old DCM motionCallbackPre
        if(!runEmergencyMotion(actuators))
        {
            setMotorJoints(actuators);
        }
        lola.writeActuators(actuators);

        // like old DCM motionCallbackPost
        DCMSensorData* sensorData = naoSensorData.writing();

        // current system time (System time, not nao time (!))
        sensorData->timeStamp = NaoTime::getSystemTimeInMilliSeconds();

        // copy sensor data to shared memory
        LolaDataConverter::readSensorData(sensors, *sensorData);

        // check if chest button was pressed as a request to shutdown
        // each cycle needs 12ms so if the button was pressed for 3 seconds
        // these are 250 frames
        sensorData->get(theButtonData);
        if(!shutdown_requested && theButtonData.numOfFramesPressed[ButtonData::Chest] > 250)
        {
            shutdown_requested = true;
            //exit(-1);
            // break;
            shutdownCallbackThread = std::thread(&LolaAdaptor::shutdownCallback, this);
        }

        // save the data for the emergency case
        if(state == DISCONNECTED) {
            std::cout << "get inertial sensor data" << std::endl;
            sensorData->get(theInertialSensorData);
            sensor_data_available = true;
        } else {
            sensor_data_available = false;
        }

        // push the data to shared memory
        naoSensorData.swapWriting();

        // notify cognition
        notify();
    }

    running = false;
}//end run()

void LolaAdaptor::waitForLolaSocket()
{
    int tryCount = 0;

    // end the thread if the lola (unix) socket doesn't exists (after 5s)!
    while(!fileExists("/tmp/robocup"))
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(250));
        if(tryCount > 20 )
        {
            fprintf(stderr, "[LolaAdaptor] Waiting for LoLa %d ms.\n", tryCount * 250);
            assert(false);
        }
        tryCount++;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(900));
}//end waitForLolaSocket()

bool LolaAdaptor::fileExists(const std::string& filename)
{
    struct stat buffer;
    return (stat (filename.c_str(), &buffer) == 0);
}

void LolaAdaptor::setMotorJoints(ActuatorData &actuators)
{
    // get the MotorJointData from the shared memory and put them to the DCM
    if ( naoCommandMotorJointData.swapReading() )
    {
        const Accessor<MotorJointData>* motorData = naoCommandMotorJointData.reading();

        // write MotorJointData to LolaActuatorData
        LolaDataConverter::set(actuators, motorData->get());

        // TODO: why do we need this? It is never resetted ...
        //drop_count = 0;
        command_data_available = true;
    }

    if(naoCommandLEDData.swapReading())
    {
        const Accessor<LEDData>* commandData = naoCommandLEDData.reading();
        LolaDataConverter::set(actuators, commandData->get());
    }
}//end setMotorJoints()

void LolaAdaptor::setWarningLED(ActuatorData& actuators, bool red)
{
    static naoth::LEDData theLEDData;
    static int count = 0;

    int begin = ((++count)/10)%10;
    theLEDData.theMonoLED[LEDData::EarRight0 + begin] = 0;
    theLEDData.theMonoLED[LEDData::EarLeft0 + begin] = 0;
    int end = (begin+2)%10;
    theLEDData.theMonoLED[LEDData::EarRight0 + end] = 1;
    theLEDData.theMonoLED[LEDData::EarLeft0 + end] = 1;

    for(int i=0; i<LEDData::numOfMultiLED; i++)
    {
        theLEDData.theMultiLED[i][LEDData::RED] = red ? 1 : 0;
        theLEDData.theMultiLED[i][LEDData::GREEN] = 0;
        theLEDData.theMultiLED[i][LEDData::BLUE] = red ? 0 : 1;
    }
    LolaDataConverter::set(actuators, theLEDData);
}//end setWarningLED

bool LolaAdaptor::runEmergencyMotion(ActuatorData& actuators)
{
    if(state == DISCONNECTED)
    {
        if(initialMotion == NULL && command_data_available && sensor_data_available)
        {
            std::cout << "emerg: start init motion" << std::endl;
            // take the last command data
            const Accessor<MotorJointData>* commandData = naoCommandMotorJointData.reading();
            initialMotion = new BasicMotion(theMotorJointData, commandData->get(), theInertialSensorData);
        }

        setWarningLED(actuators, state == DISCONNECTED);
    }//end if

    // after reconnect: wait until the init motion is finished
    if(initialMotion != NULL)
    {
        if(state == CONNECTED && initialMotion->isFinish())
        {
            std::cout << "emerg: stop init motion" << std::endl;
            delete initialMotion;
            initialMotion = NULL;
        }
        else
        {
            // execute the emergency motion
            // (the resulting joint commands are written to theMotorJointData)
            initialMotion->execute();

            // write MotorJointData to LolaActuatorData
            LolaDataConverter::set(actuators, theMotorJointData);
        }
    }//end if

    return initialMotion != NULL;
}//end runEmergencyMotion

void LolaAdaptor::notify()
{
    static int drop_count = 10;

    // raise the semaphore: triggers core
    if(sem != SEM_FAILED)
    {
        int sval;
        if(sem_getvalue(sem, &sval) == 0)
        {
            if(sval < 1)
            {
                sem_post(sem);

                // until now we were disconnected, but now we're alive and connected ...
                if(state == DISCONNECTED) {
                    fprintf(stderr, "[LolaAdaptor] I think the core is alive.\n");
                }

                drop_count = 0;
                state = CONNECTED;
            }
            else
            {
                if(drop_count == 0) {
                    fprintf(stderr, "[LolaAdaptor] dropped sensor data.\n");
                } else if(drop_count == 10) {
                    fprintf(stderr, "[LolaAdaptor] I think the core is dead.\n");
                    state = DISCONNECTED;
                }

                // don't count more than 11
                drop_count += (drop_count < 11);
            }//end if
        }
        else
        {
            fprintf(stderr, "[LolaAdaptor] I couldn't get value by sem_getvalue.\n");
        }
    }//end if SEM_FAILED
}//end notify()

void LolaAdaptor::shutdownCallback()
{
    // play a sound that the user knows we recognized his shutdown request
    system("paplay /opt/aldebaran/share/naoqi/wav/bip_power_off.wav");

    // stop the user program
    std::cout << "[LolaAdaptor] stopping naoth" << std::endl;
    // stop naoth to trigger emergency motion
    system("killall naoth");
    // in NaoSMAL it's like this
    //system("naoth stop");

    sleep(5);

    // we are the child process, do a blocking call to shutdown
    std::cout << "[LolaAdaptor] System shutdown requested" << std::endl;
    system("/sbin/shutdown -h now");

    // await termination
    while(true) {
        sleep(100);
    }
}//end shutdownCallback
<|endoftext|>


<commit_before>/*****************************************************************************
 * recents.cpp : Recents MRL (menu)
 *****************************************************************************
 * Copyright © 2008-2014 VideoLAN and VLC authors
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *          Jean-baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qt4.hpp"
#include "recents.hpp"
#include "dialogs_provider.hpp"
#include "menus.hpp"
#include "util/qt_dirs.hpp"

#include <QStringList>
#include <QRegExp>
#include <QSignalMapper>

#ifdef _WIN32
    #include <shlobj.h>
    /* typedef enum  {
        SHARD_PIDL              = 0x00000001,
        SHARD_PATHA             = 0x00000002,
        SHARD_PATHW             = 0x00000003,
        SHARD_APPIDINFO         = 0x00000004,
        SHARD_APPIDINFOIDLIST   = 0x00000005,
        SHARD_LINK              = 0x00000006,
        SHARD_APPIDINFOLINK     = 0x00000007,
        SHARD_SHELLITEM         = 0x00000008
    } SHARD; */
    #define SHARD_PATHW 0x00000003

    #include <vlc_charset.h>
#endif

RecentsMRL::RecentsMRL( intf_thread_t *_p_intf ) : p_intf( _p_intf )
{
    stack = new QStringList;

    signalMapper = new QSignalMapper( this );
    CONNECT( signalMapper,
            mapped(const QString & ),
            this,
            playMRL( const QString & ) );

    /* Load the filter psz */
    char* psz_tmp = var_InheritString( p_intf, "qt-recentplay-filter" );
    if( psz_tmp && *psz_tmp )
        filter = new QRegExp( psz_tmp, Qt::CaseInsensitive );
    else
        filter = NULL;
    free( psz_tmp );

    load();
    isActive = var_InheritBool( p_intf, "qt-recentplay" );
    if( !isActive ) clear();
}

RecentsMRL::~RecentsMRL()
{
    delete filter;
    delete stack;
}

void RecentsMRL::addRecent( const QString &mrl )
{
    if ( !isActive || ( filter && filter->indexIn( mrl ) >= 0 ) )
        return;

#ifdef _WIN32
    /* Add to the Windows 7 default list in taskbar */
    char* path = make_path( qtu( mrl ) );
    if( path )
    {
        wchar_t *wmrl = ToWide( path );
        SHAddToRecentDocs( SHARD_PATHW, wmrl );
        free( wmrl );
        free( path );
    }
#endif

    int i_index = stack->indexOf( mrl );
    if( 0 <= i_index )
    {
        /* move to the front */
        stack->move( i_index, 0 );
    }
    else
    {
        stack->prepend( mrl );
        if( stack->count() > RECENTS_LIST_SIZE )
            stack->takeLast();
    }
    VLCMenuBar::updateRecents( p_intf );
    save();
}

void RecentsMRL::clear()
{
    if ( stack->isEmpty() )
        return;

    stack->clear();
    if( isActive ) VLCMenuBar::updateRecents( p_intf );
    save();
}

QStringList RecentsMRL::recents()
{
    return *stack;
}

void RecentsMRL::load()
{
    /* Load from the settings */
    QStringList list = getSettings()->value( "RecentsMRL/list" ).toStringList();

    /* And filter the regexp on the list */
    for( int i = 0; i < list.count(); ++i )
    {
        if ( !filter || filter->indexIn( list.at(i) ) == -1 )
            stack->append( list.at(i) );
    }
}

void RecentsMRL::save()
{
    getSettings()->setValue( "RecentsMRL/list", *stack );
}

playlist_item_t *RecentsMRL::toPlaylist(int length)
{
    playlist_item_t *p_node_recent = playlist_NodeCreate(THEPL, _("Recently Played"), THEPL->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL);

    if ( p_node_recent == NULL )  return NULL;

    if (length == 0 || stack->count() < length)
        length = stack->count();

    for (int i = 0; i < length; i++)
    {
        input_item_t *p_input = input_item_New(qtu(stack->at(i)), NULL);
        playlist_NodeAddInput(THEPL, p_input, p_node_recent, PLAYLIST_APPEND, PLAYLIST_END, false);
    }

    return p_node_recent;
}

void RecentsMRL::playMRL( const QString &mrl )
{
    Open::openMRL( p_intf, mrl );
}

int Open::openMRL( intf_thread_t *p_intf,
                    const QString &mrl,
                    bool b_start,
                    bool b_playlist)
{
    return openMRLwithOptions( p_intf, mrl, NULL, b_start, b_playlist );
}

int Open::openMRLwithOptions( intf_thread_t* p_intf,
                     const QString &mrl,
                     QStringList *options,
                     bool b_start,
                     bool b_playlist,
                     const char *title)
{
    /* Options */
    const char **ppsz_options = NULL;
    int i_options = 0;

    if( options != NULL && options->count() > 0 )
    {
        ppsz_options = (const char **)malloc( options->count() );
        if( ppsz_options ) {
            for( int j = 0; j < options->count(); j++ ) {
                QString option = colon_unescape( options->at(j) );
                if( !option.isEmpty() ) {
                    ppsz_options[j] = qtu(option);
                    i_options++;
                }
            }
        }
    }

    /* Add to playlist */
    int i_ret = playlist_AddExt( THEPL,
                  qtu(mrl), title,
                  PLAYLIST_APPEND | (b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE),
                  PLAYLIST_END,
                  -1,
                  i_options, ppsz_options, VLC_INPUT_OPTION_TRUSTED,
                  b_playlist,
                  pl_Unlocked );

    /* Add to recent items, only if played */
    if( i_ret == VLC_SUCCESS && b_start && b_playlist )
        RecentsMRL::getInstance( p_intf )->addRecent( mrl );

    return i_ret;
}

<commit_msg>Qt: save recents on quit()<commit_after>/*****************************************************************************
 * recents.cpp : Recents MRL (menu)
 *****************************************************************************
 * Copyright © 2008-2014 VideoLAN and VLC authors
 * $Id$
 *
 * Authors: Ludovic Fauvet <etix@l0cal.com>
 *          Jean-baptiste Kempf <jb@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * ( at your option ) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "qt4.hpp"
#include "recents.hpp"
#include "dialogs_provider.hpp"
#include "menus.hpp"
#include "util/qt_dirs.hpp"

#include <QStringList>
#include <QRegExp>
#include <QSignalMapper>

#ifdef _WIN32
    #include <shlobj.h>
    /* typedef enum  {
        SHARD_PIDL              = 0x00000001,
        SHARD_PATHA             = 0x00000002,
        SHARD_PATHW             = 0x00000003,
        SHARD_APPIDINFO         = 0x00000004,
        SHARD_APPIDINFOIDLIST   = 0x00000005,
        SHARD_LINK              = 0x00000006,
        SHARD_APPIDINFOLINK     = 0x00000007,
        SHARD_SHELLITEM         = 0x00000008
    } SHARD; */
    #define SHARD_PATHW 0x00000003

    #include <vlc_charset.h>
#endif

RecentsMRL::RecentsMRL( intf_thread_t *_p_intf ) : p_intf( _p_intf )
{
    stack = new QStringList;

    signalMapper = new QSignalMapper( this );
    CONNECT( signalMapper,
            mapped(const QString & ),
            this,
            playMRL( const QString & ) );

    /* Load the filter psz */
    char* psz_tmp = var_InheritString( p_intf, "qt-recentplay-filter" );
    if( psz_tmp && *psz_tmp )
        filter = new QRegExp( psz_tmp, Qt::CaseInsensitive );
    else
        filter = NULL;
    free( psz_tmp );

    load();
    isActive = var_InheritBool( p_intf, "qt-recentplay" );
    if( !isActive ) clear();
}

RecentsMRL::~RecentsMRL()
{
    save();
    delete filter;
    delete stack;
}

void RecentsMRL::addRecent( const QString &mrl )
{
    if ( !isActive || ( filter && filter->indexIn( mrl ) >= 0 ) )
        return;

#ifdef _WIN32
    /* Add to the Windows 7 default list in taskbar */
    char* path = make_path( qtu( mrl ) );
    if( path )
    {
        wchar_t *wmrl = ToWide( path );
        SHAddToRecentDocs( SHARD_PATHW, wmrl );
        free( wmrl );
        free( path );
    }
#endif

    int i_index = stack->indexOf( mrl );
    if( 0 <= i_index )
    {
        /* move to the front */
        stack->move( i_index, 0 );
    }
    else
    {
        stack->prepend( mrl );
        if( stack->count() > RECENTS_LIST_SIZE )
            stack->takeLast();
    }
    VLCMenuBar::updateRecents( p_intf );
    save();
}

void RecentsMRL::clear()
{
    if ( stack->isEmpty() )
        return;

    stack->clear();
    if( isActive ) VLCMenuBar::updateRecents( p_intf );
    save();
}

QStringList RecentsMRL::recents()
{
    return *stack;
}

void RecentsMRL::load()
{
    /* Load from the settings */
    QStringList list = getSettings()->value( "RecentsMRL/list" ).toStringList();

    /* And filter the regexp on the list */
    for( int i = 0; i < list.count(); ++i )
    {
        if ( !filter || filter->indexIn( list.at(i) ) == -1 )
            stack->append( list.at(i) );
    }
}

void RecentsMRL::save()
{
    getSettings()->setValue( "RecentsMRL/list", *stack );
}

playlist_item_t *RecentsMRL::toPlaylist(int length)
{
    playlist_item_t *p_node_recent = playlist_NodeCreate(THEPL, _("Recently Played"), THEPL->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL);

    if ( p_node_recent == NULL )  return NULL;

    if (length == 0 || stack->count() < length)
        length = stack->count();

    for (int i = 0; i < length; i++)
    {
        input_item_t *p_input = input_item_New(qtu(stack->at(i)), NULL);
        playlist_NodeAddInput(THEPL, p_input, p_node_recent, PLAYLIST_APPEND, PLAYLIST_END, false);
    }

    return p_node_recent;
}

void RecentsMRL::playMRL( const QString &mrl )
{
    Open::openMRL( p_intf, mrl );
}

int Open::openMRL( intf_thread_t *p_intf,
                    const QString &mrl,
                    bool b_start,
                    bool b_playlist)
{
    return openMRLwithOptions( p_intf, mrl, NULL, b_start, b_playlist );
}

int Open::openMRLwithOptions( intf_thread_t* p_intf,
                     const QString &mrl,
                     QStringList *options,
                     bool b_start,
                     bool b_playlist,
                     const char *title)
{
    /* Options */
    const char **ppsz_options = NULL;
    int i_options = 0;

    if( options != NULL && options->count() > 0 )
    {
        ppsz_options = (const char **)malloc( options->count() );
        if( ppsz_options ) {
            for( int j = 0; j < options->count(); j++ ) {
                QString option = colon_unescape( options->at(j) );
                if( !option.isEmpty() ) {
                    ppsz_options[j] = qtu(option);
                    i_options++;
                }
            }
        }
    }

    /* Add to playlist */
    int i_ret = playlist_AddExt( THEPL,
                  qtu(mrl), title,
                  PLAYLIST_APPEND | (b_start ? PLAYLIST_GO : PLAYLIST_PREPARSE),
                  PLAYLIST_END,
                  -1,
                  i_options, ppsz_options, VLC_INPUT_OPTION_TRUSTED,
                  b_playlist,
                  pl_Unlocked );

    /* Add to recent items, only if played */
    if( i_ret == VLC_SUCCESS && b_start && b_playlist )
        RecentsMRL::getInstance( p_intf )->addRecent( mrl );

    return i_ret;
}

<|endoftext|>


<commit_before>// $Id: elem_refinement.C,v 1.2 2003-05-29 15:54:06 benkirk Exp $

// The Next Great Finite Element Library.
// Copyright (C) 2002  Benjamin S. Kirk, John W. Peterson

// This library 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 2.1 of the License, or (at your option) any later version.

// This library 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 this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <algorithm>
#include <iterator>
#include <set>

// Local includes
#include "elem.h"
#include "mesh_base.h"

//--------------------------------------------------------------------
// Elem methods

/**
 * The following functions only apply when
 * AMR is enabled and thus are not present
 * otherwise.
 */
#ifdef ENABLE_AMR

void Elem::refine (MeshBase& mesh)
{
  assert (this->refinement_flag() == Elem::REFINE);
  assert (this->active());
  assert (_children == NULL);

  // Two big prime numbers less than
  // sqrt(max_unsigned_int) for key creation.
  const unsigned int bp1 = 65449;
  const unsigned int bp2 = 48661;

  // Create my children
  {
    _children = new Elem*[this->n_children()];

    for (unsigned int c=0; c<this->n_children(); c++)
      {
	_children[c] = Elem::build(this->type(), this);
	_children[c]->set_refinement_flag(Elem::JUST_REFINED);
      }
  }

  // Compute new nodal locations
  // and asssign nodes to children
  {
    // Make these static.  It is unlikely the
    // sizes will change from call to call, so having these
    // static should save on reallocations
    std::vector<std::vector<Point> >        p    (this->n_children());
    std::vector<std::vector<unsigned int> > keys (this->n_children());
    std::vector<std::vector<Node*> >        nodes(this->n_children());

    // compute new nodal locations
    for (unsigned int c=0; c<this->n_children(); c++)
      {
	p[c].resize    (this->child(c)->n_nodes());
	keys[c].resize (this->child(c)->n_nodes());
	nodes[c].resize(this->child(c)->n_nodes());

      for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	{
	  // zero entries
	  p[c][nc].zero();
	  keys[c][nc]  = 0;
	  nodes[c][nc] = NULL;

	  for (unsigned int n=0; n<this->n_nodes(); n++)
	    {
	      // The value from the embedding matrix
	      const float em_val = this->embedding_matrix(c,nc,n);

	      if (em_val != 0.)
		{
		  p[c][nc].add_scaled (this->point(n), em_val);

		  // We may have found the node, in which case we
		  // won't need to look it up later.
		  if (em_val == 1.)
		    nodes[c][nc] = this->get_node(n);

		  // Otherwise build the key to look for the node
		  else
		    {
		      // An unsigned int associated with the
		      // address of the node n.  We can't use the
		      // node number since they can change.
		      const unsigned int n_id =

#if SIZEOF_INT == SIZEOF_VOID_P

			// 32-bit machines
			reinterpret_cast<unsigned int>(this->get_node(n));

#elif SIZEOF_LONG_LONG_INT == SIZEOF_VOID_P

		        // 64-bit machines
 		        // Another big prime number less than max_unsigned_int
		        // for key creation on 64-bit machines
		        const unsigned int bp3 = 4294967291;
		        static_cast<long long unsigned int>(this->get_node(n))%
			bp3;

#else
			// Huh?
		        0; error();

#endif
		      // Compute the key for this new node nc.  This will
		      // be used to locate the node if it already exists
		      // in the mesh.
		      keys[c][nc] +=
			(((static_cast<unsigned int>(em_val*100000.)%bp1) *
			  (n_id%bp1))%bp1)*bp2;
		    }
		}
	    }
	}

      // assign nodes to children & add them to the mesh
      for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	{
	  if (nodes[c][nc] != NULL)
	    {
	      this->child(c)->set_node(nc) = nodes[c][nc];
	    }
	  else
	    {
	      this->child(c)->set_node(nc) =
		mesh.mesh_refinement.add_point(p[c][nc],
					       keys[c][nc]);
	    }
	}

	mesh.add_elem(this->child(c),
		      mesh.mesh_refinement.new_element_number());
      }
  }

  // Possibly add boundary information
  for (unsigned int s=0; s<this->n_neighbors(); s++)
    if (this->neighbor(s) == NULL)
      {
	const short int id = mesh.boundary_info.boundary_id(this, s);

	if (id != mesh.boundary_info.invalid_id)
	  for (unsigned int sc=0; sc<this->n_children_per_side(s); sc++)
	    mesh.boundary_info.add_side(this->child(this->side_children_matrix(s,sc)),
					s,
					id);
      }

  // Un-set my refinement flag now
  this->set_refinement_flag(Elem::DO_NOTHING);

  assert (!this->active());
}

void Elem::coarsen()
{
  assert (this->refinement_flag() == Elem::COARSEN);
  assert (!this->active());

  // Delete the storage for my children
  delete [] _children;

  _children = NULL;

  this->set_refinement_flag(Elem::DO_NOTHING);

  assert (this->active());
}

#endif // #ifdef ENABLE_AMR

<commit_msg>64-bit fix for SGI<commit_after>// $Id: elem_refinement.C,v 1.3 2003-05-29 16:58:49 benkirk Exp $

// The Next Great Finite Element Library.
// Copyright (C) 2002  Benjamin S. Kirk, John W. Peterson

// This library 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 2.1 of the License, or (at your option) any later version.

// This library 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 this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <algorithm>
#include <iterator>
#include <set>

// Local includes
#include "elem.h"
#include "mesh_base.h"

//--------------------------------------------------------------------
// Elem methods

/**
 * The following functions only apply when
 * AMR is enabled and thus are not present
 * otherwise.
 */
#ifdef ENABLE_AMR

void Elem::refine (MeshBase& mesh)
{
  assert (this->refinement_flag() == Elem::REFINE);
  assert (this->active());
  assert (_children == NULL);

  // Two big prime numbers less than
  // sqrt(max_unsigned_int) for key creation.
  const unsigned int bp1 = 65449;
  const unsigned int bp2 = 48661;

  // Create my children
  {
    _children = new Elem*[this->n_children()];

    for (unsigned int c=0; c<this->n_children(); c++)
      {
	_children[c] = Elem::build(this->type(), this);
	_children[c]->set_refinement_flag(Elem::JUST_REFINED);
      }
  }

  // Compute new nodal locations
  // and asssign nodes to children
  {
    // Make these static.  It is unlikely the
    // sizes will change from call to call, so having these
    // static should save on reallocations
    std::vector<std::vector<Point> >        p    (this->n_children());
    std::vector<std::vector<unsigned int> > keys (this->n_children());
    std::vector<std::vector<Node*> >        nodes(this->n_children());

    // compute new nodal locations
    for (unsigned int c=0; c<this->n_children(); c++)
      {
	p[c].resize    (this->child(c)->n_nodes());
	keys[c].resize (this->child(c)->n_nodes());
	nodes[c].resize(this->child(c)->n_nodes());

      for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	{
	  // zero entries
	  p[c][nc].zero();
	  keys[c][nc]  = 0;
	  nodes[c][nc] = NULL;

	  for (unsigned int n=0; n<this->n_nodes(); n++)
	    {
	      // The value from the embedding matrix
	      const float em_val = this->embedding_matrix(c,nc,n);

	      if (em_val != 0.)
		{
		  p[c][nc].add_scaled (this->point(n), em_val);

		  // We may have found the node, in which case we
		  // won't need to look it up later.
		  if (em_val == 1.)
		    nodes[c][nc] = this->get_node(n);

		  // Otherwise build the key to look for the node
		  else
		    {
		      // An unsigned int associated with the
		      // address of the node n.  We can't use the
		      // node number since they can change.

#if SIZEOF_INT == SIZEOF_VOID_P

		      // 32-bit machines
		      const unsigned int n_id =
			reinterpret_cast<unsigned int>(this->get_node(n));

#elif SIZEOF_LONG_LONG_INT == SIZEOF_VOID_P

		      // 64-bit machines
		      // Another big prime number less than max_unsigned_int
		      // for key creation on 64-bit machines
		      const unsigned int bp3 = 4294967291;
		      const unsigned int n_id =
		        reinterpret_cast<long long unsigned int>(this->get_node(n))%bp3;

#else
		      // Huh?
		      DIE HERE...  CANNOT COMPILE

#endif
		      // Compute the key for this new node nc.  This will
		      // be used to locate the node if it already exists
		      // in the mesh.
			keys[c][nc] +=
			(((static_cast<unsigned int>(em_val*100000.)%bp1) *
			  (n_id%bp1))%bp1)*bp2;
		    }
		}
	    }
	}

      // assign nodes to children & add them to the mesh
      for (unsigned int nc=0; nc<this->child(c)->n_nodes(); nc++)
	{
	  if (nodes[c][nc] != NULL)
	    {
	      this->child(c)->set_node(nc) = nodes[c][nc];
	    }
	  else
	    {
	      this->child(c)->set_node(nc) =
		mesh.mesh_refinement.add_point(p[c][nc],
					       keys[c][nc]);
	    }
	}

	mesh.add_elem(this->child(c),
		      mesh.mesh_refinement.new_element_number());
      }
  }

  // Possibly add boundary information
  for (unsigned int s=0; s<this->n_neighbors(); s++)
    if (this->neighbor(s) == NULL)
      {
	const short int id = mesh.boundary_info.boundary_id(this, s);

	if (id != mesh.boundary_info.invalid_id)
	  for (unsigned int sc=0; sc<this->n_children_per_side(s); sc++)
	    mesh.boundary_info.add_side(this->child(this->side_children_matrix(s,sc)),
					s,
					id);
      }

  // Un-set my refinement flag now
  this->set_refinement_flag(Elem::DO_NOTHING);

  assert (!this->active());
}

void Elem::coarsen()
{
  assert (this->refinement_flag() == Elem::COARSEN);
  assert (!this->active());

  // Delete the storage for my children
  delete [] _children;

  _children = NULL;

  this->set_refinement_flag(Elem::DO_NOTHING);

  assert (this->active());
}

#endif // #ifdef ENABLE_AMR

<|endoftext|>