<commit_before>// @(#)root/meta:$Name:  $:$Id: TGenericClassInfo.cxx,v 1.18 2007/02/01 21:59:28 pcanal Exp $
// Author: Philippe Canal 08/05/2002

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

#include "TROOT.h"
#include "TClass.h"
#include "TVirtualStreamerInfo.h"
#include "TStreamer.h"
#include "TVirtualIsAProxy.h"
#include "TVirtualCollectionProxy.h"
#include "TCollectionProxyInfo.h"

namespace ROOT {

   const TInitBehavior *DefineBehavior(void * /*parent_type*/,
                                       void * /*actual_type*/)
   {

      // This function loads the default behavior for the
      // loading of classes.

      static TDefaultInitBehavior theDefault;
      return &theDefault;
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        void *showmembers, VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(showmembers),
        fVersion(1),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof)
   {
      // Constructor.

      Init(pragmabits);
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        void* showmembers,  VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(showmembers),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
   {
      // Constructor with version number.

      Init(pragmabits);
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(0),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)

   {
      // Constructor with version number and no showmembers.

      Init(pragmabits);
   }

   class TForNamespace {}; // Dummy class to give a typeid to namespace (See also TClassTable.cc)

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const TInitBehavior  *action,
                                        VoidFuncPtr_t dictionary, Int_t pragmabits)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(typeid(TForNamespace)),
        fImplFileName(0), fImplFileLine(0),
        fIsA(0), fShowMembers(0),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(0),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)

   {
      // Constructor for namespace

      Init(pragmabits);
   }

  /*  TGenericClassInfo::TGenericClassInfo(const TGenericClassInfo& gci) :
    fAction(gci.fAction),
    fClass(gci.fClass),
    fClassName(gci.fClassName),
    fDeclFileName(gci.fDeclFileName),
    fDeclFileLine(gci.fDeclFileLine),
    fDictionary(gci.fDictionary),
    fInfo(gci.fInfo),
    fImplFileName(gci.fImplFileName),
    fImplFileLine(gci.fImplFileLine),
    fIsA(gci.fIsA),
    fShowMembers(gci.fShowMembers),
    fVersion(gci.fVersion),
    fNew(gci.fNew),
    fNewArray(gci.fNewArray),
    fDelete(gci.fDelete),
    fDeleteArray(gci.fDeleteArray),
    fDestructor(gci.fDestructor),
    fStreamer(gci.fStreamer),
    fCollectionProxy(gci.fCollectionProxy),
    fSizeof(gci.fSizeof)
   { }

  TGenericClassInfo& TGenericClassInfo::operator=(const TGenericClassInfo& gci)
   {
     if(this!=&gci) {
       fAction=gci.fAction;
       fClass=gci.fClass;
       fClassName=gci.fClassName;
       fDeclFileName=gci.fDeclFileName;
       fDeclFileLine=gci.fDeclFileLine;
       fDictionary=gci.fDictionary;
       fInfo=gci.fInfo;
       fImplFileName=gci.fImplFileName;
       fImplFileLine=gci.fImplFileLine;
       fIsA=gci.fIsA;
       fShowMembers=gci.fShowMembers;
       fVersion=gci.fVersion;
       fNew=gci.fNew;
       fNewArray=gci.fNewArray;
       fDelete=gci.fDelete;
       fDeleteArray=gci.fDeleteArray;
       fDestructor=gci.fDestructor;
       fStreamer=gci.fStreamer;
       fCollectionProxy=gci.fCollectionProxy;
       fSizeof=gci.fSizeof;
     } return *this;
   }
  */

   void TGenericClassInfo::Init(Int_t pragmabits)
   {
      // Initilization routine.

      //TVirtualStreamerInfo::Class_Version MUST be the same as TStreamerInfo::Class_Version
      if (fVersion==-2) fVersion = TVirtualStreamerInfo::Class_Version();
      if (!fAction) return;
      GetAction().Register(fClassName,
                           fVersion,
                           fInfo, // typeid(RootClass),
                           fDictionary,
                           pragmabits);
   }

   TGenericClassInfo::~TGenericClassInfo()
   {
      // Destructor.

      delete fCollectionProxyInfo;
      delete fCollectionStreamerInfo;
      if (!fClass) delete fIsA; // fIsA is adopted by the class if any.
      fIsA = 0;
      if (!gROOT) return;
      if (fAction) GetAction().Unregister(GetClassName());
   }

   const TInitBehavior &TGenericClassInfo::GetAction() const
   {
      // Return the creator action.

      return *fAction;
   }

   TClass *TGenericClassInfo::GetClass()
   {
      // Generate and return the TClass object.

      if (!fClass && fAction) {
         fClass = GetAction().CreateClass(GetClassName(),
                                          GetVersion(),
                                          GetInfo(),
                                          GetIsA(),
                                          (ShowMembersFunc_t)GetShowMembers(),
                                          GetDeclFileName(),
                                          GetImplFileName(),
                                          GetDeclFileLine(),
                                          GetImplFileLine());
         fClass->SetNew(fNew);
         fClass->SetNewArray(fNewArray);
         fClass->SetDelete(fDelete);
         fClass->SetDeleteArray(fDeleteArray);
         fClass->SetDestructor(fDestructor);
         fClass->AdoptStreamer(fStreamer); fStreamer = 0;
         // If IsZombie is true, something went wront and we will not be
         // able to properly copy the collection proxy
         if (!fClass->IsZombie()) {
            if (fCollectionProxy) fClass->CopyCollectionProxy(*fCollectionProxy);
            else if (fCollectionProxyInfo) {
               fClass->SetCollectionProxy(*fCollectionProxyInfo);
            }
         }
         fClass->SetClassSize(fSizeof);
      }
      return fClass;
   }

   const char *TGenericClassInfo::GetClassName() const
   {
      // Return the class name

      return fClassName;
   }

   TCollectionProxyInfo *TGenericClassInfo::GetCollectionProxyInfo() const
   {
      // Return the set of info we have for the CollectionProxy, if any

      return fCollectionProxyInfo;
   }

   TCollectionProxyInfo *TGenericClassInfo::GetCollectionStreamerInfo() const
   {
      // Return the set of info we have for the Collection Streamer, if any

      return fCollectionProxyInfo;
   }

   const type_info &TGenericClassInfo::GetInfo() const
   {
      // Return the typeifno value

      return fInfo;
   }

   void *TGenericClassInfo::GetShowMembers() const
   {
      // Return the point of the ShowMembers function
      return fShowMembers;
   }

   void TGenericClassInfo::SetFromTemplate()
   {
      // Import the information from the class template.

      TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0);
      if (info) SetImplFile(info->GetTitle(), info->GetUniqueID());
   }

   Int_t TGenericClassInfo::SetImplFile(const char *file, Int_t line)
   {
      // Set the name of the implementation file.

      fImplFileName = file;
      fImplFileLine = line;
      if (fClass) fClass->AddImplFile(file,line);
      return 0;
   }

   Int_t TGenericClassInfo::SetDeclFile(const char *file, Int_t line)
   {
      // Set the name of the declaration file.

      fDeclFileName = file;
      fDeclFileLine = line;
      if (fClass) fClass->SetDeclFile(file,line);
      return 0;
   }

   Short_t TGenericClassInfo::SetVersion(Short_t version)
   {
      // Set a class version number.

      ROOT::ResetClassVersion(fClass, GetClassName(),version);
      fVersion = version;
      return version;
   }

   void TGenericClassInfo::AdoptCollectionProxyInfo(TCollectionProxyInfo *info)
   {
      // Set the info for the CollectionProxy

      fCollectionProxyInfo = info;
   }

   void TGenericClassInfo::AdoptCollectionStreamerInfo(TCollectionProxyInfo *info)
   {
      // Set the info for the Collection Streamer

      fCollectionProxyInfo = info;
   }

   Short_t TGenericClassInfo::AdoptStreamer(TClassStreamer *streamer)
   {
      // Set a Streamer object.  The streamer object is now 'owned'
      // by the TGenericClassInfo.

      delete fStreamer; fStreamer = 0;
      if (fClass) {
         fClass->AdoptStreamer(streamer);
      } else {
         fStreamer = streamer;
      }
      return 0;
   }

   Short_t TGenericClassInfo::AdoptCollectionProxy(TVirtualCollectionProxy *collProxy)
   {
      // Set the CollectProxy object.  The CollectionProxy object is now 'owned'
      // by the TGenericClassInfo.

      delete fCollectionProxy; fCollectionProxy = 0;
      fCollectionProxy = collProxy;
      if (fClass && fCollectionProxy && !fClass->IsZombie()) {
         fClass->CopyCollectionProxy(*fCollectionProxy);
      }
      return 0;
   }

   Short_t TGenericClassInfo::SetStreamer(ClassStreamerFunc_t streamer)
   {
      // Set a Streamer function.

      delete fStreamer; fStreamer = 0;
      if (fClass) {
         fClass->AdoptStreamer(new TClassStreamer(streamer));
      } else {
         fStreamer = new TClassStreamer(streamer);
      }
      return 0;
   }

   const char *TGenericClassInfo::GetDeclFileName() const
   {
      // Get the name of the declaring header file.

      return fDeclFileName;
   }

   Int_t TGenericClassInfo::GetDeclFileLine() const
   {
      // Get the declaring line number.

      return fDeclFileLine;
   }

   const char *TGenericClassInfo::GetImplFileName()
   {
      // Get the implementation filename.

      if (!fImplFileName) SetFromTemplate();
      return fImplFileName;
   }

   Int_t TGenericClassInfo::GetImplFileLine()
   {
      // Get the ClassImp line number.

      if (!fImplFileLine) SetFromTemplate();
      return fImplFileLine;
   }

   Int_t TGenericClassInfo::GetVersion() const
   {
      // Return the class version number.

      return fVersion;
   }

   TClass *TGenericClassInfo::IsA(const void *obj)
   {
      // Return the actual type of the object.

      return (*GetIsA())(obj);
   }

   TVirtualIsAProxy* TGenericClassInfo::GetIsA() const
   {
      // Return the IsA proxy.

      return fIsA;
   }

   void TGenericClassInfo::SetNew(NewFunc_t newFunc)
   {
      // Install a new wrapper around 'new'.

      fNew = newFunc;
      if (fClass) fClass->SetNew(fNew);
   }

   void TGenericClassInfo::SetNewArray(NewArrFunc_t newArrayFunc)
   {
      // Install a new wrapper around 'new []'.

      fNewArray = newArrayFunc;
      if (fClass) fClass->SetNewArray(fNewArray);
   }

   void TGenericClassInfo::SetDelete(DelFunc_t deleteFunc)
   {
      // Install a new wrapper around 'delete'.

      fDelete = deleteFunc;
      if (fClass) fClass->SetDelete(fDelete);
   }

   void TGenericClassInfo::SetDeleteArray(DelArrFunc_t deleteArrayFunc)
   {
      // Install a new wrapper around 'delete []'.

      fDeleteArray = deleteArrayFunc;
      if (fClass) fClass->SetDeleteArray(fDeleteArray);
   }

   void TGenericClassInfo::SetDestructor(DesFunc_t destructorFunc)
   {
      // Install a new wrapper around the destructor.

      fDestructor = destructorFunc;
      if (fClass) fClass->SetDestructor(fDestructor);
   }

   NewFunc_t TGenericClassInfo::GetNew() const
   {
      // Get the wrapper around 'new'.

      return fNew;
   }

   NewArrFunc_t TGenericClassInfo::GetNewArray() const
   {
      // Get the wrapper around 'new []'.

      return fNewArray;
   }

   DelFunc_t TGenericClassInfo::GetDelete() const
   {
      // Get the wrapper around 'delete'.

      return fDelete;
   }

   DelArrFunc_t TGenericClassInfo::GetDeleteArray() const
   {
      // Get the wrapper around 'delete []'.

      return fDeleteArray;
   }

   DesFunc_t TGenericClassInfo::GetDestructor() const
   {
      // Get the wrapper around the destructor.

      return fDestructor;
   }

}
<commit_msg>From Philippe: Fix a problem affecting SEAL, cintex/ROOTClassEnhancer.cxx reported by Pere.<commit_after>// @(#)root/meta:$Name:  $:$Id: TGenericClassInfo.cxx,v 1.19 2007/02/05 18:11:00 brun Exp $
// Author: Philippe Canal 08/05/2002

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

#include "TROOT.h"
#include "TClass.h"
#include "TVirtualStreamerInfo.h"
#include "TStreamer.h"
#include "TVirtualIsAProxy.h"
#include "TVirtualCollectionProxy.h"
#include "TCollectionProxyInfo.h"

namespace ROOT {

   const TInitBehavior *DefineBehavior(void * /*parent_type*/,
                                       void * /*actual_type*/)
   {

      // This function loads the default behavior for the
      // loading of classes.

      static TDefaultInitBehavior theDefault;
      return &theDefault;
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        void *showmembers, VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(showmembers),
        fVersion(1),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
   {
      // Constructor.

      Init(pragmabits);
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        void* showmembers,  VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(showmembers),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)
   {
      // Constructor with version number.

      Init(pragmabits);
   }

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const type_info &info, const TInitBehavior  *action,
                                        VoidFuncPtr_t dictionary,
                                        TVirtualIsAProxy *isa, Int_t pragmabits, Int_t sizof)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(info),
        fImplFileName(0), fImplFileLine(0),
        fIsA(isa), fShowMembers(0),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(sizof),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)

   {
      // Constructor with version number and no showmembers.

      Init(pragmabits);
   }

   class TForNamespace {}; // Dummy class to give a typeid to namespace (See also TClassTable.cc)

   TGenericClassInfo::TGenericClassInfo(const char *fullClassname, Int_t version,
                                        const char *declFileName, Int_t declFileLine,
                                        const TInitBehavior  *action,
                                        VoidFuncPtr_t dictionary, Int_t pragmabits)
      : fAction(action), fClass(0), fClassName(fullClassname),
        fDeclFileName(declFileName), fDeclFileLine(declFileLine),
        fDictionary(dictionary), fInfo(typeid(TForNamespace)),
        fImplFileName(0), fImplFileLine(0),
        fIsA(0), fShowMembers(0),
        fVersion(version),
        fNew(0),fNewArray(0),fDelete(0),fDeleteArray(0),fDestructor(0), fStreamer(0),
        fCollectionProxy(0), fSizeof(0),
        fCollectionProxyInfo(0), fCollectionStreamerInfo(0)

   {
      // Constructor for namespace

      Init(pragmabits);
   }

  /*  TGenericClassInfo::TGenericClassInfo(const TGenericClassInfo& gci) :
    fAction(gci.fAction),
    fClass(gci.fClass),
    fClassName(gci.fClassName),
    fDeclFileName(gci.fDeclFileName),
    fDeclFileLine(gci.fDeclFileLine),
    fDictionary(gci.fDictionary),
    fInfo(gci.fInfo),
    fImplFileName(gci.fImplFileName),
    fImplFileLine(gci.fImplFileLine),
    fIsA(gci.fIsA),
    fShowMembers(gci.fShowMembers),
    fVersion(gci.fVersion),
    fNew(gci.fNew),
    fNewArray(gci.fNewArray),
    fDelete(gci.fDelete),
    fDeleteArray(gci.fDeleteArray),
    fDestructor(gci.fDestructor),
    fStreamer(gci.fStreamer),
    fCollectionProxy(gci.fCollectionProxy),
    fSizeof(gci.fSizeof)
   { }

  TGenericClassInfo& TGenericClassInfo::operator=(const TGenericClassInfo& gci)
   {
     if(this!=&gci) {
       fAction=gci.fAction;
       fClass=gci.fClass;
       fClassName=gci.fClassName;
       fDeclFileName=gci.fDeclFileName;
       fDeclFileLine=gci.fDeclFileLine;
       fDictionary=gci.fDictionary;
       fInfo=gci.fInfo;
       fImplFileName=gci.fImplFileName;
       fImplFileLine=gci.fImplFileLine;
       fIsA=gci.fIsA;
       fShowMembers=gci.fShowMembers;
       fVersion=gci.fVersion;
       fNew=gci.fNew;
       fNewArray=gci.fNewArray;
       fDelete=gci.fDelete;
       fDeleteArray=gci.fDeleteArray;
       fDestructor=gci.fDestructor;
       fStreamer=gci.fStreamer;
       fCollectionProxy=gci.fCollectionProxy;
       fSizeof=gci.fSizeof;
     } return *this;
   }
  */

   void TGenericClassInfo::Init(Int_t pragmabits)
   {
      // Initilization routine.

      //TVirtualStreamerInfo::Class_Version MUST be the same as TStreamerInfo::Class_Version
      if (fVersion==-2) fVersion = TVirtualStreamerInfo::Class_Version();
      if (!fAction) return;
      GetAction().Register(fClassName,
                           fVersion,
                           fInfo, // typeid(RootClass),
                           fDictionary,
                           pragmabits);
   }

   TGenericClassInfo::~TGenericClassInfo()
   {
      // Destructor.

      delete fCollectionProxyInfo;
      delete fCollectionStreamerInfo;
      if (!fClass) delete fIsA; // fIsA is adopted by the class if any.
      fIsA = 0;
      if (!gROOT) return;
      if (fAction) GetAction().Unregister(GetClassName());
   }

   const TInitBehavior &TGenericClassInfo::GetAction() const
   {
      // Return the creator action.

      return *fAction;
   }

   TClass *TGenericClassInfo::GetClass()
   {
      // Generate and return the TClass object.

      if (!fClass && fAction) {
         fClass = GetAction().CreateClass(GetClassName(),
                                          GetVersion(),
                                          GetInfo(),
                                          GetIsA(),
                                          (ShowMembersFunc_t)GetShowMembers(),
                                          GetDeclFileName(),
                                          GetImplFileName(),
                                          GetDeclFileLine(),
                                          GetImplFileLine());
         fClass->SetNew(fNew);
         fClass->SetNewArray(fNewArray);
         fClass->SetDelete(fDelete);
         fClass->SetDeleteArray(fDeleteArray);
         fClass->SetDestructor(fDestructor);
         fClass->AdoptStreamer(fStreamer); fStreamer = 0;
         // If IsZombie is true, something went wront and we will not be
         // able to properly copy the collection proxy
         if (!fClass->IsZombie()) {
            if (fCollectionProxy) fClass->CopyCollectionProxy(*fCollectionProxy);
            else if (fCollectionProxyInfo) {
               fClass->SetCollectionProxy(*fCollectionProxyInfo);
            }
         }
         fClass->SetClassSize(fSizeof);
      }
      return fClass;
   }

   const char *TGenericClassInfo::GetClassName() const
   {
      // Return the class name

      return fClassName;
   }

   TCollectionProxyInfo *TGenericClassInfo::GetCollectionProxyInfo() const
   {
      // Return the set of info we have for the CollectionProxy, if any

      return fCollectionProxyInfo;
   }

   TCollectionProxyInfo *TGenericClassInfo::GetCollectionStreamerInfo() const
   {
      // Return the set of info we have for the Collection Streamer, if any

      return fCollectionProxyInfo;
   }

   const type_info &TGenericClassInfo::GetInfo() const
   {
      // Return the typeifno value

      return fInfo;
   }

   void *TGenericClassInfo::GetShowMembers() const
   {
      // Return the point of the ShowMembers function
      return fShowMembers;
   }

   void TGenericClassInfo::SetFromTemplate()
   {
      // Import the information from the class template.

      TNamed *info = ROOT::RegisterClassTemplate(GetClassName(), 0, 0);
      if (info) SetImplFile(info->GetTitle(), info->GetUniqueID());
   }

   Int_t TGenericClassInfo::SetImplFile(const char *file, Int_t line)
   {
      // Set the name of the implementation file.

      fImplFileName = file;
      fImplFileLine = line;
      if (fClass) fClass->AddImplFile(file,line);
      return 0;
   }

   Int_t TGenericClassInfo::SetDeclFile(const char *file, Int_t line)
   {
      // Set the name of the declaration file.

      fDeclFileName = file;
      fDeclFileLine = line;
      if (fClass) fClass->SetDeclFile(file,line);
      return 0;
   }

   Short_t TGenericClassInfo::SetVersion(Short_t version)
   {
      // Set a class version number.

      ROOT::ResetClassVersion(fClass, GetClassName(),version);
      fVersion = version;
      return version;
   }

   void TGenericClassInfo::AdoptCollectionProxyInfo(TCollectionProxyInfo *info)
   {
      // Set the info for the CollectionProxy

      fCollectionProxyInfo = info;
   }

   void TGenericClassInfo::AdoptCollectionStreamerInfo(TCollectionProxyInfo *info)
   {
      // Set the info for the Collection Streamer

      fCollectionProxyInfo = info;
   }

   Short_t TGenericClassInfo::AdoptStreamer(TClassStreamer *streamer)
   {
      // Set a Streamer object.  The streamer object is now 'owned'
      // by the TGenericClassInfo.

      delete fStreamer; fStreamer = 0;
      if (fClass) {
         fClass->AdoptStreamer(streamer);
      } else {
         fStreamer = streamer;
      }
      return 0;
   }

   Short_t TGenericClassInfo::AdoptCollectionProxy(TVirtualCollectionProxy *collProxy)
   {
      // Set the CollectProxy object.  The CollectionProxy object is now 'owned'
      // by the TGenericClassInfo.

      delete fCollectionProxy; fCollectionProxy = 0;
      fCollectionProxy = collProxy;
      if (fClass && fCollectionProxy && !fClass->IsZombie()) {
         fClass->CopyCollectionProxy(*fCollectionProxy);
      }
      return 0;
   }

   Short_t TGenericClassInfo::SetStreamer(ClassStreamerFunc_t streamer)
   {
      // Set a Streamer function.

      delete fStreamer; fStreamer = 0;
      if (fClass) {
         fClass->AdoptStreamer(new TClassStreamer(streamer));
      } else {
         fStreamer = new TClassStreamer(streamer);
      }
      return 0;
   }

   const char *TGenericClassInfo::GetDeclFileName() const
   {
      // Get the name of the declaring header file.

      return fDeclFileName;
   }

   Int_t TGenericClassInfo::GetDeclFileLine() const
   {
      // Get the declaring line number.

      return fDeclFileLine;
   }

   const char *TGenericClassInfo::GetImplFileName()
   {
      // Get the implementation filename.

      if (!fImplFileName) SetFromTemplate();
      return fImplFileName;
   }

   Int_t TGenericClassInfo::GetImplFileLine()
   {
      // Get the ClassImp line number.

      if (!fImplFileLine) SetFromTemplate();
      return fImplFileLine;
   }

   Int_t TGenericClassInfo::GetVersion() const
   {
      // Return the class version number.

      return fVersion;
   }

   TClass *TGenericClassInfo::IsA(const void *obj)
   {
      // Return the actual type of the object.

      return (*GetIsA())(obj);
   }

   TVirtualIsAProxy* TGenericClassInfo::GetIsA() const
   {
      // Return the IsA proxy.

      return fIsA;
   }

   void TGenericClassInfo::SetNew(NewFunc_t newFunc)
   {
      // Install a new wrapper around 'new'.

      fNew = newFunc;
      if (fClass) fClass->SetNew(fNew);
   }

   void TGenericClassInfo::SetNewArray(NewArrFunc_t newArrayFunc)
   {
      // Install a new wrapper around 'new []'.

      fNewArray = newArrayFunc;
      if (fClass) fClass->SetNewArray(fNewArray);
   }

   void TGenericClassInfo::SetDelete(DelFunc_t deleteFunc)
   {
      // Install a new wrapper around 'delete'.

      fDelete = deleteFunc;
      if (fClass) fClass->SetDelete(fDelete);
   }

   void TGenericClassInfo::SetDeleteArray(DelArrFunc_t deleteArrayFunc)
   {
      // Install a new wrapper around 'delete []'.

      fDeleteArray = deleteArrayFunc;
      if (fClass) fClass->SetDeleteArray(fDeleteArray);
   }

   void TGenericClassInfo::SetDestructor(DesFunc_t destructorFunc)
   {
      // Install a new wrapper around the destructor.

      fDestructor = destructorFunc;
      if (fClass) fClass->SetDestructor(fDestructor);
   }

   NewFunc_t TGenericClassInfo::GetNew() const
   {
      // Get the wrapper around 'new'.

      return fNew;
   }

   NewArrFunc_t TGenericClassInfo::GetNewArray() const
   {
      // Get the wrapper around 'new []'.

      return fNewArray;
   }

   DelFunc_t TGenericClassInfo::GetDelete() const
   {
      // Get the wrapper around 'delete'.

      return fDelete;
   }

   DelArrFunc_t TGenericClassInfo::GetDeleteArray() const
   {
      // Get the wrapper around 'delete []'.

      return fDeleteArray;
   }

   DesFunc_t TGenericClassInfo::GetDestructor() const
   {
      // Get the wrapper around the destructor.

      return fDestructor;
   }

}
<|endoftext|>


<commit_before>/*
 *  lineedit.cpp  -  Line edit widget with extra drag and drop options
 *  Program:  kalarm
 *  Copyright © 2003-2005,2009 by David Jarvie <djarvie@kde.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 "kalarm.h"
#include "lineedit.moc"

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kvcarddrag.h>
#include <kcal/icaldrag.h>

#include <kurl.h>
#include <kurlcompletion.h>
#include <kshell.h>

#include <QRegExp>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFocusEvent>

/*=============================================================================
= Class LineEdit
= Line edit which accepts drag and drop of text, URLs and/or email addresses.
* It has an option to prevent its contents being selected when it receives
= focus.
=============================================================================*/
LineEdit::LineEdit(Type type, QWidget* parent)
	: KLineEdit(parent),
	  mType(type),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

LineEdit::LineEdit(QWidget* parent)
	: KLineEdit(parent),
	  mType(Text),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

void LineEdit::init()
{
	if (mType == Url)
	{
		setCompletionMode(KGlobalSettings::CompletionShell);
		KUrlCompletion* comp = new KUrlCompletion(KUrlCompletion::FileCompletion);
		comp->setReplaceHome(true);
		setCompletionObject(comp);
		setAutoDeleteCompletionObject(true);
	}
	else
		setCompletionMode(KGlobalSettings::CompletionNone);
}

/******************************************************************************
*  Called when the line edit receives focus.
*  If 'noSelect' is true, prevent the contents being selected.
*/
void LineEdit::focusInEvent(QFocusEvent* e)
{
	QFocusEvent newe(QEvent::FocusIn, (mNoSelect ? Qt::OtherFocusReason : e->reason()));
	KLineEdit::focusInEvent(&newe);
	mNoSelect = false;
}

QString LineEdit::text() const
{
	if (mType == Url)
		return KShell::tildeExpand(QLineEdit::text());
	return QLineEdit::text();
}

void LineEdit::setText(const QString& text)
{
	KLineEdit::setText(text);
	setCursorPosition(mSetCursorAtEnd ? text.length() : 0);
}

void LineEdit::dragEnterEvent(QDragEnterEvent* e)
{
	const QMimeData* data = e->mimeData();
	bool ok;
	if (KCal::ICalDrag::canDecode(data))
		ok = false;   // don't accept "text/calendar" objects
	else
		ok = (data->hasText()
		   || KUrl::List::canDecode(data)
		   || (mType != Url && KPIM::MailList::canDecode(data))
		   || (mType == Emails && KPIM::KVCardDrag::canDecode(data)));
	if (ok)
		e->accept(rect());
	else
		e->ignore(rect());
}

void LineEdit::dropEvent(QDropEvent* e)
{
	const QMimeData* data = e->mimeData();
	QString               newText;
	QStringList           newEmails;
	KUrl::List            files;
	KABC::Addressee::List addrList;

	if (mType != Url
	&&  KPIM::MailList::canDecode(data))
	{
		KPIM::MailList mailList = KPIM::MailList::fromMimeData(data);
		// KMail message(s) - ignore all but the first
		if (mailList.count())
		{
			if (mType == Emails)
				newText = mailList.first().from();
			else
				setText(mailList.first().subject());    // replace any existing text
		}
	}
	// This must come before KUrl
	else if (mType == Emails
	&&  KPIM::KVCardDrag::canDecode(data)  &&  KPIM::KVCardDrag::fromMimeData(data, addrList))
	{
		// KAddressBook entries
		for (KABC::Addressee::List::Iterator it = addrList.begin();  it != addrList.end();  ++it)
		{
			QString em((*it).fullEmail());
			if (!em.isEmpty())
				newEmails.append(em);
		}
	}
	else if (!(files = KUrl::List::fromMimeData(data)).isEmpty())
	{
		// URL(s)
		switch (mType)
		{
			case Url:
				// URL entry field - ignore all but the first dropped URL
				setText(files.first().prettyUrl());    // replace any existing text
				break;
			case Emails:
			{
				// Email entry field - ignore all but mailto: URLs
				QString mailto = QLatin1String("mailto");
				for (KUrl::List::Iterator it = files.begin();  it != files.end();  ++it)
				{
					if ((*it).protocol() == mailto)
						newEmails.append((*it).path());
				}
				break;
			}
			case Text:
				newText = files.first().prettyUrl();
				break;
		}
	}
	else if (data->hasText())
	{
		// Plain text
		QString txt = data->text();
		if (mType == Emails)
		{
			// Remove newlines from a list of email addresses, and allow an eventual mailto: protocol
			QString mailto = QLatin1String("mailto:");
			newEmails = txt.split(QRegExp("[\r\n]+"), QString::SkipEmptyParts);
			for (QStringList::Iterator it = newEmails.begin();  it != newEmails.end();  ++it)
			{
				if ((*it).startsWith(mailto))
				{
					KUrl url(*it);
					*it = url.path();
				}
			}
		}
		else
		{
			int newline = txt.indexOf(QLatin1Char('\n'));
			newText = (newline >= 0) ? txt.left(newline) : txt;
		}
	}

	if (newEmails.count())
	{
		newText = newEmails.join(",");
		int c = cursorPosition();
		if (c > 0)
			newText.prepend(",");
		if (c < static_cast<int>(text().length()))
			newText.append(",");
	}
	if (!newText.isEmpty())
		insert(newText);
}
<commit_msg>Fix parent class reference<commit_after>/*
 *  lineedit.cpp  -  Line edit widget with extra drag and drop options
 *  Program:  kalarm
 *  Copyright © 2003-2005,2009 by David Jarvie <djarvie@kde.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 "kalarm.h"
#include "lineedit.moc"

#include <libkdepim/maillistdrag.h>
#include <libkdepim/kvcarddrag.h>
#include <kcal/icaldrag.h>

#include <kurl.h>
#include <kurlcompletion.h>
#include <kshell.h>

#include <QRegExp>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFocusEvent>

/*=============================================================================
= Class LineEdit
= Line edit which accepts drag and drop of text, URLs and/or email addresses.
* It has an option to prevent its contents being selected when it receives
= focus.
=============================================================================*/
LineEdit::LineEdit(Type type, QWidget* parent)
	: KLineEdit(parent),
	  mType(type),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

LineEdit::LineEdit(QWidget* parent)
	: KLineEdit(parent),
	  mType(Text),
	  mNoSelect(false),
	  mSetCursorAtEnd(false)
{
	init();
}

void LineEdit::init()
{
	if (mType == Url)
	{
		setCompletionMode(KGlobalSettings::CompletionShell);
		KUrlCompletion* comp = new KUrlCompletion(KUrlCompletion::FileCompletion);
		comp->setReplaceHome(true);
		setCompletionObject(comp);
		setAutoDeleteCompletionObject(true);
	}
	else
		setCompletionMode(KGlobalSettings::CompletionNone);
}

/******************************************************************************
*  Called when the line edit receives focus.
*  If 'noSelect' is true, prevent the contents being selected.
*/
void LineEdit::focusInEvent(QFocusEvent* e)
{
	QFocusEvent newe(QEvent::FocusIn, (mNoSelect ? Qt::OtherFocusReason : e->reason()));
	KLineEdit::focusInEvent(&newe);
	mNoSelect = false;
}

QString LineEdit::text() const
{
	if (mType == Url)
		return KShell::tildeExpand(KLineEdit::text());
	return KLineEdit::text();
}

void LineEdit::setText(const QString& text)
{
	KLineEdit::setText(text);
	setCursorPosition(mSetCursorAtEnd ? text.length() : 0);
}

void LineEdit::dragEnterEvent(QDragEnterEvent* e)
{
	const QMimeData* data = e->mimeData();
	bool ok;
	if (KCal::ICalDrag::canDecode(data))
		ok = false;   // don't accept "text/calendar" objects
	else
		ok = (data->hasText()
		   || KUrl::List::canDecode(data)
		   || (mType != Url && KPIM::MailList::canDecode(data))
		   || (mType == Emails && KPIM::KVCardDrag::canDecode(data)));
	if (ok)
		e->accept(rect());
	else
		e->ignore(rect());
}

void LineEdit::dropEvent(QDropEvent* e)
{
	const QMimeData* data = e->mimeData();
	QString               newText;
	QStringList           newEmails;
	KUrl::List            files;
	KABC::Addressee::List addrList;

	if (mType != Url
	&&  KPIM::MailList::canDecode(data))
	{
		KPIM::MailList mailList = KPIM::MailList::fromMimeData(data);
		// KMail message(s) - ignore all but the first
		if (mailList.count())
		{
			if (mType == Emails)
				newText = mailList.first().from();
			else
				setText(mailList.first().subject());    // replace any existing text
		}
	}
	// This must come before KUrl
	else if (mType == Emails
	&&  KPIM::KVCardDrag::canDecode(data)  &&  KPIM::KVCardDrag::fromMimeData(data, addrList))
	{
		// KAddressBook entries
		for (KABC::Addressee::List::Iterator it = addrList.begin();  it != addrList.end();  ++it)
		{
			QString em((*it).fullEmail());
			if (!em.isEmpty())
				newEmails.append(em);
		}
	}
	else if (!(files = KUrl::List::fromMimeData(data)).isEmpty())
	{
		// URL(s)
		switch (mType)
		{
			case Url:
				// URL entry field - ignore all but the first dropped URL
				setText(files.first().prettyUrl());    // replace any existing text
				break;
			case Emails:
			{
				// Email entry field - ignore all but mailto: URLs
				QString mailto = QLatin1String("mailto");
				for (KUrl::List::Iterator it = files.begin();  it != files.end();  ++it)
				{
					if ((*it).protocol() == mailto)
						newEmails.append((*it).path());
				}
				break;
			}
			case Text:
				newText = files.first().prettyUrl();
				break;
		}
	}
	else if (data->hasText())
	{
		// Plain text
		QString txt = data->text();
		if (mType == Emails)
		{
			// Remove newlines from a list of email addresses, and allow an eventual mailto: protocol
			QString mailto = QLatin1String("mailto:");
			newEmails = txt.split(QRegExp("[\r\n]+"), QString::SkipEmptyParts);
			for (QStringList::Iterator it = newEmails.begin();  it != newEmails.end();  ++it)
			{
				if ((*it).startsWith(mailto))
				{
					KUrl url(*it);
					*it = url.path();
				}
			}
		}
		else
		{
			int newline = txt.indexOf(QLatin1Char('\n'));
			newText = (newline >= 0) ? txt.left(newline) : txt;
		}
	}

	if (newEmails.count())
	{
		newText = newEmails.join(",");
		int c = cursorPosition();
		if (c > 0)
			newText.prepend(",");
		if (c < static_cast<int>(text().length()))
			newText.append(",");
	}
	if (!newText.isEmpty())
		insert(newText);
}
<|endoftext|>


<commit_before>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

#include "allocore/ui/al_PresetSequencer.hpp"
#include "allocore/io/al_File.hpp"

using namespace al;

void PresetSequencer::playSequence(std::string sequenceName)
{
	stopSequence();
	std::string fullName = mDirectory;
	if (fullName.back() != '/') {
		fullName += "/";
	}
	if (sequenceName.size() < 9 || sequenceName.substr(sequenceName.size() - 9) != ".sequence") {
		fullName += sequenceName + ".sequence";
	}
	std::ifstream f(fullName);
	if (!f.is_open()) {
		std::cout << "Could not open:" << fullName << std::endl;
		return;
	}
	while (!mSteps.empty()) {
		mSteps.pop();
	}
	std::string line;
	while (getline(f, line)) {
		if (line.substr(0, 2) == "::") {
			break;
		}
		std::stringstream ss(line);
		std::string name, delta,duration;
		std::getline(ss, name, ':');
		std::getline(ss, delta, ':');
		std::getline(ss, duration, ':');
		if (name.size() > 0 && name[0] != '#') {
			Step step;
			step.presetName = name;
			step.delta = std::stof(delta);
			step.duration = std::stof(duration);
			mSteps.push(step);
			std::cout << name  << ":" << delta << ":" << duration << std::endl;
		}
	}
	if (f.bad()) {
		std::cout << "Error reading:" << sequenceName << std::endl;
		return;
	}
	mSequenceConditionVar.notify_one();
	//		mSequenceLock.unlock();
	mRunning = true;
}

void PresetSequencer::stopSequence()
{
	mRunning = false;
	//		mSequenceLock.lock(); // Waits until the sequencer thread is done and back at the condition variable
}

std::vector<std::string> al::PresetSequencer::getSequenceList()
{
	std::vector<std::string> sequenceList;
	Dir presetDir(mDirectory);
	while(presetDir.read()) {
		FileInfo info = presetDir.entry();
		if (info.type() == FileInfo::REG) {
			std::string fileName = info.name();
			if (fileName.find(".sequence") == fileName.size() - 9) {
				// Should do better checks, what if '.sequence' is not at the end...
				sequenceList.push_back(fileName.substr(0, fileName.size() - 9));
			}
		}
	}
	return sequenceList;
}

void PresetSequencer::sequencerFunction(al::PresetSequencer *sequencer)
{
	while(sequencer->mSequencerActive) {
		{
			std::unique_lock<std::mutex> lk(sequencer->mSequenceLock);
			sequencer->mSequenceConditionVar.wait(lk);
		}
		while(sequencer->running() && sequencer->mSteps.size() > 0) {
			Step &step = sequencer->mSteps.front();
			sequencer->mPresetHandler->setMorphTime(step.delta);
			sequencer->mPresetHandler->recallPreset(step.presetName);
//			std::cout << "PresetSequencer loading:" << step.presetName << std::endl;
			al::wait(step.delta + step.duration);
			sequencer->mSteps.pop();
		}
		sequencer->mRunning = false;
		//		std::cout << "Sequence finished." << std::endl;
	}
}

// SequenceServer ----------------------------------------------------------------

SequenceServer::SequenceServer(std::string oscAddress, int oscPort) :
    mServer(nullptr), mSequencer(nullptr),
    mOSCpath("/sequence"),
    mParamServer(nullptr)
{
	mServer = new osc::Recv(oscPort, oscAddress.c_str(), 0.001); // Is this 1ms wait OK?
	if (mServer) {
		mServer->handler(*this);
		mServer->start();
	} else {
		std::cout << "Error starting OSC server." << std::endl;
	}
}

SequenceServer::SequenceServer(ParameterServer &paramServer) :
    mServer(nullptr), mSequencer(nullptr),
    mParamServer(&paramServer),
    mOSCpath("/sequence")
{
	paramServer.registerOSCListener(this);
}

SequenceServer::~SequenceServer()
{
//	std::cout << "~SequenceServer()" << std::endl;;
	if (mServer) {
		mServer->stop();
		delete mServer;
		mServer = nullptr;
	}
}

void SequenceServer::onMessage(osc::Message &m)
{
	if(m.addressPattern() == mOSCpath && m.typeTags() == "s"){
		std::string val;
		m >> val;
		std::cout << "start sequence " << val << std::endl;
		if (mSequencer) {
			mSequencer->playSequence(val);
		} else {
			std::cout << "Sequence Server. OSC received, but PresetSequencer not registered." << std::endl;
		}
	}
}

void SequenceServer::print()
{
	if (mServer) {
		std::cout << "Sequence server listening on: " << mServer->address() << ":" << mServer->port() << std::endl;
		std::cout << "Communicating on path: " << mOSCpath << std::endl;
	}
	for (auto sender:mOSCSenders) {
		std::cout << sender->address() << ":" << sender->port() << std::endl;
	}
}

void SequenceServer::stopServer()
{
	if (mServer) {
		mServer->stop();
		delete mServer;
		mServer = nullptr;
	}
}

void SequenceServer::setAddress(std::string address)
{
	mOSCpath = address;
}

std::string SequenceServer::getAddress()
{
	return mOSCpath;
}

void SequenceServer::changeCallback(int value, void *sender, void *userData)
{
	SequenceServer *server = static_cast<SequenceServer *>(userData);
	Parameter *parameter = static_cast<Parameter *>(sender);
	server->notifyListeners(server->mOSCpath, value);
}

<commit_msg>Better handling of stopping sequencer to avoid crashes if sequence is started before stop has been processed.<commit_after>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>

#include "allocore/ui/al_PresetSequencer.hpp"
#include "allocore/io/al_File.hpp"

using namespace al;

void PresetSequencer::playSequence(std::string sequenceName)
{
	stopSequence();
	std::string fullName = mDirectory;
	if (fullName.back() != '/') {
		fullName += "/";
	}
	if (sequenceName.size() < 9 || sequenceName.substr(sequenceName.size() - 9) != ".sequence") {
		fullName += sequenceName + ".sequence";
	}
	std::ifstream f(fullName);
	if (!f.is_open()) {
		std::cout << "Could not open:" << fullName << std::endl;
		return;
	}
	while (!mSteps.empty()) {
		mSteps.pop();
	}
	std::string line;
	while (getline(f, line)) {
		if (line.substr(0, 2) == "::") {
			break;
		}
		std::stringstream ss(line);
		std::string name, delta,duration;
		std::getline(ss, name, ':');
		std::getline(ss, delta, ':');
		std::getline(ss, duration, ':');
		if (name.size() > 0 && name[0] != '#') {
			Step step;
			step.presetName = name;
			step.delta = std::stof(delta);
			step.duration = std::stof(duration);
			mSteps.push(step);
			std::cout << name  << ":" << delta << ":" << duration << std::endl;
		}
	}
	if (f.bad()) {
		std::cout << "Error reading:" << sequenceName << std::endl;
		return;
	}
	mSequenceConditionVar.notify_one();
	//		mSequenceLock.unlock();
	mRunning = true;
}

void PresetSequencer::stopSequence()
{
	mRunning = false;
	mSequenceLock.lock(); // Waits until the sequencer thread is done and back at the condition variable
	mSequenceLock.unlock();
}

std::vector<std::string> al::PresetSequencer::getSequenceList()
{
	std::vector<std::string> sequenceList;
	Dir presetDir(mDirectory);
	while(presetDir.read()) {
		FileInfo info = presetDir.entry();
		if (info.type() == FileInfo::REG) {
			std::string fileName = info.name();
			if (fileName.find(".sequence") == fileName.size() - 9) {
				// Should do better checks, what if '.sequence' is not at the end...
				sequenceList.push_back(fileName.substr(0, fileName.size() - 9));
			}
		}
	}
	return sequenceList;
}

void PresetSequencer::sequencerFunction(al::PresetSequencer *sequencer)
{
	while(sequencer->mSequencerActive) {
		{
			std::unique_lock<std::mutex> lk(sequencer->mSequenceLock);
			sequencer->mSequenceConditionVar.wait(lk);
		}
		while(sequencer->running() && sequencer->mSteps.size() > 0) {
			Step &step = sequencer->mSteps.front();
			sequencer->mPresetHandler->setMorphTime(step.delta);
			sequencer->mPresetHandler->recallPreset(step.presetName);
//			std::cout << "PresetSequencer loading:" << step.presetName << std::endl;
			float totalWaitTime = step.delta + step.duration;
			while (totalWaitTime > 1.0f) {
				al_sec before = al::timeNow();
				al::wait(1.0);
				if (sequencer->mRunning == false) {
					break;
				}
				al_sec elapsed = al::timeNow()- before;
	//			std::cout << "Elapsed " << elapsed << std::endl;
				totalWaitTime -= elapsed;
			}
			al::wait(totalWaitTime);
			sequencer->mSteps.pop();
		}
		sequencer->mRunning = false;
		//		std::cout << "Sequence finished." << std::endl;
	}
}

// SequenceServer ----------------------------------------------------------------

SequenceServer::SequenceServer(std::string oscAddress, int oscPort) :
    mServer(nullptr), mSequencer(nullptr),
    mOSCpath("/sequence"),
    mParamServer(nullptr)
{
	mServer = new osc::Recv(oscPort, oscAddress.c_str(), 0.001); // Is this 1ms wait OK?
	if (mServer) {
		mServer->handler(*this);
		mServer->start();
	} else {
		std::cout << "Error starting OSC server." << std::endl;
	}
}

SequenceServer::SequenceServer(ParameterServer &paramServer) :
    mServer(nullptr), mSequencer(nullptr),
    mParamServer(&paramServer),
    mOSCpath("/sequence")
{
	paramServer.registerOSCListener(this);
}

SequenceServer::~SequenceServer()
{
//	std::cout << "~SequenceServer()" << std::endl;;
	if (mServer) {
		mServer->stop();
		delete mServer;
		mServer = nullptr;
	}
}

void SequenceServer::onMessage(osc::Message &m)
{
	if(m.addressPattern() == mOSCpath && m.typeTags() == "s"){
		std::string val;
		m >> val;
		std::cout << "start sequence " << val << std::endl;
		if (mSequencer) {
			mSequencer->playSequence(val);
		} else {
			std::cout << "Sequence Server. OSC received, but PresetSequencer not registered." << std::endl;
		}
	}
}

void SequenceServer::print()
{
	if (mServer) {
		std::cout << "Sequence server listening on: " << mServer->address() << ":" << mServer->port() << std::endl;
		std::cout << "Communicating on path: " << mOSCpath << std::endl;
	}
	for (auto sender:mOSCSenders) {
		std::cout << sender->address() << ":" << sender->port() << std::endl;
	}
}

void SequenceServer::stopServer()
{
	if (mServer) {
		mServer->stop();
		delete mServer;
		mServer = nullptr;
	}
}

void SequenceServer::setAddress(std::string address)
{
	mOSCpath = address;
}

std::string SequenceServer::getAddress()
{
	return mOSCpath;
}

void SequenceServer::changeCallback(int value, void *sender, void *userData)
{
	SequenceServer *server = static_cast<SequenceServer *>(userData);
	Parameter *parameter = static_cast<Parameter *>(sender);
	server->notifyListeners(server->mOSCpath, value);
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "keyboard.hpp"
#include "interrupts.hpp"
#include "kernel_utils.hpp"
#include "semaphore.hpp"
#include "spinlock.hpp"
#include "sleep_queue.hpp"

namespace {

char qwertz[128] = {
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'q', 'w', 'e', 'r',	/* 19 */
  't', 'z', 'u', 'i', 'o', 'p', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'y', 'x', 'c', 'v', 'b', 'n',			/* 49 */
  'm', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};

char shifted_qwertz[128] = {
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'Q', 'W', 'E', 'R',	/* 19 */
  'T', 'Z', 'U', 'I', 'O', 'P', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'Y', 'X', 'C', 'V', 'B', 'N',			/* 49 */
  'M', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};

const uint8_t BUFFER_SIZE = 64;

//TODO Encapsulate the buffer
char input_buffer[BUFFER_SIZE];
volatile uint8_t start;
volatile uint8_t count;

spinlock lock;
sleep_queue queue;

void give_char(scheduler::pid_t pid, char t){
    scheduler::get_process(pid).regs.rax = t;
}

void keyboard_handler(const interrupt::syscall_regs&){
    auto key = static_cast<char>(in_byte(0x60));

    std::lock_guard<spinlock> l(lock);

    if(count == BUFFER_SIZE){
        //The buffer is full, we loose the characters
    } else {
        if(queue.empty()){
            auto end = (start + count) % BUFFER_SIZE;
            input_buffer[end] = key;
            ++count;
        } else {
            auto pid = queue.wake_up();
            give_char(pid, key);
        }
    }
}

} //end of anonymous namespace

void keyboard::install_driver(){
    interrupt::register_irq_handler(1, keyboard_handler);

    start = 0;
    count = 0;
}

void keyboard::get_char_blocking(){
    std::lock_guard<spinlock> l(lock);

    if(count > 0){
        auto key = input_buffer[start];
        start = (start + 1) % BUFFER_SIZE;
        --count;

        auto pid = scheduler::get_pid();
        give_char(pid, key);
    } else {
        //Wait for a char
        queue.sleep();
    }
}

//TODO Once shell is user mode, can be removed
char keyboard::get_char(){
    //Wait for the buffer to contains something
    while(count == 0){
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
    }

    auto key = input_buffer[start];
    start = (start + 1) % BUFFER_SIZE;
    --count;

    return key;
}

char keyboard::key_to_ascii(uint8_t key){
    return qwertz[key];
}

char keyboard::shift_key_to_ascii(uint8_t key){
    return shifted_qwertz[key];
}
<commit_msg>Transform the key to ascii<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include "keyboard.hpp"
#include "interrupts.hpp"
#include "kernel_utils.hpp"
#include "semaphore.hpp"
#include "spinlock.hpp"
#include "sleep_queue.hpp"

namespace {

char qwertz[128] = {
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'q', 'w', 'e', 'r',	/* 19 */
  't', 'z', 'u', 'i', 'o', 'p', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'y', 'x', 'c', 'v', 'b', 'n',			/* 49 */
  'm', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};

char shifted_qwertz[128] = {
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'Q', 'W', 'E', 'R',	/* 19 */
  'T', 'Z', 'U', 'I', 'O', 'P', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'Y', 'X', 'C', 'V', 'B', 'N',			/* 49 */
  'M', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};

const uint8_t BUFFER_SIZE = 64;

//TODO Encapsulate the buffer
char input_buffer[BUFFER_SIZE];
volatile uint8_t start;
volatile uint8_t count;

spinlock lock;
sleep_queue queue;

void give_char(scheduler::pid_t pid, char t){
    scheduler::get_process(pid).regs.rax = t;
}

void keyboard_handler(const interrupt::syscall_regs&){
    auto key = static_cast<char>(in_byte(0x60));

    std::lock_guard<spinlock> l(lock);

    if(count == BUFFER_SIZE){
        //The buffer is full, we loose the characters
    } else {
        if(queue.empty()){
            auto end = (start + count) % BUFFER_SIZE;
            input_buffer[end] = key;
            ++count;
        } else {
            auto pid = queue.wake_up();
            give_char(pid, keyboard::shift_key_to_ascii(key));
        }
    }
}

} //end of anonymous namespace

void keyboard::install_driver(){
    interrupt::register_irq_handler(1, keyboard_handler);

    start = 0;
    count = 0;
}

void keyboard::get_char_blocking(){
    std::lock_guard<spinlock> l(lock);

    if(count > 0){
        auto key = input_buffer[start];
        start = (start + 1) % BUFFER_SIZE;
        --count;

        auto pid = scheduler::get_pid();
        give_char(pid, shift_key_to_ascii(key));
    } else {
        //Wait for a char
        queue.sleep();
    }
}

//TODO Once shell is user mode, can be removed
char keyboard::get_char(){
    //Wait for the buffer to contains something
    while(count == 0){
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
        __asm__  __volatile__ ("nop");
    }

    auto key = input_buffer[start];
    start = (start + 1) % BUFFER_SIZE;
    --count;

    return key;
}

char keyboard::key_to_ascii(uint8_t key){
    return qwertz[key];
}

char keyboard::shift_key_to_ascii(uint8_t key){
    return shifted_qwertz[key];
}
<|endoftext|>


<commit_before>#include <event2/event.h>
#include <lightstep/tracer.h>
#include <lightstep/transporter.h>
#include <cassert>
#include <iostream>
#include "qa_bot.h"
using namespace lightstep;

static void FlushTracerCallback(int /*sock*/, short /*what*/, void* context) {
  auto tracer = static_cast<LightStepTracer*>(context);
  tracer->Flush();
}

static void TransporterCallback(int /*sock*/, short what, void* context) {
  auto transporter = static_cast<LightStepAsyncTransporter*>(context);
  if (what & EV_READ) {
    transporter->OnRead();
  } else if (what & EV_WRITE) {
    transporter->OnWrite();
  } else if (what & EV_TIMEOUT) {
    transporter->OnTimeout();
  }
}

int main() {
  auto base = event_base_new();

  auto transporter = MakeLightStepAsyncTransporter();
  assert(transporter);

  // Set up events associated with the LightStep transportation socket.
  timeval transporter_timeout = {5, 0};
  auto transporter_event = event_new(
      base, transporter->file_descriptor(), EV_READ | EV_WRITE | EV_PERSIST,
      TransporterCallback, static_cast<void*>(transporter.get()));
  event_add(transporter_event, &transporter_timeout);

  LightStepManualTracerOptions options;
  options.verbose = true;
  options.transporter =
      std::unique_ptr<AsyncTransporter>{transporter.release()};
  auto tracer = MakeLightStepTracer(std::move(options));
  assert(tracer);

  // Set up a periodic timer event to flush the tracer.
  auto timer_event =
      event_new(base, -1, EV_PERSIST, FlushTracerCallback, tracer.get());
  timeval flush_time_period = {1, 0};
  evtimer_add(timer_event, &flush_time_period);

  QABot bot{std::move(tracer), base};
  event_base_dispatch(base);
  event_del(transporter_event);
  event_del(timer_event);
  event_base_free(base);
  return 0;
}
<commit_msg>Document the manual tracer example.<commit_after>/**
 * This is a minimal example of an application that uses LightStep's manual
 * tracer.
 *
 * The application is built using the Reactor pattern. It uses libevent to
 * concurrently manage multiple sockets. From each socket, it reads questions
 * and sends answers until that socket closes. It integrates the regular tracer
 * flushes and events over the tracer's socket into the main libevent loop.
 */
#include <event2/event.h>
#include <lightstep/tracer.h>
#include <lightstep/transporter.h>
#include <cassert>
#include <iostream>
#include "qa_bot.h"
using namespace lightstep;

static void FlushTracerCallback(int /*sock*/, short /*what*/, void* context) {
  auto tracer = static_cast<LightStepTracer*>(context);
  tracer->Flush();
}

static void TransporterCallback(int /*sock*/, short what, void* context) {
  auto transporter = static_cast<LightStepAsyncTransporter*>(context);
  if (what & EV_READ) {
    transporter->OnRead();
  } else if (what & EV_WRITE) {
    transporter->OnWrite();
  } else if (what & EV_TIMEOUT) {
    transporter->OnTimeout();
  }
}

int main() {
  auto base = event_base_new();

  auto transporter = MakeLightStepAsyncTransporter();
  assert(transporter);

  // Set up events associated with the LightStep transportation socket.
  timeval transporter_timeout = {5, 0};
  auto transporter_event = event_new(
      base, transporter->file_descriptor(), EV_READ | EV_WRITE | EV_PERSIST,
      TransporterCallback, static_cast<void*>(transporter.get()));
  event_add(transporter_event, &transporter_timeout);

  LightStepManualTracerOptions options;
  options.verbose = true;
  options.transporter =
      std::unique_ptr<AsyncTransporter>{transporter.release()};
  auto tracer = MakeLightStepTracer(std::move(options));
  assert(tracer);

  // Set up a periodic timer event to flush the tracer.
  auto timer_event =
      event_new(base, -1, EV_PERSIST, FlushTracerCallback, tracer.get());
  timeval flush_time_period = {1, 0};
  evtimer_add(timer_event, &flush_time_period);

  // Set up the QABot server.
  QABot bot{std::move(tracer), base};
  event_base_dispatch(base);
  event_del(transporter_event);
  event_del(timer_event);
  event_base_free(base);
  return 0;
}
<|endoftext|>


<commit_before>// Copyright © 2011, Université catholique de Louvain
// 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.
//
// 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 HOLDER 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.

#ifndef __STORAGE_DECL_H
#define __STORAGE_DECL_H

#include "core-forward-decl.hh"

#include "type-decl.hh"
#include "memword.hh"
#include "arrays.hh"

#include <type_traits>

// Hacky helper (see below) - officially UB
namespace std {
  template<typename> struct has_trivial_destructor;
  template<typename> struct is_trivially_destructible;
}

namespace mozart {

/* First a hackish helper to support compilers and std libs which still use
 * has_trivial_destructor instead of is_trivially_destructible. */

template<typename T>
class have_cxx11_trait_helper {
private:
  template<typename T2, bool = std::is_trivially_destructible<T2>::type::value>
  static std::true_type test(int);

  template<typename T2, bool = std::has_trivial_destructor<T2>::type::value>
  static std::false_type test(...);

public:
  typedef decltype(test<T>(0)) type;
};

template<typename T>
struct have_cxx11_trait : have_cxx11_trait_helper<T>::type {
};

template<typename T>
using is_trivially_destructible =
  typename std::conditional<have_cxx11_trait<T>::value,
                            std::is_trivially_destructible<T>,
                            std::has_trivial_destructor<T>>::type;

// Now our stuff

template<typename T>
struct ImplAndCleanupListNode {
  template<class... Args>
  inline
  ImplAndCleanupListNode(VM vm, Args&&... args);

  T impl;
  VMCleanupListNode cleanupListNode;
};

template<typename T>
struct DerefPotentialImplAndCleanup {
  static T& deref(T& impl) {
    return impl;
  }
};

template<typename T>
struct DerefPotentialImplAndCleanup<ImplAndCleanupListNode<T>> {
  static T& deref(ImplAndCleanupListNode<T>& implAndCleanupListNode) {
    return implAndCleanupListNode.impl;
  }
};

template<class I, class E>
class ImplWithArray {
  I* p;
public:
  ImplWithArray(I* p) : p(p) {}

  I* operator->() {
    return p;
  }

  E& operator[](size_t i) {
    return getRawArray()[i];
  }

  StaticArray<E> getArray(size_t size) {
    return StaticArray<E>(getRawArray(), size);
  }
private:
  template <typename T, typename U>
  friend class AccessorHelper;

  E* getRawArray() {
    return static_cast<E*>(static_cast<void*>(
      static_cast<char*>(static_cast<void*>(p)) + sizeof(I)));
  }
};

// Marker class that specifies to use the default storage (pointer to value)
template<class T>
class DefaultStorage {
};

// Meta-function from Type to its storage
template<class T>
class Storage {
public:
  typedef DefaultStorage<T> Type;
};

template<class T, class U>
class AccessorHelper {
public:
  // StoredAs types must be trivially destructible
  static_assert(is_trivially_destructible<U>::value,
                "The type U in StoredAs<U> must be trivially destructible.");

  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm, Args&&... args) {
    type = T::type();
    value.alloc<U>(vm);
    T::create(value.get<U>(), vm, std::forward<Args>(args)...);
  }

  static T get(MemWord value) {
    return T(value.get<U>());
  }
};

template<class T>
class AccessorHelper<T, DefaultStorage<T>> {
private:
  typedef typename std::conditional<
    is_trivially_destructible<T>::value,
    T, ImplAndCleanupListNode<T>>::type ActualT;
public:
  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm, Args&&... args) {
    type = T::type();
    ActualT* val = new (vm) ActualT(vm, std::forward<Args>(args)...);
    value.init<ActualT*>(vm, val);
  }

  static T& get(MemWord value) {
    return DerefPotentialImplAndCleanup<ActualT>::deref(
      *(value.get<ActualT*>()));
  }
};

template<class T, class E>
class AccessorHelper<T, ImplWithArray<T, E>> {
public:
  // Limitation of the current implementation
  static_assert(
    is_trivially_destructible<T>::value && is_trivially_destructible<E>::value,
    "The types T and E in T: StoredWithArrayOfAs<U> must be trivially destructible.");

  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm,
                   size_t elemCount, Args&&... args) {
    // Allocate memory
    void* memory = operator new (sizeof(T) + elemCount*sizeof(E), vm);
    ImplWithArray<T, E> implWithArray(static_cast<T*>(memory));

    // Initialize the array
    E* array = implWithArray.getRawArray();
    new (array) E[elemCount];

    // Initialize the impl
    T* impl = implWithArray.operator->();
    new (impl) T(vm, elemCount, implWithArray.getArray(elemCount),
                 std::forward<Args>(args)...);

    // Fill in output parameters
    type = T::type();
    value.init<T*>(vm, impl);
  }

  static T& get(MemWord value) {
    return *(value.get<T*>());
  }
};

template <typename T>
using Accessor = AccessorHelper<T, typename Storage<T>::Type>;

}

#endif // __STORAGE_DECL_H
<commit_msg>Conditional definition of is_trivially_destructible.<commit_after>// Copyright © 2011, Université catholique de Louvain
// 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.
//
// 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 HOLDER 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.

#ifndef __STORAGE_DECL_H
#define __STORAGE_DECL_H

#include "core-forward-decl.hh"

#include "type-decl.hh"
#include "memword.hh"
#include "arrays.hh"

#include <type_traits>

namespace mozart {

/* In order to know if a type T has a trivial destructor we *should* use the
 * type trait std::is_tirivally_destructible<T>. However some standard library
 * provide the trait under the name std::has_trivial_destructor<T>. In the
 * following lines we alias any of those options depending on the standard
 * library we are using.
 * TODO: This is something we should eventually change or remove.
 */
#ifdef _LIBCPP_TYPE_TRAITS // using libc++
  template<typename T>
  using is_trivially_destructible = std::is_trivially_destructible<T>;
#else // libstdc++
  template<typename T>
  using is_trivially_destructible = std::has_trivial_destructor<T>;
#endif

// Now our stuff

template<typename T>
struct ImplAndCleanupListNode {
  template<class... Args>
  inline
  ImplAndCleanupListNode(VM vm, Args&&... args);

  T impl;
  VMCleanupListNode cleanupListNode;
};

template<typename T>
struct DerefPotentialImplAndCleanup {
  static T& deref(T& impl) {
    return impl;
  }
};

template<typename T>
struct DerefPotentialImplAndCleanup<ImplAndCleanupListNode<T>> {
  static T& deref(ImplAndCleanupListNode<T>& implAndCleanupListNode) {
    return implAndCleanupListNode.impl;
  }
};

template<class I, class E>
class ImplWithArray {
  I* p;
public:
  ImplWithArray(I* p) : p(p) {}

  I* operator->() {
    return p;
  }

  E& operator[](size_t i) {
    return getRawArray()[i];
  }

  StaticArray<E> getArray(size_t size) {
    return StaticArray<E>(getRawArray(), size);
  }
private:
  template <typename T, typename U>
  friend class AccessorHelper;

  E* getRawArray() {
    return static_cast<E*>(static_cast<void*>(
      static_cast<char*>(static_cast<void*>(p)) + sizeof(I)));
  }
};

// Marker class that specifies to use the default storage (pointer to value)
template<class T>
class DefaultStorage {
};

// Meta-function from Type to its storage
template<class T>
class Storage {
public:
  typedef DefaultStorage<T> Type;
};

template<class T, class U>
class AccessorHelper {
public:
  // StoredAs types must be trivially destructible
  static_assert(is_trivially_destructible<U>::value,
                "The type U in StoredAs<U> must be trivially destructible.");

  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm, Args&&... args) {
    type = T::type();
    value.alloc<U>(vm);
    T::create(value.get<U>(), vm, std::forward<Args>(args)...);
  }

  static T get(MemWord value) {
    return T(value.get<U>());
  }
};

template<class T>
class AccessorHelper<T, DefaultStorage<T>> {
private:
  typedef typename std::conditional<
    is_trivially_destructible<T>::value,
    T, ImplAndCleanupListNode<T>>::type ActualT;
public:
  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm, Args&&... args) {
    type = T::type();
    ActualT* val = new (vm) ActualT(vm, std::forward<Args>(args)...);
    value.init<ActualT*>(vm, val);
  }

  static T& get(MemWord value) {
    return DerefPotentialImplAndCleanup<ActualT>::deref(
      *(value.get<ActualT*>()));
  }
};

template<class T, class E>
class AccessorHelper<T, ImplWithArray<T, E>> {
public:
  // Limitation of the current implementation
  static_assert(
    is_trivially_destructible<T>::value && is_trivially_destructible<E>::value,
    "The types T and E in T: StoredWithArrayOfAs<U> must be trivially destructible.");

  template<class... Args>
  static void init(Type& type, MemWord& value, VM vm,
                   size_t elemCount, Args&&... args) {
    // Allocate memory
    void* memory = operator new (sizeof(T) + elemCount*sizeof(E), vm);
    ImplWithArray<T, E> implWithArray(static_cast<T*>(memory));

    // Initialize the array
    E* array = implWithArray.getRawArray();
    new (array) E[elemCount];

    // Initialize the impl
    T* impl = implWithArray.operator->();
    new (impl) T(vm, elemCount, implWithArray.getArray(elemCount),
                 std::forward<Args>(args)...);

    // Fill in output parameters
    type = T::type();
    value.init<T*>(vm, impl);
  }

  static T& get(MemWord value) {
    return *(value.get<T*>());
  }
};

template <typename T>
using Accessor = AccessorHelper<T, typename Storage<T>::Type>;

}

#endif // __STORAGE_DECL_H
<|endoftext|>


<commit_before>#include "tonemap.h"

#include <QPainter>
#include <QList>
#include <QPoint>
#include <QDebug>
#include <QMouseEvent>
#include <QColor>
#include <cmath>

static const double GRAB_DIST = 10; // pixels

inline static double sqr(double x)
{
    return x*x;
}

ToneMap::ToneMap(QWidget *parent) :
    QWidget(parent)
{
    mouseDown = false;
    W = width();
    H = height();
    selectedPoint = -1;

    points.append(QPoint(0,0));
    points.append(QPoint(16384,32768));
    points.append(QPoint(32768, 16384));
    points.append(QPoint(65535, 65535));
    refreshPoints();

    setMouseTracking(true);
}

QPoint ToneMap::fromDisplay(const QPoint & p)
{
    return QPoint((p.x() * 65536) / W, ((H-1-p.y()) * 65536) / H);
}

QPoint ToneMap::toDisplay(const QPoint &p)
{
    return QPoint((p.x() * W) / 65536, H-1 - (p.y() * H) / 65536);
}

void ToneMap::refreshPoints()
{
    dpoints.clear();
    for (int i = 0; i < points.size(); ++i)
        dpoints.append(toDisplay(points[i]));

    curve.setControlPoints(points);
    dcurve.setControlPoints(dpoints);
}

int ToneMap::nearestPoint(const QList<QPoint> & pts, QPoint p, double * dist)
{
    double bdist = 1.0e10;
    int best = 0;
    for (int i = 0; i < pts.count(); ++i)
    {
        double d = sqrt(sqr(p.x() - pts[i].x()) + sqr(p.y() - pts[i].y()));
        if (d < bdist)
        {
            bdist = d;
            best = i;
        }
    }

    if (dist) *dist = bdist;
    return best;
}

int ToneMap::value(int x)
{
   return x;
}

void ToneMap::mousePressEvent(QMouseEvent * event)
{
    mouseDown = true;
    mouseMoveEvent(event);
}

void ToneMap::mouseReleaseEvent(QMouseEvent * event)
{
    mouseDown = false;
}

void ToneMap::mouseMoveEvent(QMouseEvent * event)
{
    double dist;
    int pt = nearestPoint(dpoints, event->pos(), &dist);

    if (dist >= GRAB_DIST)
        pt = -1;

    if (pt != selectedPoint)
    {
        selectedPoint = pt;
        repaint();
    }

    qDebug() << "Move at " << event->pos() << endl;
    qDebug() << " nearest: " << pt << ", with dist = " << dist << endl;
}

void ToneMap::paintEvent(QPaintEvent * event)
{
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing, true);

    if (points.isEmpty())
        return;

    W = p.viewport().width();
    H = p.viewport().height();

    p.setBrush(QBrush(Qt::black));
    for (int i = 0; i < dpoints.count(); ++i)
    {
        if (selectedPoint == i)
            p.setBrush(Qt::SolidPattern);
        else
            p.setBrush(Qt::NoBrush);
        p.drawEllipse(dpoints[i], 3, 3);
    }

    p.drawPolyline(dcurve.getPolyline());
}
<commit_msg>Selected point highligting.<commit_after>#include "tonemap.h"

#include <QPainter>
#include <QList>
#include <QPoint>
#include <QDebug>
#include <QMouseEvent>
#include <QColor>
#include <cmath>

static const double GRAB_DIST = 6; // pixels
static const int DOT_RADIUS = 3;

inline static double sqr(double x)
{
    return x*x;
}

ToneMap::ToneMap(QWidget *parent) :
    QWidget(parent)
{
    mouseDown = false;
    W = width();
    H = height();
    selectedPoint = -1;

    points.append(QPoint(0,0));
    points.append(QPoint(16384,32768));
    points.append(QPoint(32768, 16384));
    points.append(QPoint(65535, 65535));
    refreshPoints();

    setMouseTracking(true);
}

QPoint ToneMap::fromDisplay(const QPoint & p)
{
    return QPoint((p.x() * 65536) / W, ((H-1-p.y()) * 65536) / H);
}

QPoint ToneMap::toDisplay(const QPoint &p)
{
    return QPoint((p.x() * W) / 65536, H-1 - (p.y() * H) / 65536);
}

void ToneMap::refreshPoints()
{
    dpoints.clear();
    for (int i = 0; i < points.size(); ++i)
        dpoints.append(toDisplay(points[i]));

    curve.setControlPoints(points);
    dcurve.setControlPoints(dpoints);
}

int ToneMap::nearestPoint(const QList<QPoint> & pts, QPoint p, double * dist)
{
    double bdist = 1.0e10;
    int best = 0;
    for (int i = 0; i < pts.count(); ++i)
    {
        double d = sqrt(sqr(p.x() - pts[i].x()) + sqr(p.y() - pts[i].y()));
        if (d < bdist)
        {
            bdist = d;
            best = i;
        }
    }

    if (dist) *dist = bdist;
    return best;
}

int ToneMap::value(int x)
{
   return x;
}

void ToneMap::mousePressEvent(QMouseEvent * event)
{
    mouseDown = true;
    mouseMoveEvent(event);
    update();
}

void ToneMap::mouseReleaseEvent(QMouseEvent * event)
{
    mouseDown = false;
    update();
}

void ToneMap::mouseMoveEvent(QMouseEvent * event)
{
    double dist;
    int pt = nearestPoint(dpoints, event->pos(), &dist);

    if (dist >= GRAB_DIST)
        pt = -1;

    if (pt != selectedPoint)
    {
        selectedPoint = pt;
        update();
    }
}

void ToneMap::paintEvent(QPaintEvent * event)
{
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing, true);

    W = p.viewport().width();
    H = p.viewport().height();

    QBrush brush(mouseDown ? Qt::red : Qt::black);
    for (int i = 0; i < dpoints.count(); ++i)
    {
        brush.setStyle(selectedPoint == i ? Qt::SolidPattern : Qt::NoBrush);
        p.setBrush(brush);
        p.drawEllipse(dpoints[i], DOT_RADIUS, DOT_RADIUS);
    }

    p.drawPolyline(dcurve.getPolyline());
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/x/selection_requestor.h"

#include "base/message_loop/message_pump_x11.h"
#include "base/run_loop.h"
#include "ui/base/x/selection_utils.h"
#include "ui/base/x/x11_util.h"

namespace ui {

namespace {

const char kChromeSelection[] = "CHROME_SELECTION";

const char* kAtomsToCache[] = {
  kChromeSelection,
  NULL
};

}  // namespace

SelectionRequestor::SelectionRequestor(Display* x_display,
                                       Window x_window,
                                       Atom selection_name)
    : x_display_(x_display),
      x_window_(x_window),
      selection_name_(selection_name),
      atom_cache_(x_display_, kAtomsToCache) {
}

SelectionRequestor::~SelectionRequestor() {}

bool SelectionRequestor::PerformBlockingConvertSelection(
    Atom target,
    scoped_refptr<base::RefCountedMemory>* out_data,
    size_t* out_data_bytes,
    size_t* out_data_items,
    Atom* out_type) {
  // The name of the property we're asking to be set on |x_window_|.
  Atom property_to_set = atom_cache_.GetAtom(kChromeSelection);

  XConvertSelection(x_display_,
                    selection_name_,
                    target,
                    property_to_set,
                    x_window_,
                    CurrentTime);

  // Now that we've thrown our message off to the X11 server, we block waiting
  // for a response.
  base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
  base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
  base::RunLoop run_loop;

  PendingRequest pending_request(target, run_loop.QuitClosure());
  pending_requests_.push_back(&pending_request);
  run_loop.Run();
  DCHECK(!pending_requests_.empty());
  DCHECK_EQ(&pending_request, pending_requests_.back());
  pending_requests_.pop_back();

  if (pending_request.returned_property != property_to_set)
    return false;

  return ui::GetRawBytesOfProperty(x_window_, pending_request.returned_property,
                                   out_data, out_data_bytes, out_data_items,
                                   out_type);
}

SelectionData SelectionRequestor::RequestAndWaitForTypes(
    const std::vector< ::Atom>& types) {
  for (std::vector< ::Atom>::const_iterator it = types.begin();
       it != types.end(); ++it) {
    scoped_refptr<base::RefCountedMemory> data;
    size_t data_bytes = 0;
    ::Atom type = None;
    if (PerformBlockingConvertSelection(*it,
                                        &data,
                                        &data_bytes,
                                        NULL,
                                        &type) &&
        type == *it) {
      return SelectionData(type, data);
    }
  }

  return SelectionData();
}

void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) {
  // Find the PendingRequest for the corresponding XConvertSelection call. If
  // there are multiple pending requests on the same target, satisfy them in
  // FIFO order.
  PendingRequest* request_notified = NULL;
  if (selection_name_ == event.selection) {
    for (std::list<PendingRequest*>::iterator iter = pending_requests_.begin();
         iter != pending_requests_.end(); ++iter) {
      PendingRequest* request = *iter;
      if (request->returned)
        continue;
      if (request->target != event.target)
        continue;
      request_notified = request;
      break;
    }
  }

  // This event doesn't correspond to any XConvertSelection calls that we
  // issued in PerformBlockingConvertSelection. This shouldn't happen, but any
  // client can send any message, so it can happen.
  if (!request_notified)
    return;

  request_notified->returned_property = event.property;
  request_notified->returned = true;
  request_notified->quit_closure.Run();
}

SelectionRequestor::PendingRequest::PendingRequest(Atom target,
                                                   base::Closure quit_closure)
    : target(target),
      quit_closure(quit_closure),
      returned_property(None),
      returned(false) {
}

SelectionRequestor::PendingRequest::~PendingRequest() {
}

}  // namespace ui
<commit_msg>x11: Set a timeout for the clipboard copy request.<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/x/selection_requestor.h"

#include "base/message_loop/message_pump_x11.h"
#include "base/run_loop.h"
#include "ui/base/x/selection_utils.h"
#include "ui/base/x/x11_util.h"

namespace ui {

namespace {

const char kChromeSelection[] = "CHROME_SELECTION";

const char* kAtomsToCache[] = {
  kChromeSelection,
  NULL
};

}  // namespace

SelectionRequestor::SelectionRequestor(Display* x_display,
                                       Window x_window,
                                       Atom selection_name)
    : x_display_(x_display),
      x_window_(x_window),
      selection_name_(selection_name),
      atom_cache_(x_display_, kAtomsToCache) {
}

SelectionRequestor::~SelectionRequestor() {}

bool SelectionRequestor::PerformBlockingConvertSelection(
    Atom target,
    scoped_refptr<base::RefCountedMemory>* out_data,
    size_t* out_data_bytes,
    size_t* out_data_items,
    Atom* out_type) {
  // The name of the property we're asking to be set on |x_window_|.
  Atom property_to_set = atom_cache_.GetAtom(kChromeSelection);

  XConvertSelection(x_display_,
                    selection_name_,
                    target,
                    property_to_set,
                    x_window_,
                    CurrentTime);

  // Now that we've thrown our message off to the X11 server, we block waiting
  // for a response.
  base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
  base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
  base::RunLoop run_loop;

  // Stop waiting for a response after a certain amount of time.
  const int kMaxWaitTimeForClipboardResponse = 300;
  loop->PostDelayedTask(
      FROM_HERE,
      run_loop.QuitClosure(),
      base::TimeDelta::FromMilliseconds(kMaxWaitTimeForClipboardResponse));

  PendingRequest pending_request(target, run_loop.QuitClosure());
  pending_requests_.push_back(&pending_request);
  run_loop.Run();
  DCHECK(!pending_requests_.empty());
  DCHECK_EQ(&pending_request, pending_requests_.back());
  pending_requests_.pop_back();

  if (pending_request.returned_property != property_to_set)
    return false;

  return ui::GetRawBytesOfProperty(x_window_, pending_request.returned_property,
                                   out_data, out_data_bytes, out_data_items,
                                   out_type);
}

SelectionData SelectionRequestor::RequestAndWaitForTypes(
    const std::vector< ::Atom>& types) {
  for (std::vector< ::Atom>::const_iterator it = types.begin();
       it != types.end(); ++it) {
    scoped_refptr<base::RefCountedMemory> data;
    size_t data_bytes = 0;
    ::Atom type = None;
    if (PerformBlockingConvertSelection(*it,
                                        &data,
                                        &data_bytes,
                                        NULL,
                                        &type) &&
        type == *it) {
      return SelectionData(type, data);
    }
  }

  return SelectionData();
}

void SelectionRequestor::OnSelectionNotify(const XSelectionEvent& event) {
  // Find the PendingRequest for the corresponding XConvertSelection call. If
  // there are multiple pending requests on the same target, satisfy them in
  // FIFO order.
  PendingRequest* request_notified = NULL;
  if (selection_name_ == event.selection) {
    for (std::list<PendingRequest*>::iterator iter = pending_requests_.begin();
         iter != pending_requests_.end(); ++iter) {
      PendingRequest* request = *iter;
      if (request->returned)
        continue;
      if (request->target != event.target)
        continue;
      request_notified = request;
      break;
    }
  }

  // This event doesn't correspond to any XConvertSelection calls that we
  // issued in PerformBlockingConvertSelection. This shouldn't happen, but any
  // client can send any message, so it can happen.
  if (!request_notified)
    return;

  request_notified->returned_property = event.property;
  request_notified->returned = true;
  request_notified->quit_closure.Run();
}

SelectionRequestor::PendingRequest::PendingRequest(Atom target,
                                                   base::Closure quit_closure)
    : target(target),
      quit_closure(quit_closure),
      returned_property(None),
      returned(false) {
}

SelectionRequestor::PendingRequest::~PendingRequest() {
}

}  // namespace ui
<|endoftext|>