<commit_before>/* bzflag
 * Copyright (c) 1993 - 2009 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "WorldBuilder.h"

/* common implementation headers */
#include "TextUtils.h"
#include "Protocol.h"
#include "DynamicColor.h"
#include "TextureMatrix.h"
#include "PhysicsDriver.h"
#include "FlagSceneNode.h"
#include "ObstacleMgr.h"
#include "BaseBuilding.h"
#include "MeshObstacle.h"
#include "MeshFace.h"

/* compression library header */
#include "zlib.h"

WorldBuilder::WorldBuilder()
{
  world = new World;
  owned = true;
}

WorldBuilder::~WorldBuilder()
{
  if (owned) delete world;
}

void* WorldBuilder::unpack(void* buf)
{
  TimeKeeper start = TimeKeeper::getCurrent();

  // unpack world database from network transfer
  // read style header
  uint16_t code, len;
  buf = nboUnpackUInt16(buf, len);
  buf = nboUnpackUInt16(buf, code);
  if (code != WorldCodeHeader) return NULL;

  // read style
  uint16_t serverMapVersion;
  buf = nboUnpackUInt16(buf, serverMapVersion);
  if (serverMapVersion != mapVersion) {
    logDebugMessage(1,"WorldBuilder::unpack() bad map version\n");
    return NULL;
  }

  // decompress
  uint32_t compressedSize, uncompressedSize;
  buf = nboUnpackUInt32 (buf, uncompressedSize);
  buf = nboUnpackUInt32 (buf, compressedSize);
  uLongf destLen = uncompressedSize;
  char *uncompressedWorld = new char[destLen];
  char *compressedWorld = (char*) buf;

  if (uncompress ((Bytef*)uncompressedWorld, &destLen,
		  (Bytef*)compressedWorld, compressedSize) != Z_OK) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() could not decompress\n");
    return NULL;
  }
  char* uncompressedEnd = uncompressedWorld + uncompressedSize;

  buf = uncompressedWorld;

  // setup the buffer overrun checking
  nboUseErrorChecking(true);
  nboSetBufferLength(uncompressedSize);
  nboClearBufferError();

  // unpack the map information
  world->mapInfo.clear();
  buf = world->mapInfo.unpack(buf);

  // unpack dynamic colors
  DYNCOLORMGR.clear();
  buf = DYNCOLORMGR.unpack(buf);

  // unpack texture matrices
  TEXMATRIXMGR.clear();
  buf = TEXMATRIXMGR.unpack(buf);

  // unpack materials
  MATERIALMGR.clear();
  buf = MATERIALMGR.unpack(buf);

  // unpack physics drivers
  PHYDRVMGR.clear();
  buf = PHYDRVMGR.unpack(buf);

  // unpack obstacle transforms
  TRANSFORMMGR.clear();
  buf = TRANSFORMMGR.unpack(buf);

  // unpack the obstacles
  OBSTACLEMGR.clear();
  buf = OBSTACLEMGR.unpack(buf);

  // unpack water level
  buf = nboUnpackFloat(buf, world->waterLevel);
  if (world->waterLevel >= 0.0f) {
    int32_t matindex;
    buf = nboUnpackInt32(buf, matindex);
    world->waterMaterial = MATERIALMGR.getMaterial(matindex);
  }

  uint32_t i, count;

  // unpack the weapons
  buf = nboUnpackUInt32(buf, count);
  for (i = 0; i < count; i++) {
    Weapon weapon;
    buf = weapon.unpack(buf);
    world->weapons.push_back(weapon);
  }

  // unpack the entry zones
  buf = nboUnpackUInt32(buf, count);
  for (i = 0; i < count; i++) {
    EntryZone zone;
    buf = zone.unpack(buf);
    world->entryZones.push_back(zone);
  }

  // check if the unpacking was successful
  nboUseErrorChecking(false);
  if (nboGetBufferError()) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() overrun\n");
    return NULL;
  }
  if ((char*)buf != uncompressedEnd) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() ending mismatch (%i)\n",
	    (char*)buf - uncompressedEnd);
    return NULL;
  }

  // switch back to the original buffer
  buf = compressedWorld + compressedSize;
  buf = nboUnpackUInt16(buf, len);
  buf = nboUnpackUInt16(buf, code);
  if ((code != WorldCodeEnd) || (len != WorldCodeEndSize)) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() bad ending\n");
    return NULL;
  }

  // delete the buffer
  delete[] uncompressedWorld;

  // build the world obstacles
  OBSTACLEMGR.makeWorld();

  // make the team bases
  if (world->gameType != ClassicCTF) {
    OBSTACLEMGR.replaceBasesWithBoxes();
  }
  else {
    const ObstacleList& bases = OBSTACLEMGR.getBases();
    for (i = 0; i < bases.size(); i++) {
      const BaseBuilding* base = (const BaseBuilding*) bases[i];
      setBase(base);
    }
    const ObstacleList& meshes = OBSTACLEMGR.getMeshes();
    for (i = 0; i < meshes.size(); i++) {
      const MeshObstacle* mesh = (const MeshObstacle*) meshes[i];
      if (!mesh->getHasSpecialFaces()) {
        continue;
      }
      const int faceCount = mesh->getFaceCount();
      for (int f = 0; f < faceCount; f++) {
        const MeshFace* face = mesh->getFace(f);
        if (face->isBaseFace()) {
          setBase(face);
        }
      }
    }
  }

  world->makeMeshDrawMgrs();

  // NOTE: relying on checkCollisionManager() to do the first loading
  //       of ColiisionManager, because the BZDB variables come in later,
  //       and would cause a double loading if we did it now.

  if (debugLevel >= 3) {
    TimeKeeper end = TimeKeeper::getCurrent();
    const float elapsed = (float)(end - start);
    logDebugMessage(0,"WorldBuilder::unpack() processed in %f seconds.\n", elapsed);
  }

  return buf;
}

void* WorldBuilder::unpackGameSettings(void* buf)
{
  // read style
  uint16_t gameType, gameOptions, maxPlayers, maxShots, botsPerIP, maxFlags;

  float worldSize;
  buf = nboUnpackFloat(buf, worldSize);
  BZDB.setFloat(StateDatabase::BZDB_WORLDSIZE, worldSize);
  buf = nboUnpackUInt16(buf, gameType);
  setGameType(short(gameType));
  buf = nboUnpackUInt16(buf, gameOptions);
  setGameOptions(short(gameOptions));
  buf = nboUnpackUInt16(buf, maxPlayers);
  setMaxPlayers(int(maxPlayers));
  buf = nboUnpackUInt16(buf, maxShots);
  setMaxShots(int(maxShots));
  buf = nboUnpackUInt16(buf, maxFlags);
  setMaxFlags(int(maxFlags));
  buf = nboUnpackUInt16(buf, botsPerIP);
  uint16_t shakeTimeout = 0, shakeWins;
  buf = nboUnpackUInt16(buf, shakeTimeout);
  setShakeTimeout(0.1f * float(shakeTimeout));
  buf = nboUnpackUInt16(buf, shakeWins);
  setShakeWins(shakeWins);

  return buf;
}

void WorldBuilder::preGetWorld()
{
  // prepare players array
  if (world->players) {
    delete[] world->players;
  }
  // FIXME
  // world->maxPlayers do not work as bzfs uses more player slot than
  // real players. Any tcp connection is assigned a slot.
  // So I put now 216. We should fix it though.
  const int maxPlayers = 216;
  int i;
  world->setPlayersSize(maxPlayers);

  // prepare flags array
  world->freeFlags();
  world->flags = new Flag[world->maxFlags];
  world->flagNodes = new FlagSceneNode*[world->maxFlags];
  world->flagWarpNodes = new FlagWarpSceneNode*[world->maxFlags];
  for (i = 0; i < world->maxFlags; i++) {
    world->flags[i].id = i;
    world->flags[i].type = Flags::Null;
    world->flags[i].status = FlagNoExist;
    world->flags[i].position.x = 0.0f;
    world->flags[i].position.y = 0.0f;
    world->flags[i].position.z = 0.0f;
    world->flagNodes[i] = new FlagSceneNode(world->flags[i].position);
    world->flagWarpNodes[i] = new FlagWarpSceneNode(world->flags[i].position);
    world->flagNodes[i]->setTexture(World::flagTexture);
  }

  return;
}

World* WorldBuilder::getWorld()
{
  owned = false;
  preGetWorld();
  return world;
}

World* WorldBuilder::peekWorld()
{
  preGetWorld();
  return world;
}

void WorldBuilder::setGameType(short gameType)
{
  world->gameType = (GameType)gameType;
}

void WorldBuilder::setGameOptions(short gameOptions)
{
  world->gameOptions = gameOptions;
}

void WorldBuilder::setMaxPlayers(int maxPlayers)
{
  world->maxPlayers = maxPlayers;
}

void WorldBuilder::setMaxShots(int maxShots)
{
  world->maxShots = maxShots;
}

void WorldBuilder::setMaxFlags(int maxFlags)
{
  world->maxFlags = maxFlags;
}

void WorldBuilder::setBotsPerIP(int botsPerIP)
{
    world->botsPerIP = botsPerIP;
}

void WorldBuilder::setShakeTimeout(float timeout) const
{
  world->shakeTimeout = timeout;
}

void WorldBuilder::setShakeWins(int wins) const
{
  world->shakeWins = wins;
}

void WorldBuilder::setBase(const Obstacle* base)
{
  world->bases[base->getBaseTeam()].push_back(base);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>max number of bots was always 1, and did not use the value read from the server<commit_after>/* bzflag
 * Copyright (c) 1993 - 2009 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "WorldBuilder.h"

/* common implementation headers */
#include "TextUtils.h"
#include "Protocol.h"
#include "DynamicColor.h"
#include "TextureMatrix.h"
#include "PhysicsDriver.h"
#include "FlagSceneNode.h"
#include "ObstacleMgr.h"
#include "BaseBuilding.h"
#include "MeshObstacle.h"
#include "MeshFace.h"

/* compression library header */
#include "zlib.h"

WorldBuilder::WorldBuilder()
{
  world = new World;
  owned = true;
}

WorldBuilder::~WorldBuilder()
{
  if (owned) delete world;
}

void* WorldBuilder::unpack(void* buf)
{
  TimeKeeper start = TimeKeeper::getCurrent();

  // unpack world database from network transfer
  // read style header
  uint16_t code, len;
  buf = nboUnpackUInt16(buf, len);
  buf = nboUnpackUInt16(buf, code);
  if (code != WorldCodeHeader) return NULL;

  // read style
  uint16_t serverMapVersion;
  buf = nboUnpackUInt16(buf, serverMapVersion);
  if (serverMapVersion != mapVersion) {
    logDebugMessage(1,"WorldBuilder::unpack() bad map version\n");
    return NULL;
  }

  // decompress
  uint32_t compressedSize, uncompressedSize;
  buf = nboUnpackUInt32 (buf, uncompressedSize);
  buf = nboUnpackUInt32 (buf, compressedSize);
  uLongf destLen = uncompressedSize;
  char *uncompressedWorld = new char[destLen];
  char *compressedWorld = (char*) buf;

  if (uncompress ((Bytef*)uncompressedWorld, &destLen,
		  (Bytef*)compressedWorld, compressedSize) != Z_OK) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() could not decompress\n");
    return NULL;
  }
  char* uncompressedEnd = uncompressedWorld + uncompressedSize;

  buf = uncompressedWorld;

  // setup the buffer overrun checking
  nboUseErrorChecking(true);
  nboSetBufferLength(uncompressedSize);
  nboClearBufferError();

  // unpack the map information
  world->mapInfo.clear();
  buf = world->mapInfo.unpack(buf);

  // unpack dynamic colors
  DYNCOLORMGR.clear();
  buf = DYNCOLORMGR.unpack(buf);

  // unpack texture matrices
  TEXMATRIXMGR.clear();
  buf = TEXMATRIXMGR.unpack(buf);

  // unpack materials
  MATERIALMGR.clear();
  buf = MATERIALMGR.unpack(buf);

  // unpack physics drivers
  PHYDRVMGR.clear();
  buf = PHYDRVMGR.unpack(buf);

  // unpack obstacle transforms
  TRANSFORMMGR.clear();
  buf = TRANSFORMMGR.unpack(buf);

  // unpack the obstacles
  OBSTACLEMGR.clear();
  buf = OBSTACLEMGR.unpack(buf);

  // unpack water level
  buf = nboUnpackFloat(buf, world->waterLevel);
  if (world->waterLevel >= 0.0f) {
    int32_t matindex;
    buf = nboUnpackInt32(buf, matindex);
    world->waterMaterial = MATERIALMGR.getMaterial(matindex);
  }

  uint32_t i, count;

  // unpack the weapons
  buf = nboUnpackUInt32(buf, count);
  for (i = 0; i < count; i++) {
    Weapon weapon;
    buf = weapon.unpack(buf);
    world->weapons.push_back(weapon);
  }

  // unpack the entry zones
  buf = nboUnpackUInt32(buf, count);
  for (i = 0; i < count; i++) {
    EntryZone zone;
    buf = zone.unpack(buf);
    world->entryZones.push_back(zone);
  }

  // check if the unpacking was successful
  nboUseErrorChecking(false);
  if (nboGetBufferError()) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() overrun\n");
    return NULL;
  }
  if ((char*)buf != uncompressedEnd) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() ending mismatch (%i)\n",
	    (char*)buf - uncompressedEnd);
    return NULL;
  }

  // switch back to the original buffer
  buf = compressedWorld + compressedSize;
  buf = nboUnpackUInt16(buf, len);
  buf = nboUnpackUInt16(buf, code);
  if ((code != WorldCodeEnd) || (len != WorldCodeEndSize)) {
    delete[] uncompressedWorld;
    logDebugMessage(1,"WorldBuilder::unpack() bad ending\n");
    return NULL;
  }

  // delete the buffer
  delete[] uncompressedWorld;

  // build the world obstacles
  OBSTACLEMGR.makeWorld();

  // make the team bases
  if (world->gameType != ClassicCTF) {
    OBSTACLEMGR.replaceBasesWithBoxes();
  }
  else {
    const ObstacleList& bases = OBSTACLEMGR.getBases();
    for (i = 0; i < bases.size(); i++) {
      const BaseBuilding* base = (const BaseBuilding*) bases[i];
      setBase(base);
    }
    const ObstacleList& meshes = OBSTACLEMGR.getMeshes();
    for (i = 0; i < meshes.size(); i++) {
      const MeshObstacle* mesh = (const MeshObstacle*) meshes[i];
      if (!mesh->getHasSpecialFaces()) {
        continue;
      }
      const int faceCount = mesh->getFaceCount();
      for (int f = 0; f < faceCount; f++) {
        const MeshFace* face = mesh->getFace(f);
        if (face->isBaseFace()) {
          setBase(face);
        }
      }
    }
  }

  world->makeMeshDrawMgrs();

  // NOTE: relying on checkCollisionManager() to do the first loading
  //       of ColiisionManager, because the BZDB variables come in later,
  //       and would cause a double loading if we did it now.

  if (debugLevel >= 3) {
    TimeKeeper end = TimeKeeper::getCurrent();
    const float elapsed = (float)(end - start);
    logDebugMessage(0,"WorldBuilder::unpack() processed in %f seconds.\n", elapsed);
  }

  return buf;
}

void* WorldBuilder::unpackGameSettings(void* buf)
{
  // read style
  uint16_t gameType, gameOptions, maxPlayers, maxShots, botsPerIP, maxFlags;

  float worldSize;
  buf = nboUnpackFloat(buf, worldSize);
  BZDB.setFloat(StateDatabase::BZDB_WORLDSIZE, worldSize);
  buf = nboUnpackUInt16(buf, gameType);
  setGameType(short(gameType));
  buf = nboUnpackUInt16(buf, gameOptions);
  setGameOptions(short(gameOptions));
  buf = nboUnpackUInt16(buf, maxPlayers);
  setMaxPlayers(int(maxPlayers));
  buf = nboUnpackUInt16(buf, maxShots);
  setMaxShots(int(maxShots));
  buf = nboUnpackUInt16(buf, maxFlags);
  setMaxFlags(int(maxFlags));
  buf = nboUnpackUInt16(buf, botsPerIP);
  setBotsPerIP(botsPerIP);
  uint16_t shakeTimeout = 0, shakeWins;
  buf = nboUnpackUInt16(buf, shakeTimeout);
  setShakeTimeout(0.1f * float(shakeTimeout));
  buf = nboUnpackUInt16(buf, shakeWins);
  setShakeWins(shakeWins);

  return buf;
}

void WorldBuilder::preGetWorld()
{
  // prepare players array
  if (world->players) {
    delete[] world->players;
  }
  // FIXME
  // world->maxPlayers do not work as bzfs uses more player slot than
  // real players. Any tcp connection is assigned a slot.
  // So I put now 216. We should fix it though.
  const int maxPlayers = 216;
  int i;
  world->setPlayersSize(maxPlayers);

  // prepare flags array
  world->freeFlags();
  world->flags = new Flag[world->maxFlags];
  world->flagNodes = new FlagSceneNode*[world->maxFlags];
  world->flagWarpNodes = new FlagWarpSceneNode*[world->maxFlags];
  for (i = 0; i < world->maxFlags; i++) {
    world->flags[i].id = i;
    world->flags[i].type = Flags::Null;
    world->flags[i].status = FlagNoExist;
    world->flags[i].position.x = 0.0f;
    world->flags[i].position.y = 0.0f;
    world->flags[i].position.z = 0.0f;
    world->flagNodes[i] = new FlagSceneNode(world->flags[i].position);
    world->flagWarpNodes[i] = new FlagWarpSceneNode(world->flags[i].position);
    world->flagNodes[i]->setTexture(World::flagTexture);
  }

  return;
}

World* WorldBuilder::getWorld()
{
  owned = false;
  preGetWorld();
  return world;
}

World* WorldBuilder::peekWorld()
{
  preGetWorld();
  return world;
}

void WorldBuilder::setGameType(short gameType)
{
  world->gameType = (GameType)gameType;
}

void WorldBuilder::setGameOptions(short gameOptions)
{
  world->gameOptions = gameOptions;
}

void WorldBuilder::setMaxPlayers(int maxPlayers)
{
  world->maxPlayers = maxPlayers;
}

void WorldBuilder::setMaxShots(int maxShots)
{
  world->maxShots = maxShots;
}

void WorldBuilder::setMaxFlags(int maxFlags)
{
  world->maxFlags = maxFlags;
}

void WorldBuilder::setBotsPerIP(int botsPerIP)
{
    world->botsPerIP = botsPerIP;
}

void WorldBuilder::setShakeTimeout(float timeout) const
{
  world->shakeTimeout = timeout;
}

void WorldBuilder::setShakeWins(int wins) const
{
  world->shakeWins = wins;
}

void WorldBuilder::setBase(const Obstacle* base)
{
  world->bases[base->getBaseTeam()].push_back(base);
}

// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include "driver.hh"
#include "bsemain.hh"
#include "internal.hh"
#include "bsesequencer.hh"

#define DDEBUG(...)     Bse::debug ("driver", __VA_ARGS__)

namespace Bse {

// == Driver ==
Driver::Driver (const String &devid) :
  devid_ (devid)
{}

Driver::~Driver ()
{}

// == RegisteredDriver ==
template<typename DriverP>
struct RegisteredDriver {
  const String                            driver_id_;
  std::function<DriverP (const String&)>  create_;
  std::function<void (Driver::EntryVec&)> list_;
  using RegisteredDriverVector = std::vector<RegisteredDriver>;
  static RegisteredDriverVector&
  registered_driver_vector()
  {
    static RegisteredDriverVector registered_driver_vector_;
    return registered_driver_vector_;
  }
  static DriverP
  open (const String &devid, Driver::IODir iodir, Error *ep,
        const std::function<Error (DriverP, Driver::IODir)> &opener)
  {
    std::function<DriverP (const String&)> create;
    const String driverid = kvpair_key (devid);
    for (const auto &driver : registered_driver_vector())
      if (driver.driver_id_ == driverid)
        {
          create = driver.create_;
          break;
        }
    Error error = Error::DEVICE_NOT_AVAILABLE;
    DriverP driver = create ? create (kvpair_value (devid)) : NULL;
    if (driver)
      {
        error = opener (driver, iodir);
        if (ep)
          *ep = error;
        if (error == Error::NONE)
          {
            assert_return (driver->opened() == true, nullptr);
            assert_return (!(iodir & Driver::READONLY) || driver->readable(), nullptr);
            assert_return (!(iodir & Driver::WRITEONLY) || driver->writable(), nullptr);
          }
        else
          driver = nullptr;
      }
    else if (ep)
      *ep = error;
    return driver;
  }
  static String
  register_driver (const String &driverid,
                   const std::function<DriverP (const String&)> &create,
                   const std::function<void (Driver::EntryVec&)> &list)
  {
    auto &vec = registered_driver_vector();
    RegisteredDriver rd = { driverid, create, list, };
    vec.push_back (rd);
    return driverid;
  }
  static Driver::EntryVec
  list_drivers (const Driver::EntryVec &pseudos)
  {
    Driver::EntryVec entries;
    std::copy (pseudos.begin(), pseudos.end(), std::back_inserter (entries));
    auto &vec = registered_driver_vector();
    for (const auto &rd : vec)
      {
        Driver::EntryVec dentries;
        rd.list_ (dentries);
        for (auto &entry : dentries)
          entry.devid = entry.devid.empty() ? rd.driver_id_ : rd.driver_id_ + "=" + entry.devid;
        entries.insert (entries.end(), std::make_move_iterator (dentries.begin()), std::make_move_iterator (dentries.end()));
      }
    std::sort (entries.begin(), entries.end(), [] (const Driver::Entry &a, const Driver::Entry &b) {
        return a.priority < b.priority;
      });
    return entries;
  }
};

// == PcmDriver ==
PcmDriver::PcmDriver (const String &devid) :
  Driver (devid)
{}

PcmDriverP
PcmDriver::open (const String &devid, IODir desired, IODir required, const PcmDriverConfig &config, Error *ep)
{
  auto opener =  [&config] (PcmDriverP d, IODir iodir) {
    return d->open (iodir, config);
  };
  if (devid == "auto")
    {
      for (const auto &entry : list_drivers())
        if (entry.priority < PSEUDO &&          // ignore pseudo devices during auto-selection
            !(entry.priority & 0x0000ffff))     // ignore secondary devices during auto-selection
          {
            PcmDriverP pcm_driver = RegisteredDriver<PcmDriverP>::open (entry.devid, desired, ep, opener);
            if (!pcm_driver && required && desired != required)
              pcm_driver = RegisteredDriver<PcmDriverP>::open (entry.devid, required, ep, opener);
            if (pcm_driver)
              return pcm_driver;
          }
    }
  else
    {
      PcmDriverP pcm_driver = RegisteredDriver<PcmDriverP>::open (devid, desired, ep, opener);
      if (!pcm_driver && required && desired != required)
        pcm_driver = RegisteredDriver<PcmDriverP>::open (devid, required, ep, opener);
      if (pcm_driver)
        return pcm_driver;
    }
  return nullptr;
}

String
PcmDriver::register_driver (const String &driverid,
                            const std::function<PcmDriverP (const String&)> &create,
                            const std::function<void (EntryVec&)> &list)
{
  return RegisteredDriver<PcmDriverP>::register_driver (driverid, create, list);
}

Driver::EntryVec
PcmDriver::list_drivers ()
{
  Driver::Entry entry;
  entry.devid = "auto";
  entry.device_name = _("Automatic driver selection");
  entry.device_info = _("Select the first available PCM card or server");
  entry.readonly = false;
  entry.writeonly = false;
  entry.priority = Driver::PAUTO;
  Driver::EntryVec pseudos;
  pseudos.push_back (entry);
  return RegisteredDriver<PcmDriverP>::list_drivers (pseudos);
}

// == MidiDriver ==
MidiDriver::MidiDriver (const String &devid) :
  Driver (devid)
{}

MidiDriverP
MidiDriver::open (const String &devid, IODir iodir, Error *ep)
{
  auto opener = [] (MidiDriverP d, IODir iodir) {
    return d->open (iodir);
  };
  if (devid == "auto")
    {
      for (const auto &entry : list_drivers())
        if (entry.priority < PSEUDO)    // ignore pseudo devices during auto-selection
          {
            MidiDriverP midi_driver = RegisteredDriver<MidiDriverP>::open (entry.devid, iodir, ep, opener);
            if (midi_driver)
              return midi_driver;
          }
    }
  else
    {
      MidiDriverP midi_driver = RegisteredDriver<MidiDriverP>::open (devid, iodir, ep, opener);
      if (midi_driver)
        return midi_driver;
    }
  return nullptr;
}

String
MidiDriver::register_driver (const String &driverid,
                             const std::function<MidiDriverP (const String&)> &create,
                             const std::function<void (EntryVec&)> &list)
{
  return RegisteredDriver<MidiDriverP>::register_driver (driverid, create, list);
}

Driver::EntryVec
MidiDriver::list_drivers ()
{
  Driver::Entry entry;
  entry.devid = "auto";
  entry.device_name = _("Automatic MIDI driver selection");
  entry.device_info = _("Select the first available MIDI device");
  entry.readonly = false;
  entry.writeonly = false;
  entry.priority = Driver::PAUTO;
  Driver::EntryVec pseudos;
  pseudos.push_back (entry);
  return RegisteredDriver<MidiDriverP>::list_drivers (pseudos);
}

// == NullPcmDriver ==
class NullPcmDriver : public PcmDriver {
  uint          n_channels_ = 0;
  uint          mix_freq_ = 0;
  uint          busy_us_ = 0;
  uint          sleep_us_ = 0;
public:
  explicit      NullPcmDriver (const String &devid) : PcmDriver (devid) {}
  static PcmDriverP
  create (const String &devid)
  {
    auto pdriverp = std::make_shared<NullPcmDriver> (devid);
    return pdriverp;
  }
  virtual float
  pcm_frequency () const override
  {
    return mix_freq_;
  }
  virtual void
  close () override
  {
    assert_return (opened());
    flags_ &= ~size_t (Flags::OPENED | Flags::READABLE | Flags::WRITABLE);
  }
  virtual Error
  open (IODir iodir, const PcmDriverConfig &config) override
  {
    assert_return (!opened(), Error::INTERNAL);
    // setup request
    const bool nosleep = true;
    const bool require_readable = iodir == READONLY || iodir == READWRITE;
    const bool require_writable = iodir == WRITEONLY || iodir == READWRITE;
    flags_ |= Flags::READABLE * require_readable;
    flags_ |= Flags::WRITABLE * require_writable;
    n_channels_ = config.n_channels;
    mix_freq_ = config.mix_freq;
    busy_us_ = 0;
    sleep_us_ = nosleep ? 0 : 10 * 1000;
    flags_ |= Flags::OPENED;
    DDEBUG ("NULL-PCM: opening with freq=%f channels=%d: %s", mix_freq_, n_channels_, bse_error_blurb (Error::NONE));
    return Error::NONE;
  }
  virtual bool
  pcm_check_io (long *timeoutp) override
  {
    // keep the sequencer busy or we will constantly timeout
    Sequencer::instance().wakeup();
    *timeoutp = 1;
    // ensure sequencer fairness
    return !Sequencer::instance().thread_lagging (2);
  }
  virtual void
  pcm_latency (uint *rlatency, uint *wlatency) const override
  {
    *rlatency = mix_freq_ / 10;
    *wlatency = mix_freq_ / 10;
  }
  virtual size_t
  pcm_read (size_t n, float *values) override
  {
    memset (values, 0, sizeof (values[0]) * n);
    return n;
  }
  virtual void
  pcm_write (size_t n, const float *values) override
  {
    busy_us_ += n * 1000000 / mix_freq_;
    if (busy_us_ >= 100 * 1000)
      {
        busy_us_ = 0;
        // give cpu to other applications (we might run at nice level -20)
        if (sleep_us_)
          g_usleep (sleep_us_);
      }
  }
  static void
  list_drivers (Driver::EntryVec &entries)
  {
    Driver::Entry entry;
    entry.devid = ""; // "null"
    entry.device_name = "Null PCM Driver";
    entry.device_info = _("Discard all PCM output and provide zeros as PCM input");
    entry.readonly = false;
    entry.writeonly = false;
    entry.priority = Driver::PNULL;
    entries.push_back (entry);
  }
};

static const String null_pcm_driverid = PcmDriver::register_driver ("null", NullPcmDriver::create, NullPcmDriver::list_drivers);

// == NullMidiDriver ==
class NullMidiDriver : public MidiDriver {
public:
  explicit      NullMidiDriver (const String &devid) : MidiDriver (devid) {}
  static MidiDriverP
  create (const String &devid)
  {
    auto pdriverp = std::make_shared<NullMidiDriver> (devid);
    return pdriverp;
  }
  virtual void
  close () override
  {
    assert_return (opened());
    flags_ &= ~size_t (Flags::OPENED | Flags::READABLE | Flags::WRITABLE);
  }
  virtual Error
  open (IODir iodir) override
  {
    assert_return (!opened(), Error::INTERNAL);
    // setup request
    const bool require_readable = iodir == READONLY || iodir == READWRITE;
    const bool require_writable = iodir == WRITEONLY || iodir == READWRITE;
    flags_ |= Flags::READABLE * require_readable;
    flags_ |= Flags::WRITABLE * require_writable;
    flags_ |= Flags::OPENED;
    DDEBUG ("NULL-MIDI: opening: %s", bse_error_blurb (Error::NONE));
    return Error::NONE;
  }
  static void
  list_drivers (Driver::EntryVec &entries)
  {
    Driver::Entry entry;
    entry.devid = ""; // "null"
    entry.device_name = "Null MIDI Driver";
    entry.device_info = _("Discard all MIDI events");
    entry.readonly = false;
    entry.writeonly = false;
    entry.priority = Driver::PNULL;
    entries.push_back (entry);
  }
};

static const String null_midi_driverid = MidiDriver::register_driver ("null", NullMidiDriver::create, NullMidiDriver::list_drivers);

} // Bse

// == libbsejack.so ==
#include <gmodule.h>

static Bse::Error
try_load_libbsejack ()
{
  using namespace Bse;
  const std::string libbsejack = string_format ("%s/lib/libbse-jack-%u.%u.%u.so", runpath (RPath::INSTALLDIR),
                                                BSE_MAJOR_VERSION, BSE_MINOR_VERSION, BSE_MICRO_VERSION);
  if (Path::check (libbsejack, "fr"))
    {
      GModule *gmodule = g_module_open (libbsejack.c_str(), G_MODULE_BIND_LOCAL); // no API import
      if (!gmodule)
        DDEBUG ("loading \"%s\" failed: %s", libbsejack, g_module_error());
    }
  return Error::NONE;
}

static bool *bsejack_loaded = Bse::register_driver_loader ("bsejack", try_load_libbsejack);
<commit_msg>BSE: driver.cc: PCM Null: warn about lack of playback timing<commit_after>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#include "driver.hh"
#include "bsemain.hh"
#include "internal.hh"
#include "bsesequencer.hh"

#define DDEBUG(...)     Bse::debug ("driver", __VA_ARGS__)

namespace Bse {

// == Driver ==
Driver::Driver (const String &devid) :
  devid_ (devid)
{}

Driver::~Driver ()
{}

// == RegisteredDriver ==
template<typename DriverP>
struct RegisteredDriver {
  const String                            driver_id_;
  std::function<DriverP (const String&)>  create_;
  std::function<void (Driver::EntryVec&)> list_;
  using RegisteredDriverVector = std::vector<RegisteredDriver>;
  static RegisteredDriverVector&
  registered_driver_vector()
  {
    static RegisteredDriverVector registered_driver_vector_;
    return registered_driver_vector_;
  }
  static DriverP
  open (const String &devid, Driver::IODir iodir, Error *ep,
        const std::function<Error (DriverP, Driver::IODir)> &opener)
  {
    std::function<DriverP (const String&)> create;
    const String driverid = kvpair_key (devid);
    for (const auto &driver : registered_driver_vector())
      if (driver.driver_id_ == driverid)
        {
          create = driver.create_;
          break;
        }
    Error error = Error::DEVICE_NOT_AVAILABLE;
    DriverP driver = create ? create (kvpair_value (devid)) : NULL;
    if (driver)
      {
        error = opener (driver, iodir);
        if (ep)
          *ep = error;
        if (error == Error::NONE)
          {
            assert_return (driver->opened() == true, nullptr);
            assert_return (!(iodir & Driver::READONLY) || driver->readable(), nullptr);
            assert_return (!(iodir & Driver::WRITEONLY) || driver->writable(), nullptr);
          }
        else
          driver = nullptr;
      }
    else if (ep)
      *ep = error;
    return driver;
  }
  static String
  register_driver (const String &driverid,
                   const std::function<DriverP (const String&)> &create,
                   const std::function<void (Driver::EntryVec&)> &list)
  {
    auto &vec = registered_driver_vector();
    RegisteredDriver rd = { driverid, create, list, };
    vec.push_back (rd);
    return driverid;
  }
  static Driver::EntryVec
  list_drivers (const Driver::EntryVec &pseudos)
  {
    Driver::EntryVec entries;
    std::copy (pseudos.begin(), pseudos.end(), std::back_inserter (entries));
    auto &vec = registered_driver_vector();
    for (const auto &rd : vec)
      {
        Driver::EntryVec dentries;
        rd.list_ (dentries);
        for (auto &entry : dentries)
          entry.devid = entry.devid.empty() ? rd.driver_id_ : rd.driver_id_ + "=" + entry.devid;
        entries.insert (entries.end(), std::make_move_iterator (dentries.begin()), std::make_move_iterator (dentries.end()));
      }
    std::sort (entries.begin(), entries.end(), [] (const Driver::Entry &a, const Driver::Entry &b) {
        return a.priority < b.priority;
      });
    return entries;
  }
};

// == PcmDriver ==
PcmDriver::PcmDriver (const String &devid) :
  Driver (devid)
{}

PcmDriverP
PcmDriver::open (const String &devid, IODir desired, IODir required, const PcmDriverConfig &config, Error *ep)
{
  auto opener =  [&config] (PcmDriverP d, IODir iodir) {
    return d->open (iodir, config);
  };
  if (devid == "auto")
    {
      for (const auto &entry : list_drivers())
        if (entry.priority < PSEUDO &&          // ignore pseudo devices during auto-selection
            !(entry.priority & 0x0000ffff))     // ignore secondary devices during auto-selection
          {
            PcmDriverP pcm_driver = RegisteredDriver<PcmDriverP>::open (entry.devid, desired, ep, opener);
            if (!pcm_driver && required && desired != required)
              pcm_driver = RegisteredDriver<PcmDriverP>::open (entry.devid, required, ep, opener);
            if (pcm_driver)
              return pcm_driver;
          }
    }
  else
    {
      PcmDriverP pcm_driver = RegisteredDriver<PcmDriverP>::open (devid, desired, ep, opener);
      if (!pcm_driver && required && desired != required)
        pcm_driver = RegisteredDriver<PcmDriverP>::open (devid, required, ep, opener);
      if (pcm_driver)
        return pcm_driver;
    }
  return nullptr;
}

String
PcmDriver::register_driver (const String &driverid,
                            const std::function<PcmDriverP (const String&)> &create,
                            const std::function<void (EntryVec&)> &list)
{
  return RegisteredDriver<PcmDriverP>::register_driver (driverid, create, list);
}

Driver::EntryVec
PcmDriver::list_drivers ()
{
  Driver::Entry entry;
  entry.devid = "auto";
  entry.device_name = _("Automatic driver selection");
  entry.device_info = _("Select the first available PCM card or server");
  entry.readonly = false;
  entry.writeonly = false;
  entry.priority = Driver::PAUTO;
  Driver::EntryVec pseudos;
  pseudos.push_back (entry);
  return RegisteredDriver<PcmDriverP>::list_drivers (pseudos);
}

// == MidiDriver ==
MidiDriver::MidiDriver (const String &devid) :
  Driver (devid)
{}

MidiDriverP
MidiDriver::open (const String &devid, IODir iodir, Error *ep)
{
  auto opener = [] (MidiDriverP d, IODir iodir) {
    return d->open (iodir);
  };
  if (devid == "auto")
    {
      for (const auto &entry : list_drivers())
        if (entry.priority < PSEUDO)    // ignore pseudo devices during auto-selection
          {
            MidiDriverP midi_driver = RegisteredDriver<MidiDriverP>::open (entry.devid, iodir, ep, opener);
            if (midi_driver)
              return midi_driver;
          }
    }
  else
    {
      MidiDriverP midi_driver = RegisteredDriver<MidiDriverP>::open (devid, iodir, ep, opener);
      if (midi_driver)
        return midi_driver;
    }
  return nullptr;
}

String
MidiDriver::register_driver (const String &driverid,
                             const std::function<MidiDriverP (const String&)> &create,
                             const std::function<void (EntryVec&)> &list)
{
  return RegisteredDriver<MidiDriverP>::register_driver (driverid, create, list);
}

Driver::EntryVec
MidiDriver::list_drivers ()
{
  Driver::Entry entry;
  entry.devid = "auto";
  entry.device_name = _("Automatic MIDI driver selection");
  entry.device_info = _("Select the first available MIDI device");
  entry.readonly = false;
  entry.writeonly = false;
  entry.priority = Driver::PAUTO;
  Driver::EntryVec pseudos;
  pseudos.push_back (entry);
  return RegisteredDriver<MidiDriverP>::list_drivers (pseudos);
}

// == NullPcmDriver ==
class NullPcmDriver : public PcmDriver {
  uint          n_channels_ = 0;
  uint          mix_freq_ = 0;
  uint          busy_us_ = 0;
  uint          sleep_us_ = 0;
public:
  explicit      NullPcmDriver (const String &devid) : PcmDriver (devid) {}
  static PcmDriverP
  create (const String &devid)
  {
    auto pdriverp = std::make_shared<NullPcmDriver> (devid);
    return pdriverp;
  }
  virtual float
  pcm_frequency () const override
  {
    return mix_freq_;
  }
  virtual void
  close () override
  {
    assert_return (opened());
    flags_ &= ~size_t (Flags::OPENED | Flags::READABLE | Flags::WRITABLE);
  }
  virtual Error
  open (IODir iodir, const PcmDriverConfig &config) override
  {
    assert_return (!opened(), Error::INTERNAL);
    // setup request
    const bool nosleep = true;
    const bool require_readable = iodir == READONLY || iodir == READWRITE;
    const bool require_writable = iodir == WRITEONLY || iodir == READWRITE;
    flags_ |= Flags::READABLE * require_readable;
    flags_ |= Flags::WRITABLE * require_writable;
    n_channels_ = config.n_channels;
    mix_freq_ = config.mix_freq;
    busy_us_ = 0;
    sleep_us_ = nosleep ? 0 : 10 * 1000;
    flags_ |= Flags::OPENED;
    DDEBUG ("NULL-PCM: opening with freq=%f channels=%d: %s", mix_freq_, n_channels_, bse_error_blurb (Error::NONE));
    return Error::NONE;
  }
  virtual bool
  pcm_check_io (long *timeoutp) override
  {
    // keep the sequencer busy or we will constantly timeout
    Sequencer::instance().wakeup();
    *timeoutp = 1;
    // ensure sequencer fairness
    return !Sequencer::instance().thread_lagging (2);
  }
  virtual void
  pcm_latency (uint *rlatency, uint *wlatency) const override
  {
    *rlatency = mix_freq_ / 10;
    *wlatency = mix_freq_ / 10;
  }
  virtual size_t
  pcm_read (size_t n, float *values) override
  {
    memset (values, 0, sizeof (values[0]) * n);
    return n;
  }
  virtual void
  pcm_write (size_t n, const float *values) override
  {
    busy_us_ += n * 1000000 / mix_freq_;
    if (busy_us_ >= 100 * 1000)
      {
        busy_us_ = 0;
        // give cpu to other applications (we might run at nice level -20)
        if (sleep_us_)
          g_usleep (sleep_us_);
      }
  }
  static void
  list_drivers (Driver::EntryVec &entries)
  {
    Driver::Entry entry;
    entry.devid = ""; // "null"
    entry.device_name = "Null PCM Driver";
    entry.device_info = _("Discard all PCM output and provide zeros as PCM input");
    entry.notice = "Warning: The Null driver has no playback timing support";
    entry.readonly = false;
    entry.writeonly = false;
    entry.priority = Driver::PNULL;
    entries.push_back (entry);
  }
};

static const String null_pcm_driverid = PcmDriver::register_driver ("null", NullPcmDriver::create, NullPcmDriver::list_drivers);

// == NullMidiDriver ==
class NullMidiDriver : public MidiDriver {
public:
  explicit      NullMidiDriver (const String &devid) : MidiDriver (devid) {}
  static MidiDriverP
  create (const String &devid)
  {
    auto pdriverp = std::make_shared<NullMidiDriver> (devid);
    return pdriverp;
  }
  virtual void
  close () override
  {
    assert_return (opened());
    flags_ &= ~size_t (Flags::OPENED | Flags::READABLE | Flags::WRITABLE);
  }
  virtual Error
  open (IODir iodir) override
  {
    assert_return (!opened(), Error::INTERNAL);
    // setup request
    const bool require_readable = iodir == READONLY || iodir == READWRITE;
    const bool require_writable = iodir == WRITEONLY || iodir == READWRITE;
    flags_ |= Flags::READABLE * require_readable;
    flags_ |= Flags::WRITABLE * require_writable;
    flags_ |= Flags::OPENED;
    DDEBUG ("NULL-MIDI: opening: %s", bse_error_blurb (Error::NONE));
    return Error::NONE;
  }
  static void
  list_drivers (Driver::EntryVec &entries)
  {
    Driver::Entry entry;
    entry.devid = ""; // "null"
    entry.device_name = "Null MIDI Driver";
    entry.device_info = _("Discard all MIDI events");
    entry.readonly = false;
    entry.writeonly = false;
    entry.priority = Driver::PNULL;
    entries.push_back (entry);
  }
};

static const String null_midi_driverid = MidiDriver::register_driver ("null", NullMidiDriver::create, NullMidiDriver::list_drivers);

} // Bse

// == libbsejack.so ==
#include <gmodule.h>

static Bse::Error
try_load_libbsejack ()
{
  using namespace Bse;
  const std::string libbsejack = string_format ("%s/lib/libbse-jack-%u.%u.%u.so", runpath (RPath::INSTALLDIR),
                                                BSE_MAJOR_VERSION, BSE_MINOR_VERSION, BSE_MICRO_VERSION);
  if (Path::check (libbsejack, "fr"))
    {
      GModule *gmodule = g_module_open (libbsejack.c_str(), G_MODULE_BIND_LOCAL); // no API import
      if (!gmodule)
        DDEBUG ("loading \"%s\" failed: %s", libbsejack, g_module_error());
    }
  return Error::NONE;
}

static bool *bsejack_loaded = Bse::register_driver_loader ("bsejack", try_load_libbsejack);
<|endoftext|>


<commit_before>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#ifndef __BSE_DRIVER_HH__
#define __BSE_DRIVER_HH__

#include <bse/bseutils.hh>
#include <functional>

namespace Bse {

class Driver {
protected:
  struct Flags { enum { OPENED = 1, READABLE = 2, WRITABLE = 4, }; };
  const String       devid_;
  size_t             flags_ = 0;
  explicit           Driver     (const String &devid);
  virtual           ~Driver     ();
public:
  enum {
    JACK     = 0x01 << 24,
    ALSA_USB = 0x03 << 24,
    ALSA     = 0x04 << 24,
    OSS      = 0x07 << 24,
    PULSE    = 0x08 << 24,
    PSEUDO   = 0x70 << 24,
    PAUTO    = 0x74 << 24,
    PNULL    = 0x77 << 24,
    WCARD    = 0x01 << 16,
    WDEV     = 0x01 <<  8,
    WSUB     = 0x01 <<  0,
  };
  enum IODir { READONLY = 1, WRITEONLY = 2, READWRITE = 3 };
  typedef std::shared_ptr<Driver> DriverP;
  bool           opened        () const        { return flags_ & Flags::OPENED; }
  bool           readable      () const        { return flags_ & Flags::READABLE; }
  bool           writable      () const        { return flags_ & Flags::WRITABLE; }
  virtual String devid         () const        { return devid_; }
  virtual void   close         () = 0;
  // registry
  using Entry = DriverEntry;
  using EntryVec = DriverEntrySeq;
};
using DriverP = Driver::DriverP;

class MidiDriver : public Driver {
protected:
  explicit           MidiDriver      (const String &devid);
  virtual Bse::Error open            (IODir iodir) = 0;
public:
  typedef std::shared_ptr<MidiDriver> MidiDriverP;
  static MidiDriverP open            (const String &devid, IODir iodir, Bse::Error *ep);
  static EntryVec    list_drivers    ();
  static String      register_driver (const String &driverid,
                                      const std::function<MidiDriverP (const String&)> &create,
                                      const std::function<void (EntryVec&)> &list);
};
using MidiDriverP = MidiDriver::MidiDriverP;

struct PcmDriverConfig {
  uint n_channels = 0;
  uint mix_freq = 0;
  uint latency_ms = 0;
  uint block_length = 0;
};

class PcmDriver : public Driver {
protected:
  explicit           PcmDriver       (const String &devid);
  virtual Bse::Error open            (IODir iodir, const PcmDriverConfig &config) = 0;
public:
  typedef std::shared_ptr<PcmDriver> PcmDriverP;
  static PcmDriverP  open            (const String &devid, IODir desired, IODir required, const PcmDriverConfig &config, Bse::Error *ep);
  virtual bool       pcm_check_io    (long *timeoutp) = 0;
  virtual void       pcm_latency     (uint *rlatency, uint *wlatency) const = 0;
  virtual float      pcm_frequency   () const = 0;
  virtual uint       block_length    () const = 0;
  virtual size_t     pcm_read        (size_t n, float *values) = 0;
  virtual void       pcm_write       (size_t n, const float *values) = 0;
  static EntryVec    list_drivers    ();
  static String      register_driver (const String &driverid,
                                      const std::function<PcmDriverP (const String&)> &create,
                                      const std::function<void (EntryVec&)> &list);
};
using PcmDriverP = PcmDriver::PcmDriverP;

} // Bse

#endif  // __BSE_DRIVER_HH__
<commit_msg>BSE: driver.hh: add shared_from_base() to Driver<commit_after>// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0
#ifndef __BSE_DRIVER_HH__
#define __BSE_DRIVER_HH__

#include <bse/bseutils.hh>
#include <functional>

namespace Bse {

class Driver : public std::enable_shared_from_this<Driver> {
protected:
  struct Flags { enum { OPENED = 1, READABLE = 2, WRITABLE = 4, }; };
  const String       devid_;
  size_t             flags_ = 0;
  explicit           Driver     (const String &devid);
  virtual           ~Driver     ();
  template<class Derived> std::shared_ptr<Derived>
  /**/               shared_from_base () { return std::static_pointer_cast<Derived> (shared_from_this()); }
public:
  enum {
    JACK     = 0x01 << 24,
    ALSA_USB = 0x03 << 24,
    ALSA     = 0x04 << 24,
    OSS      = 0x07 << 24,
    PULSE    = 0x08 << 24,
    PSEUDO   = 0x70 << 24,
    PAUTO    = 0x74 << 24,
    PNULL    = 0x77 << 24,
    WCARD    = 0x01 << 16,
    WDEV     = 0x01 <<  8,
    WSUB     = 0x01 <<  0,
  };
  enum IODir { READONLY = 1, WRITEONLY = 2, READWRITE = 3 };
  typedef std::shared_ptr<Driver> DriverP;
  bool           opened        () const        { return flags_ & Flags::OPENED; }
  bool           readable      () const        { return flags_ & Flags::READABLE; }
  bool           writable      () const        { return flags_ & Flags::WRITABLE; }
  virtual String devid         () const        { return devid_; }
  virtual void   close         () = 0;
  // registry
  using Entry = DriverEntry;
  using EntryVec = DriverEntrySeq;
};
using DriverP = Driver::DriverP;

class MidiDriver : public Driver {
protected:
  explicit           MidiDriver      (const String &devid);
  virtual Bse::Error open            (IODir iodir) = 0;
public:
  typedef std::shared_ptr<MidiDriver> MidiDriverP;
  static MidiDriverP open            (const String &devid, IODir iodir, Bse::Error *ep);
  static EntryVec    list_drivers    ();
  static String      register_driver (const String &driverid,
                                      const std::function<MidiDriverP (const String&)> &create,
                                      const std::function<void (EntryVec&)> &list);
};
using MidiDriverP = MidiDriver::MidiDriverP;

struct PcmDriverConfig {
  uint n_channels = 0;
  uint mix_freq = 0;
  uint latency_ms = 0;
  uint block_length = 0;
};

class PcmDriver : public Driver {
protected:
  explicit           PcmDriver       (const String &devid);
  virtual Bse::Error open            (IODir iodir, const PcmDriverConfig &config) = 0;
public:
  typedef std::shared_ptr<PcmDriver> PcmDriverP;
  static PcmDriverP  open            (const String &devid, IODir desired, IODir required, const PcmDriverConfig &config, Bse::Error *ep);
  virtual bool       pcm_check_io    (long *timeoutp) = 0;
  virtual void       pcm_latency     (uint *rlatency, uint *wlatency) const = 0;
  virtual float      pcm_frequency   () const = 0;
  virtual uint       block_length    () const = 0;
  virtual size_t     pcm_read        (size_t n, float *values) = 0;
  virtual void       pcm_write       (size_t n, const float *values) = 0;
  static EntryVec    list_drivers    ();
  static String      register_driver (const String &driverid,
                                      const std::function<PcmDriverP (const String&)> &create,
                                      const std::function<void (EntryVec&)> &list);
};
using PcmDriverP = PcmDriver::PcmDriverP;

} // Bse

#endif  // __BSE_DRIVER_HH__
<|endoftext|>


<commit_before>AliAnalysisVertexingHF* ConfigVertexingHF() {

  printf("Call to AliAnalysisVertexingHF parameters setting :\n");
  vHF = new AliAnalysisVertexingHF();

  //--- switch-off candidates finding (default: all on)
  //vHF->SetD0toKpiOff();
  vHF->SetJPSItoEleOff();
  //vHF->Set3ProngOff();
  //vHF->SetLikeSignOn(); // like-sign pairs and triplets
  vHF->Set4ProngOff();
  vHF->SetDstarOff();
  vHF->SetFindVertexForDstar(kFALSE);
  //--- secondary vertex with KF?
  //vHF->SetSecVtxWithKF();
  vHF->SetCascadesOff();
  vHF->SetFindVertexForCascades(kFALSE);

  //--- set cuts for single-track selection
  //     displaced tracks
  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts","default");
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetMinNClustersTPC(70);
  esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetMinNClustersITS(4);
  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
					 AliESDtrackCuts::kAny);
  esdTrackCuts->SetMinDCAToVertexXY(0.0100);
  esdTrackCuts->SetPtRange(0.8,1.e10);
  esdTrackCuts->SetEtaRange(-0.8,+0.8);
  AliAnalysisFilter *trkFilter = new AliAnalysisFilter("trackFilter");
  trkFilter->AddCuts(esdTrackCuts);
  vHF->SetTrackFilter(trkFilter);
  //     D* soft pion tracks
  AliESDtrackCuts *esdTrackCutsSoftPi = new AliESDtrackCuts("AliESDtrackCuts","default");
  esdTrackCutsSoftPi->SetMinNClustersITS(4);
  esdTrackCuts->SetPtRange(0.2,1.e10);
  esdTrackCutsSoftPi->SetEtaRange(-0.8,+0.8);
  AliAnalysisFilter *trkFilterSoftPi = new AliAnalysisFilter("trackFilterSoftPi");
  trkFilterSoftPi->AddCuts(esdTrackCutsSoftPi);
  vHF->SetTrackFilterSoftPi(trkFilterSoftPi);
  //--- set cuts for candidates selection
  AliRDHFCutsD0toKpi *cutsD0toKpi = new AliRDHFCutsD0toKpi("CutsD0toKpi");
  Float_t cutsArrayD0toKpi[9]={0.2,999999.,1.1,0.,0.,999999.,999999.,0.,0.5};
  cutsD0toKpi->SetCuts(9,cutsArrayD0toKpi);
  cutsD0toKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsD0toKpi(cutsD0toKpi);
  AliRDHFCutsJpsitoee *cutsJpsitoee = new AliRDHFCutsJpsitoee("CutsJpsitoee");
  Float_t cutsArrayJpsitoee[9]={0.350,100000.,1.1,0.,0.,100000.,100000.,100000000.,-1.1};
  cutsJpsitoee->SetCuts(9,cutsArrayJpsitoee);
  cutsJpsitoee->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsJpsitoee(cutsJpsitoee);
  AliRDHFCutsDplustoKpipi *cutsDplustoKpipi = new AliRDHFCutsDplustoKpipi("CutsDplustoKpipi");
  Float_t cutsArrayDplustoKpipi[12]={0.2,0.8,0.8,0.,0.,0.01,0.06,0.03,0.,0.85,0.,10000000000.};
  cutsDplustoKpipi->SetCuts(12,cutsArrayDplustoKpipi);
  cutsDplustoKpipi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsDplustoKpipi(cutsDplustoKpipi);
  AliRDHFCutsDstoKKpi *cutsDstoKKpi = new AliRDHFCutsDstoKKpi("CutsDstoKKpi");
  Float_t cutsArrayDstoKKpi[14]={0.,999.,999.,0.,0.,0.005,0.06,0.,0.,0.7,0.,1000.,0.1,0.1};
  cutsDstoKKpi->SetCuts(14,cutsArrayDstoKKpi);
  cutsDstoKKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsDstoKKpi(cutsDstoKKpi);
  AliRDHFCutsLctopKpi *cutsLctopKpi = new AliRDHFCutsLctopKpi("CutsLctopKpi");
  //Float_t cutsArrayLctopKpi[12]={0.2,0.4,0.4,0.,0.,0.01,0.06,0.02,0.,0.85,0.,10000000000.};
  Float_t cutsArrayLctopKpi[12]={0.,999.,999.,0.,0.,0.01,0.06,0.005,0.7,0.,0.,0.05};
  cutsLctopKpi->SetCuts(12,cutsArrayLctopKpi);
  cutsLctopKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsLctopKpi(cutsLctopKpi);
  AliRDHFCutsD0toKpipipi *cutsD0toKpipipi = new AliRDHFCutsD0toKpipipi("CutsD0toKpipipi");
  Float_t cutsArrayD0toKpipipi[9]={0.2,0.04,0.00,0.01,0.02,0.8,0.,0.1,0.};
  cutsD0toKpipipi->SetCuts(9,cutsArrayD0toKpipipi);
  cutsD0toKpipipi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsD0toKpipipi(cutsD0toKpipipi);
  AliRDHFCutsDStartoKpipi *cutsDStartoKpipi = new AliRDHFCutsDStartoKpipi("CutsDStartoKpipi");
  Float_t cutsArrayDStartoKpipi[14]={0.15,0.07.,0.85,0.8,0.8,0.06.,0.06.,0.001,0.6,0.15, 0.03, 0.2, 5, 0.5}; // first 9 for D0 from D*, last 5 for D*
  cutsDStartoKpipi->SetCuts(14,cutsArrayDStartoKpipi);
  cutsDStartoKpipi->AddTrackCuts(esdTrackCuts);
  cutsDStartoKpipi->AddTrackCutsSoftPi(esdTrackCutsSoftPi);
  vHF->SetCutsDStartoKpipi(cutsDStartoKpipi);
  AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0("CutsLctoV0");
  Float_t cutsArrayLctoV0[9]={4.0,4.0,2.0,2.0,0.0,0.0,0.0,1000.,1000.};
  cutsLctoV0->SetCuts(9,cutsArrayLctoV0);
  cutsLctoV0->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsLctoV0(cutsLctoV0);
  //
  //--- set this if you want to reconstruct primary vertex candidate by
  //    candidate using other tracks in the event (for pp, broad
  //    interaction region)
  //vHF->SetRecoPrimVtxSkippingTrks();
  //--- OR set this if you want to remove the candidate daughters from
  //    the primary vertex, without recostructing it from scratch
  //vHF->SetRmTrksFromPrimVtx();

  //--- check the settings
  vHF->PrintStatus();
  //--- verbose
  //  AliLog::SetClassDebugLevel("AliAnalysisVertexingHF",2);

  return vHF;
}

<commit_msg>Enable D*<commit_after>AliAnalysisVertexingHF* ConfigVertexingHF() {

  printf("Call to AliAnalysisVertexingHF parameters setting :\n");
  vHF = new AliAnalysisVertexingHF();

  //--- switch-off candidates finding (default: all on)
  //vHF->SetD0toKpiOff();
  vHF->SetJPSItoEleOff();
  //vHF->Set3ProngOff();
  //vHF->SetLikeSignOn(); // like-sign pairs and triplets
  vHF->Set4ProngOff();
  //vHF->SetDstarOff();
  vHF->SetFindVertexForDstar(kFALSE);
  //--- secondary vertex with KF?
  //vHF->SetSecVtxWithKF();
  vHF->SetCascadesOff();
  vHF->SetFindVertexForCascades(kFALSE);

  //--- set cuts for single-track selection
  //     displaced tracks
  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts","default");
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetMinNClustersTPC(70);
  esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetMinNClustersITS(4);
  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
					 AliESDtrackCuts::kAny);
  esdTrackCuts->SetMinDCAToVertexXY(0.0100);
  esdTrackCuts->SetPtRange(0.8,1.e10);
  esdTrackCuts->SetEtaRange(-0.8,+0.8);
  AliAnalysisFilter *trkFilter = new AliAnalysisFilter("trackFilter");
  trkFilter->AddCuts(esdTrackCuts);
  vHF->SetTrackFilter(trkFilter);
  //     D* soft pion tracks
  AliESDtrackCuts *esdTrackCutsSoftPi = new AliESDtrackCuts("AliESDtrackCuts","default");
  esdTrackCutsSoftPi->SetMinNClustersITS(4);
  esdTrackCuts->SetPtRange(0.2,1.e10);
  esdTrackCutsSoftPi->SetEtaRange(-0.8,+0.8);
  AliAnalysisFilter *trkFilterSoftPi = new AliAnalysisFilter("trackFilterSoftPi");
  trkFilterSoftPi->AddCuts(esdTrackCutsSoftPi);
  vHF->SetTrackFilterSoftPi(trkFilterSoftPi);
  //--- set cuts for candidates selection
  AliRDHFCutsD0toKpi *cutsD0toKpi = new AliRDHFCutsD0toKpi("CutsD0toKpi");
  Float_t cutsArrayD0toKpi[9]={0.2,999999.,1.1,0.,0.,999999.,999999.,0.,0.5};
  cutsD0toKpi->SetCuts(9,cutsArrayD0toKpi);
  cutsD0toKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsD0toKpi(cutsD0toKpi);
  AliRDHFCutsJpsitoee *cutsJpsitoee = new AliRDHFCutsJpsitoee("CutsJpsitoee");
  Float_t cutsArrayJpsitoee[9]={0.350,100000.,1.1,0.,0.,100000.,100000.,100000000.,-1.1};
  cutsJpsitoee->SetCuts(9,cutsArrayJpsitoee);
  cutsJpsitoee->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsJpsitoee(cutsJpsitoee);
  AliRDHFCutsDplustoKpipi *cutsDplustoKpipi = new AliRDHFCutsDplustoKpipi("CutsDplustoKpipi");
  Float_t cutsArrayDplustoKpipi[12]={0.2,0.8,0.8,0.,0.,0.01,0.06,0.03,0.,0.85,0.,10000000000.};
  cutsDplustoKpipi->SetCuts(12,cutsArrayDplustoKpipi);
  cutsDplustoKpipi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsDplustoKpipi(cutsDplustoKpipi);
  AliRDHFCutsDstoKKpi *cutsDstoKKpi = new AliRDHFCutsDstoKKpi("CutsDstoKKpi");
  Float_t cutsArrayDstoKKpi[14]={0.,999.,999.,0.,0.,0.005,0.06,0.,0.,0.7,0.,1000.,0.1,0.1};
  cutsDstoKKpi->SetCuts(14,cutsArrayDstoKKpi);
  cutsDstoKKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsDstoKKpi(cutsDstoKKpi);
  AliRDHFCutsLctopKpi *cutsLctopKpi = new AliRDHFCutsLctopKpi("CutsLctopKpi");
  //Float_t cutsArrayLctopKpi[12]={0.2,0.4,0.4,0.,0.,0.01,0.06,0.02,0.,0.85,0.,10000000000.};
  Float_t cutsArrayLctopKpi[12]={0.,999.,999.,0.,0.,0.01,0.06,0.005,0.7,0.,0.,0.05};
  cutsLctopKpi->SetCuts(12,cutsArrayLctopKpi);
  cutsLctopKpi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsLctopKpi(cutsLctopKpi);
  AliRDHFCutsD0toKpipipi *cutsD0toKpipipi = new AliRDHFCutsD0toKpipipi("CutsD0toKpipipi");
  Float_t cutsArrayD0toKpipipi[9]={0.2,0.04,0.00,0.01,0.02,0.8,0.,0.1,0.};
  cutsD0toKpipipi->SetCuts(9,cutsArrayD0toKpipipi);
  cutsD0toKpipipi->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsD0toKpipipi(cutsD0toKpipipi);
  AliRDHFCutsDStartoKpipi *cutsDStartoKpipi = new AliRDHFCutsDStartoKpipi("CutsDStartoKpipi");
  Float_t cutsArrayDStartoKpipi[14]={0.15,0.07.,0.85,0.8,0.8,0.06.,0.06.,0.001,0.6,0.15, 0.03, 0.2, 5, 0.5}; // first 9 for D0 from D*, last 5 for D*
  cutsDStartoKpipi->SetCuts(14,cutsArrayDStartoKpipi);
  cutsDStartoKpipi->AddTrackCuts(esdTrackCuts);
  cutsDStartoKpipi->AddTrackCutsSoftPi(esdTrackCutsSoftPi);
  vHF->SetCutsDStartoKpipi(cutsDStartoKpipi);
  AliRDHFCutsLctoV0 *cutsLctoV0 = new AliRDHFCutsLctoV0("CutsLctoV0");
  Float_t cutsArrayLctoV0[9]={4.0,4.0,2.0,2.0,0.0,0.0,0.0,1000.,1000.};
  cutsLctoV0->SetCuts(9,cutsArrayLctoV0);
  cutsLctoV0->AddTrackCuts(esdTrackCuts);
  vHF->SetCutsLctoV0(cutsLctoV0);
  //
  //--- set this if you want to reconstruct primary vertex candidate by
  //    candidate using other tracks in the event (for pp, broad
  //    interaction region)
  //vHF->SetRecoPrimVtxSkippingTrks();
  //--- OR set this if you want to remove the candidate daughters from
  //    the primary vertex, without recostructing it from scratch
  //vHF->SetRmTrksFromPrimVtx();

  //--- check the settings
  vHF->PrintStatus();
  //--- verbose
  //  AliLog::SetClassDebugLevel("AliAnalysisVertexingHF",2);

  return vHF;
}

<|endoftext|>


<commit_before>
//
// Calculate flow in the forward and central regions using the Q cumulants method.
//
// Inputs:
//  - AliAODEvent
//
// Outputs:
//  - AnalysisResults.root or forward_flow.root
//
#include <iostream>
#include <TROOT.h>
#include <TSystem.h>
#include <TList.h>
#include <THn.h>

#include "AliAnalysisManager.h"
#include "AliInputEventHandler.h"

#include "AliAODEvent.h"
#include "AliMCEvent.h"

#include "AliForwardFlowRun2Task.h"
#include "AliForwardQCumulantRun2.h"
#include "AliForwardGenericFramework.h"
#include "AliForwardFlowUtil.h"
#include "AliAODForwardMult.h"

using namespace std;
ClassImp(AliForwardFlowRun2Task)
#if 0
; // For emacs
#endif

//_____________________________________________________________________
AliForwardFlowRun2Task::AliForwardFlowRun2Task() : AliAnalysisTaskSE(),
  fAOD(0),           // input event
  fOutputList(0),    // output list
  fAnalysisList(0),
  fEventList(0),
  fRandom(0),
  centralDist(),
  refDist(),
  forwardDist(),
  fStorage(nullptr),
  fSettings(),
  fUtil(),
  fCalculator()
  {
  //
  //  Default constructor
  //
  }

//_____________________________________________________________________
AliForwardFlowRun2Task::AliForwardFlowRun2Task(const char* name) : AliAnalysisTaskSE(name),
  fAOD(0),           // input event
  fOutputList(0),    // output list
  fAnalysisList(0),
  fEventList(0),
  fRandom(0),
  centralDist(),
  refDist(),
  forwardDist(),
  fStorage(nullptr),
  fSettings(),
  fUtil(),
  fCalculator()
  {
  //
  //  Constructor
  //
  //  Parameters:
  //   name: Name of task
  //

  // Rely on validation task for event and track selection
  DefineInput(1, AliForwardTaskValidation::Class());

  DefineOutput(1, AliForwardFlowResultStorage::Class());
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::UserCreateOutputObjects()
{
  //
  //  Create output objects
  //
  //bool saveAutoAdd = TH1::AddDirectoryStatus();

  fOutputList = new TList();          // the final output list
  fOutputList->SetOwner(kTRUE);       // memory stuff: the list is owner of all objects it contains and will delete them if requested

  TRandom r = TRandom();              // random integer to use for creation of samples (used for error bars).
                                      // Needs to be created here, otherwise it will draw the same random number.

  fAnalysisList    = new TList();
  fAnalysisList   ->SetName("cumulants");

  fOutputList->Add(fAnalysisList);

  // do analysis from v_2 to a maximum of v_5
  constexpr Int_t dimensions = 7;
  Int_t ptnmax =  (fSettings.doPt ? 5 : 0);

  // create a THn for each harmonic
  Int_t rbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNRefEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.rW4Four)} ; // n, pt, s, zvtx,eta,cent,kind
  Double_t rmin[dimensions] = {0,0, 0,fSettings.fZVtxAcceptanceLowEdge, fSettings.fEtaLowEdge, 0, 1};
  Double_t rmax[dimensions] = {4,double(ptnmax+1),double(fSettings.fnoSamples),fSettings.fZVtxAcceptanceUpEdge, fSettings.fEtaUpEdge, 100, static_cast<Double_t>(fSettings.kW4Four)+1};

  fAnalysisList->Add(new THnD("reference", "reference", dimensions, rbins, rmin, rmax));

  Int_t std_dbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNDiffEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.dW4Four)} ;
  Int_t mixed_dbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNDiffEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.dWTwoTwoD)} ;
  Double_t dmin[dimensions] = {0,0, 0,fSettings.fZVtxAcceptanceLowEdge, fSettings.fEtaLowEdge, 0, 1};
  Double_t dmax[dimensions] = {4,double(ptnmax+1),double(fSettings.fnoSamples),fSettings.fZVtxAcceptanceUpEdge, fSettings.fEtaUpEdge, 100, static_cast<Double_t>(fSettings.dW4Four)+1};

  fAnalysisList->Add(new THnD("standard_differential","standard_differential", dimensions, std_dbins, dmin, dmax));
  fAnalysisList->Add(new THnD("mixed_differential","mixed_differential", dimensions, mixed_dbins, dmin, dmax));

  // The THn has dimensions [n, pt, random samples, vertex position, eta, centrality, kind of variable to store]
  // set names
  THnD* reference = static_cast<THnD*>(fAnalysisList->At(0));
  reference->GetAxis(0)->SetName("n");
  reference->GetAxis(1)->SetName("pt");
  reference->GetAxis(2)->SetName("samples");
  reference->GetAxis(3)->SetName("vertex");
  reference->GetAxis(4)->SetName("eta");
  reference->GetAxis(5)->SetName("cent");
  reference->GetAxis(6)->SetName("identifier");

  THnD* standard_differential = static_cast<THnD*>(fAnalysisList->At(1));
  standard_differential->GetAxis(0)->SetName("n");
  standard_differential->GetAxis(1)->SetName("pt");
  standard_differential->GetAxis(2)->SetName("samples");
  standard_differential->GetAxis(3)->SetName("vertex");
  standard_differential->GetAxis(4)->SetName("eta");
  standard_differential->GetAxis(5)->SetName("cent");
  standard_differential->GetAxis(6)->SetName("identifier");

  THnD* mixed_differential = static_cast<THnD*>(fAnalysisList->At(2));
  mixed_differential->GetAxis(0)->SetName("n");
  mixed_differential->GetAxis(1)->SetName("pt");
  mixed_differential->GetAxis(2)->SetName("samples");
  mixed_differential->GetAxis(3)->SetName("vertex");
  mixed_differential->GetAxis(4)->SetName("eta");
  mixed_differential->GetAxis(5)->SetName("cent");
  mixed_differential->GetAxis(6)->SetName("identifier");

  // Make centralDist
  Int_t   centralEtaBins = (fSettings.useITS ? 200 : 400);
  Int_t   centralPhiBins = (fSettings.useITS ? 20 : 400);
  Double_t centralEtaMin = (fSettings.useSPD ? -2.5 : fSettings.useITS ? -4 : -1.5);
  Double_t centralEtaMax = (fSettings.useSPD ? 2.5 : fSettings.useITS ? 6 : 1.5);

  // Make refDist
  Int_t   refEtaBins = (((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 200 : 400);
  Int_t   refPhiBins = (((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 20  : 400);
  Double_t refEtaMin = ((fSettings.ref_mode & fSettings.kSPDref) ? -2.5
                             : ((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? -4
                             : -1.5);
  Double_t refEtaMax = ((fSettings.ref_mode & fSettings.kSPDref) ?  2.5
                             : ((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 6
                             : 1.5);

  centralDist = new TH2D("c","",centralEtaBins,centralEtaMin,centralEtaMax,centralPhiBins,0,2*TMath::Pi());
  centralDist ->SetDirectory(0);
  refDist     = new TH2D("r","",refEtaBins,refEtaMin,refEtaMax,refPhiBins,0,2*TMath::Pi());
  refDist     ->SetDirectory(0);
  forwardDist = new TH2D("ft","",200,-4,6,20,0,TMath::TwoPi());
  forwardDist ->SetDirectory(0);

  fStorage = new AliForwardFlowResultStorage(fSettings.fileName, fOutputList);

  PostData(1, fStorage);
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::UserExec(Option_t *)
  {
  //
  //  Analyses the event with use of the helper class AliForwardQCumulantRun2
  //
  //  Parameters:
  //   option: Not used
  //
  //forwardDist = 0;

  fCalculator.fSettings = fSettings;
  fUtil.fSettings = fSettings;

  // Get the event validation object
  AliForwardTaskValidation* ev_val = dynamic_cast<AliForwardTaskValidation*>(this->GetInputData(1));
  if (!ev_val->IsValidEvent()){
  //  PostData(1, this->fOutputList);
    PostData(1, fStorage);

    return;
  }

  if (!fSettings.esd){
    AliAODEvent* aodevent = dynamic_cast<AliAODEvent*>(InputEvent());
    fUtil.fAODevent = aodevent;
    if(!aodevent) throw std::runtime_error("Not AOD as expected");
  }
  if (fSettings.mc) fUtil.fMCevent = this->MCEvent();

  fUtil.fevent = fInputEvent;

  Double_t cent = fUtil.GetCentrality(fSettings.centrality_estimator);
  // if (cent > 60.0){
  //   //PostData(1, fOutputList);
  //   return;
  // }

  fUtil.FillData(refDist,centralDist,forwardDist);

  // dNdeta
  // for (Int_t etaBin = 1; etaBin <= centralDist->GetNbinsX(); etaBin++) {
  //   Double_t eta = centralDist->GetXaxis()->GetBinCenter(etaBin);
  //   for (Int_t phiBin = 1; phiBin <= centralDist->GetNbinsX(); phiBin++) {
  //     fdNdeta->Fill(eta,cent,centralDist->GetBinContent(etaBin,phiBin));
  //   }
  // }
  // for (Int_t etaBin = 1; etaBin <= forwardDist->GetNbinsX(); etaBin++) {
  //   Double_t eta = forwardDist->GetXaxis()->GetBinCenter(etaBin);
  //   for (Int_t phiBin = 1; phiBin <= forwardDist->GetNbinsX(); phiBin++) {
  //     fdNdeta->Fill(eta,cent,forwardDist->GetBinContent(etaBin,phiBin));
  //   }
  // }

  Double_t zvertex = fUtil.GetZ();

  //if (fSettings.makeFakeHoles) fUtil.MakeFakeHoles(*forwardDist);

  //fCent->Fill(cent);
  //fVertex->Fill(zvertex);

  if (fSettings.a5){
    fCalculator.CumulantsAccumulate(forwardDist, cent, zvertex,kTRUE, true,false);
    fCalculator.CumulantsAccumulate(centralDist, cent, zvertex,kFALSE,true,false);
  }
  else{
    if (fSettings.ref_mode & fSettings.kFMDref) fCalculator.CumulantsAccumulate(refDist, cent, zvertex,kTRUE,true,false);
    else fCalculator.CumulantsAccumulate(refDist, cent, zvertex,kFALSE,true,false);
  }
  fCalculator.CumulantsAccumulate(forwardDist, cent, zvertex,kTRUE,false,true);
  fCalculator.CumulantsAccumulate(centralDist, cent, zvertex,kFALSE,false,true);

  UInt_t randomInt = fRandom.Integer(fSettings.fnoSamples);
  fCalculator.saveEvent(fOutputList, cent, zvertex,  randomInt, 0);

  fCalculator.reset();

  centralDist->Reset();

  if (!(fSettings.ref_mode & fSettings.kFMDref) || (fSettings.mc && fSettings.esd)) refDist->Reset();
  if ((fSettings.mc && fSettings.use_primaries_fwd) || (fSettings.mc && fSettings.esd)) {
    forwardDist->Reset();
    refDist->Reset();
  }

  PostData(1, fStorage);
  return;
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::Terminate(Option_t */*option*/)
{
  std::cout << "Terminating" << '\n';
  return;
}

//_____________________________________________________________________
<commit_msg>minor changes<commit_after>
//
// Calculate flow in the forward and central regions using the Q cumulants method.
//
// Inputs:
//  - AliAODEvent
//
// Outputs:
//  - AnalysisResults.root or forward_flow.root
//
#include <iostream>
#include <TROOT.h>
#include <TSystem.h>
#include <TList.h>
#include <THn.h>

#include "AliAnalysisManager.h"
#include "AliInputEventHandler.h"

#include "AliAODEvent.h"
#include "AliMCEvent.h"

#include "AliForwardFlowRun2Task.h"
#include "AliForwardQCumulantRun2.h"
#include "AliForwardGenericFramework.h"
#include "AliForwardFlowUtil.h"
#include "AliAODForwardMult.h"

using namespace std;
ClassImp(AliForwardFlowRun2Task)
#if 0
; // For emacs
#endif

//_____________________________________________________________________
AliForwardFlowRun2Task::AliForwardFlowRun2Task() : AliAnalysisTaskSE(),
  fAOD(0),           // input event
  fOutputList(0),    // output list
  fAnalysisList(0),
  fEventList(0),
  fRandom(0),
  centralDist(),
  refDist(),
  forwardDist(),
  fStorage(nullptr),
  fSettings(),
  fUtil(),
  fCalculator()
  {
  //
  //  Default constructor
  //
  }

//_____________________________________________________________________
AliForwardFlowRun2Task::AliForwardFlowRun2Task(const char* name) : AliAnalysisTaskSE(name),
  fAOD(0),           // input event
  fOutputList(0),    // output list
  fAnalysisList(0),
  fEventList(0),
  fRandom(0),
  centralDist(),
  refDist(),
  forwardDist(),
  fStorage(nullptr),
  fSettings(),
  fUtil(),
  fCalculator()
  {
  //
  //  Constructor
  //
  //  Parameters:
  //   name: Name of task
  //

  // Rely on validation task for event and track selection
  DefineInput(1, AliForwardTaskValidation::Class());

  DefineOutput(1, AliForwardFlowResultStorage::Class());
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::UserCreateOutputObjects()
{
  //
  //  Create output objects
  //
  //bool saveAutoAdd = TH1::AddDirectoryStatus();

  fOutputList = new TList();          // the final output list
  fOutputList->SetOwner(kTRUE);       // memory stuff: the list is owner of all objects it contains and will delete them if requested

  TRandom r = TRandom();              // random integer to use for creation of samples (used for error bars).
                                      // Needs to be created here, otherwise it will draw the same random number.

  fAnalysisList    = new TList();
  fAnalysisList   ->SetName("cumulants");

  fOutputList->Add(fAnalysisList);

  // do analysis from v_2 to a maximum of v_5
  constexpr Int_t dimensions = 7;
  Int_t ptnmax =  (fSettings.doPt ? 5 : 0);

  // create a THn for each harmonic
  Int_t rbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNRefEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.rW4Four)} ; // n, pt, s, zvtx,eta,cent,kind
  Double_t rmin[dimensions] = {0,0, 0,fSettings.fZVtxAcceptanceLowEdge, fSettings.fEtaLowEdge, 0, 1};
  Double_t rmax[dimensions] = {4,double(ptnmax+1),double(fSettings.fnoSamples),fSettings.fZVtxAcceptanceUpEdge, fSettings.fEtaUpEdge, 100, static_cast<Double_t>(fSettings.kW4Four)+1};

  fAnalysisList->Add(new THnD("reference", "reference", dimensions, rbins, rmin, rmax));

  Int_t std_dbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNDiffEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.dW4Four)} ;
  Int_t mixed_dbins[dimensions] = {4,ptnmax + 1,fSettings.fnoSamples, fSettings.fNZvtxBins, fSettings.fNDiffEtaBins, fSettings.fCentBins, static_cast<Int_t>(fSettings.dWTwoTwoD)} ;
  Double_t dmin[dimensions] = {0,0, 0,fSettings.fZVtxAcceptanceLowEdge, fSettings.fEtaLowEdge, 0, 1};
  Double_t dmax[dimensions] = {4,double(ptnmax+1),double(fSettings.fnoSamples),fSettings.fZVtxAcceptanceUpEdge, fSettings.fEtaUpEdge, 100, static_cast<Double_t>(fSettings.dW4Four)+1};
  Double_t dmax_mixed[dimensions] = {4,double(ptnmax+1),double(fSettings.fnoSamples),fSettings.fZVtxAcceptanceUpEdge, fSettings.fEtaUpEdge, 100, static_cast<Double_t>(fSettings.dWTwoTwoD)+1};

  fAnalysisList->Add(new THnD("standard_differential","standard_differential", dimensions, std_dbins, dmin, dmax));
  fAnalysisList->Add(new THnD("mixed_differential","mixed_differential", dimensions, mixed_dbins, dmin, dmax_mixed));

  // The THn has dimensions [n, pt, random samples, vertex position, eta, centrality, kind of variable to store]
  // set names
  THnD* reference = static_cast<THnD*>(fAnalysisList->At(0));
  reference->GetAxis(0)->SetName("n");
  reference->GetAxis(1)->SetName("pt");
  reference->GetAxis(2)->SetName("samples");
  reference->GetAxis(3)->SetName("vertex");
  reference->GetAxis(4)->SetName("eta");
  reference->GetAxis(5)->SetName("cent");
  reference->GetAxis(6)->SetName("identifier");

  THnD* standard_differential = static_cast<THnD*>(fAnalysisList->At(1));
  standard_differential->GetAxis(0)->SetName("n");
  standard_differential->GetAxis(1)->SetName("pt");
  standard_differential->GetAxis(2)->SetName("samples");
  standard_differential->GetAxis(3)->SetName("vertex");
  standard_differential->GetAxis(4)->SetName("eta");
  standard_differential->GetAxis(5)->SetName("cent");
  standard_differential->GetAxis(6)->SetName("identifier");

  THnD* mixed_differential = static_cast<THnD*>(fAnalysisList->At(2));
  mixed_differential->GetAxis(0)->SetName("n");
  mixed_differential->GetAxis(1)->SetName("pt");
  mixed_differential->GetAxis(2)->SetName("samples");
  mixed_differential->GetAxis(3)->SetName("vertex");
  mixed_differential->GetAxis(4)->SetName("eta");
  mixed_differential->GetAxis(5)->SetName("cent");
  mixed_differential->GetAxis(6)->SetName("identifier");

  // Make centralDist
  Int_t   centralEtaBins = (fSettings.useITS ? 200 : 400);
  Int_t   centralPhiBins = (fSettings.useITS ? 20 : 400);
  Double_t centralEtaMin = (fSettings.useSPD ? -2.5 : fSettings.useITS ? -4 : -1.5);
  Double_t centralEtaMax = (fSettings.useSPD ? 2.5 : fSettings.useITS ? 6 : 1.5);

  // Make refDist
  Int_t   refEtaBins = (((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 200 : 400);
  Int_t   refPhiBins = (((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 20  : 400);
  Double_t refEtaMin = ((fSettings.ref_mode & fSettings.kSPDref) ? -2.5
                             : ((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? -4
                             : -1.5);
  Double_t refEtaMax = ((fSettings.ref_mode & fSettings.kSPDref) ?  2.5
                             : ((fSettings.ref_mode & fSettings.kITSref) | (fSettings.ref_mode & fSettings.kFMDref)) ? 6
                             : 1.5);

  centralDist = new TH2D("c","",centralEtaBins,centralEtaMin,centralEtaMax,centralPhiBins,0,2*TMath::Pi());
  centralDist ->SetDirectory(0);
  refDist     = new TH2D("r","",refEtaBins,refEtaMin,refEtaMax,refPhiBins,0,2*TMath::Pi());
  refDist     ->SetDirectory(0);
  forwardDist = new TH2D("ft","",200,-4,6,20,0,TMath::TwoPi());
  forwardDist ->SetDirectory(0);

  fStorage = new AliForwardFlowResultStorage(fSettings.fileName, fOutputList);

  PostData(1, fStorage);
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::UserExec(Option_t *)
  {
  //
  //  Analyses the event with use of the helper class AliForwardQCumulantRun2
  //
  //  Parameters:
  //   option: Not used
  //
  //forwardDist = 0;

  fCalculator.fSettings = fSettings;
  fUtil.fSettings = fSettings;

  // Get the event validation object
  AliForwardTaskValidation* ev_val = dynamic_cast<AliForwardTaskValidation*>(this->GetInputData(1));
  if (!ev_val->IsValidEvent()){
  //  PostData(1, this->fOutputList);
    PostData(1, fStorage);

    return;
  }

  if (!fSettings.esd){
    AliAODEvent* aodevent = dynamic_cast<AliAODEvent*>(InputEvent());
    fUtil.fAODevent = aodevent;
    if(!aodevent) throw std::runtime_error("Not AOD as expected");
  }
  if (fSettings.mc) fUtil.fMCevent = this->MCEvent();

  fUtil.fevent = fInputEvent;

  Double_t cent = fUtil.GetCentrality(fSettings.centrality_estimator);
  // if (cent > 60.0){
  //   //PostData(1, fOutputList);
  //   return;
  // }

  fUtil.FillData(refDist,centralDist,forwardDist);

  // dNdeta
  // for (Int_t etaBin = 1; etaBin <= centralDist->GetNbinsX(); etaBin++) {
  //   Double_t eta = centralDist->GetXaxis()->GetBinCenter(etaBin);
  //   for (Int_t phiBin = 1; phiBin <= centralDist->GetNbinsX(); phiBin++) {
  //     fdNdeta->Fill(eta,cent,centralDist->GetBinContent(etaBin,phiBin));
  //   }
  // }
  // for (Int_t etaBin = 1; etaBin <= forwardDist->GetNbinsX(); etaBin++) {
  //   Double_t eta = forwardDist->GetXaxis()->GetBinCenter(etaBin);
  //   for (Int_t phiBin = 1; phiBin <= forwardDist->GetNbinsX(); phiBin++) {
  //     fdNdeta->Fill(eta,cent,forwardDist->GetBinContent(etaBin,phiBin));
  //   }
  // }

  Double_t zvertex = fUtil.GetZ();

  //if (fSettings.makeFakeHoles) fUtil.MakeFakeHoles(*forwardDist);

  //fCent->Fill(cent);
  //fVertex->Fill(zvertex);

  if (fSettings.a5){
    fCalculator.CumulantsAccumulate(forwardDist, cent, zvertex,kTRUE, true,false);
    fCalculator.CumulantsAccumulate(centralDist, cent, zvertex,kFALSE,true,false);
  }
  else{
    if (fSettings.ref_mode & fSettings.kFMDref) fCalculator.CumulantsAccumulate(refDist, cent, zvertex,kTRUE,true,false);
    else fCalculator.CumulantsAccumulate(refDist, cent, zvertex,kFALSE,true,false);
  }
  fCalculator.CumulantsAccumulate(forwardDist, cent, zvertex,kTRUE,false,true);
  fCalculator.CumulantsAccumulate(centralDist, cent, zvertex,kFALSE,false,true);

  UInt_t randomInt = fRandom.Integer(fSettings.fnoSamples);
  fCalculator.saveEvent(fOutputList, cent, zvertex,  randomInt, 0);

  fCalculator.reset();

  centralDist->Reset();

  if (!(fSettings.ref_mode & fSettings.kFMDref) || (fSettings.mc && fSettings.esd)) refDist->Reset();
  if ((fSettings.mc && fSettings.use_primaries_fwd) || (fSettings.mc && fSettings.esd)) {
    forwardDist->Reset();
    refDist->Reset();
  }

  PostData(1, fStorage);
  return;
}

//_____________________________________________________________________
void AliForwardFlowRun2Task::Terminate(Option_t */*option*/)
{
  std::cout << "Terminating" << '\n';
  return;
}

//_____________________________________________________________________
<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 2000 Stefan Seefeld <stefan@berlin-consortium.org>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */
#ifndef _PSDrawingKit_hh
#define _PSDrawingKit_hh

#include <Warsaw/config.hh>
#include <Warsaw/Raster.hh>
#include <Berlin/KitImpl.hh>
#include <Drawing/DrawingKitBase.hh>
#include <string>
#include <vector>
#include <iostream>

class PSDrawingKit : public DrawingKitBase, public KitImpl
{
public:
  PSDrawingKit(KitFactory *, const Warsaw::Kit::PropertySeq &);
  virtual ~PSDrawingKit();

  virtual void transformation(Warsaw::Transform_ptr t) { DrawingKitBase::transformation(t);}
  virtual Warsaw::Transform_ptr transformation() { return Warsaw::Transform::_duplicate(tr);}
  virtual void clipping(Warsaw::Region_ptr r) { DrawingKitBase::clipping(r);}
  virtual Warsaw::Region_ptr clipping() { return Warsaw::Region::_duplicate(cl);}
//   using DrawingKitBase::foreground;
  virtual void foreground(const Warsaw::Color &c) { DrawingKitBase::foreground(c);}
  virtual Warsaw::Color foreground() { return fg;}
  virtual void lighting(const Warsaw::Color &c) { DrawingKitBase::lighting(c);}
  virtual Warsaw::Color lighting() { return lt;}
  virtual void point_size(Warsaw::Coord c) { DrawingKitBase::point_size(c);}
  virtual Warsaw::Coord point_size() { return ps;}
  virtual void line_width(Warsaw::Coord c) { DrawingKitBase::line_width(c);}
  virtual Warsaw::Coord line_width() { return lw;}
  virtual void line_endstyle(Warsaw::DrawingKit::Endstyle e) { DrawingKitBase::line_endstyle(e);}
  virtual Warsaw::DrawingKit::Endstyle line_endstyle() { return es;}
  virtual void surface_fillstyle(Warsaw::DrawingKit::Fillstyle f) { DrawingKitBase::surface_fillstyle(f);}
  virtual Warsaw::DrawingKit::Fillstyle surface_fillstyle() { return fs;}
  virtual void texture(Warsaw::Raster_ptr r) { DrawingKitBase::texture(r);}
  virtual Warsaw::Raster_ptr texture();

  virtual CORBA::ULong font_size();
  virtual CORBA::ULong font_weight();
  virtual Warsaw::Unistring *font_family();
  virtual Warsaw::Unistring *font_subfamily();
  virtual Warsaw::Unistring *font_fullname();
  virtual Warsaw::Unistring *font_style();
  virtual Warsaw::DrawingKit::FontMetrics font_metrics();
  virtual Warsaw::DrawingKit::GlyphMetrics glyph_metrics(Warsaw::Unichar);
  virtual CORBA::Any *get_font_attribute(const Warsaw::Unistring &);

  virtual void set_transformation(Warsaw::Transform_ptr);
  virtual void set_clipping(Warsaw::Region_ptr);
  virtual void set_foreground(const Warsaw::Color &);
  virtual void set_lighting(const Warsaw::Color &);
  virtual void set_point_size(Warsaw::Coord);
  virtual void set_line_width(Warsaw::Coord);
  virtual void set_line_endstyle(Warsaw::DrawingKit::Endstyle);
  virtual void set_surface_fillstyle(Warsaw::DrawingKit::Fillstyle);
  virtual void set_texture(Warsaw::Raster_ptr);

  virtual void set_font_size(CORBA::ULong);
  virtual void set_font_weight(CORBA::ULong);
  virtual void set_font_family(const Warsaw::Unistring &);
  virtual void set_font_subfamily(const Warsaw::Unistring &);
  virtual void set_font_fullname(const Warsaw::Unistring &);
  virtual void set_font_style(const Warsaw::Unistring &);
  virtual void set_font_attribute(const Warsaw::NVPair &);

  virtual Warsaw::Coord resolution(Warsaw::Axis);
  virtual void draw_path(const Warsaw::Path &);
//   virtual void drawPatch(const Warsaw::Patch &);
  virtual void draw_rectangle(const Warsaw::Vertex &, const Warsaw::Vertex &);
  virtual void draw_quadric(const Warsaw::DrawingKit::Quadric, Warsaw::Coord, Warsaw::Coord);
  virtual void draw_ellipse(const Warsaw::Vertex &, const Warsaw::Vertex &);
  virtual void draw_image(Warsaw::Raster_ptr);
  virtual void allocate_char(Warsaw::Unichar, Warsaw::Graphic::Requisition &);
  virtual void draw_char(Warsaw::Unichar);
  virtual void allocate_text(const Warsaw::Unistring &, Warsaw::Graphic::Requisition &);
  virtual void draw_text(const Warsaw::Unistring &);
  virtual void copy_drawable(Warsaw::Drawable_ptr, Warsaw::PixelCoord, Warsaw::PixelCoord, Warsaw::PixelCoord, Warsaw::PixelCoord);
  virtual void flush();
private:
  Prague::Mutex  mutex;
  Warsaw::Transform_var  tr;
  Warsaw::Region_var     cl;
  Warsaw::Color          fg;
  Warsaw::Color          lt;
  Warsaw::Coord          ps;
  Warsaw::Coord          lw;
  Warsaw::DrawingKit::Endstyle       es;
  Warsaw::DrawingKit::Fillstyle      fs;
};

#endif
<commit_msg>sick of these 'undefined symbol' messages each time I start the server...<commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 2000 Stefan Seefeld <stefan@berlin-consortium.org>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */
#ifndef _PSDrawingKit_hh
#define _PSDrawingKit_hh

#include <Warsaw/config.hh>
#include <Warsaw/Raster.hh>
#include <Berlin/KitImpl.hh>
#include <Drawing/DrawingKitBase.hh>
#include <string>
#include <vector>
#include <iostream>

class PSDrawingKit : public DrawingKitBase, public KitImpl
{
public:
  PSDrawingKit(KitFactory *, const Warsaw::Kit::PropertySeq &);
  virtual ~PSDrawingKit();

  virtual void transformation(Warsaw::Transform_ptr t) { DrawingKitBase::transformation(t);}
  virtual Warsaw::Transform_ptr transformation() { return Warsaw::Transform::_duplicate(tr);}
  virtual void clipping(Warsaw::Region_ptr r) { DrawingKitBase::clipping(r);}
  virtual Warsaw::Region_ptr clipping() { return Warsaw::Region::_duplicate(cl);}
//   using DrawingKitBase::foreground;
  virtual void foreground(const Warsaw::Color &c) { DrawingKitBase::foreground(c);}
  virtual Warsaw::Color foreground() { return fg;}
  virtual void lighting(const Warsaw::Color &c) { DrawingKitBase::lighting(c);}
  virtual Warsaw::Color lighting() { return lt;}
  virtual void point_size(Warsaw::Coord c) { DrawingKitBase::point_size(c);}
  virtual Warsaw::Coord point_size() { return ps;}
  virtual void line_width(Warsaw::Coord c) { DrawingKitBase::line_width(c);}
  virtual Warsaw::Coord line_width() { return lw;}
  virtual void line_endstyle(Warsaw::DrawingKit::Endstyle e) { DrawingKitBase::line_endstyle(e);}
  virtual Warsaw::DrawingKit::Endstyle line_endstyle() { return es;}
  virtual void surface_fillstyle(Warsaw::DrawingKit::Fillstyle f) { DrawingKitBase::surface_fillstyle(f);}
  virtual Warsaw::DrawingKit::Fillstyle surface_fillstyle() { return fs;}
  virtual void texture(Warsaw::Raster_ptr r) { DrawingKitBase::texture(r);}
  virtual Warsaw::Raster_ptr texture() { return Warsaw::Raster::_nil();}

  virtual CORBA::ULong font_size() { return 0;}
  virtual CORBA::ULong font_weight() { return 0;}
  virtual Warsaw::Unistring *font_family() { return 0;}
  virtual Warsaw::Unistring *font_subfamily() { return 0;}
  virtual Warsaw::Unistring *font_fullname() { return 0;}
  virtual Warsaw::Unistring *font_style() { return 0;}
  virtual Warsaw::DrawingKit::FontMetrics font_metrics() { return Warsaw::DrawingKit::FontMetrics();}
  virtual Warsaw::DrawingKit::GlyphMetrics glyph_metrics(Warsaw::Unichar) { return Warsaw::DrawingKit::GlyphMetrics();}
  virtual CORBA::Any *get_font_attribute(const Warsaw::Unistring &) { return new CORBA::Any();}

  virtual void set_transformation(Warsaw::Transform_ptr);
  virtual void set_clipping(Warsaw::Region_ptr);
  virtual void set_foreground(const Warsaw::Color &);
  virtual void set_lighting(const Warsaw::Color &);
  virtual void set_point_size(Warsaw::Coord);
  virtual void set_line_width(Warsaw::Coord);
  virtual void set_line_endstyle(Warsaw::DrawingKit::Endstyle);
  virtual void set_surface_fillstyle(Warsaw::DrawingKit::Fillstyle);
  virtual void set_texture(Warsaw::Raster_ptr);

  virtual void set_font_size(CORBA::ULong);
  virtual void set_font_weight(CORBA::ULong);
  virtual void set_font_family(const Warsaw::Unistring &);
  virtual void set_font_subfamily(const Warsaw::Unistring &);
  virtual void set_font_fullname(const Warsaw::Unistring &);
  virtual void set_font_style(const Warsaw::Unistring &);
  virtual void set_font_attribute(const Warsaw::NVPair &);

  virtual Warsaw::Coord resolution(Warsaw::Axis) { return 0;}
  virtual void draw_path(const Warsaw::Path &);
//   virtual void drawPatch(const Warsaw::Patch &);
  virtual void draw_rectangle(const Warsaw::Vertex &, const Warsaw::Vertex &);
  virtual void draw_quadric(const Warsaw::DrawingKit::Quadric, Warsaw::Coord, Warsaw::Coord);
  virtual void draw_ellipse(const Warsaw::Vertex &, const Warsaw::Vertex &);
  virtual void draw_image(Warsaw::Raster_ptr);
  virtual void allocate_char(Warsaw::Unichar, Warsaw::Graphic::Requisition &);
  virtual void draw_char(Warsaw::Unichar);
  virtual void allocate_text(const Warsaw::Unistring &, Warsaw::Graphic::Requisition &);
  virtual void draw_text(const Warsaw::Unistring &);
  virtual void copy_drawable(Warsaw::Drawable_ptr, Warsaw::PixelCoord, Warsaw::PixelCoord, Warsaw::PixelCoord, Warsaw::PixelCoord);
  virtual void flush() {}
private:
  Prague::Mutex  mutex;
  Warsaw::Transform_var  tr;
  Warsaw::Region_var     cl;
  Warsaw::Color          fg;
  Warsaw::Color          lt;
  Warsaw::Coord          ps;
  Warsaw::Coord          lw;
  Warsaw::DrawingKit::Endstyle       es;
  Warsaw::DrawingKit::Fillstyle      fs;
};

#endif
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// 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 <iostream>

#include <commons/Timer.hpp>

#include "StringPool.hpp"
#include "Variables.hpp"
#include "Compiler.hpp"
#include "Nodes.hpp"
#include "Parser.hpp"

using std::string;
using std::cout;
using std::endl;

void execCommand(string command);

int Compiler::compile(string file){
	cout << "Compile " << file << endl;

	Timer timer;

	string output = "a.out";

	int code = 0;
	try {
		lexer.lex(file);

		Parser parser(lexer);

		Program* program = parser.parse();

		Variables variables;
		StringPool* pool = new StringPool();

		//Semantical analysis
		check(program, variables);
		checkStrings(program, *pool);

		//Optimize the parse tree
		program->optimize();

		writer.open("output.asm");
		compile(program, *pool);

		delete program;
		delete pool;

		string asCommand = "as --32 -o output.o output.asm";

		execCommand(asCommand);

		string ldCommand = "ld -m elf_i386 -s -o ";
		ldCommand += output;
		ldCommand += " output.o";

		execCommand(ldCommand);

//as --32 -o assembly.o assembly.asm
//ld -m elf_i386 -s -o assembly assembly.o

		//TODO compile and link the assembly into an executable
	} catch (CompilerException e){
		cout << e.what() << endl;
		code = 1;
	}

	lexer.close();
	writer.close();

	if(code != 0){
		remove(output.c_str());
	}

	cout << "Compilation took " << timer.elapsed() << "ms" << endl;

	return code;
}

void execCommand(string command){
	char buffer[1024];

	FILE* stream = popen(command.c_str(), "r");

	while(fgets(buffer, 1024, stream) != NULL){
		cout << buffer;
	}

	pclose(stream);
}

void Compiler::compile(Program* program, StringPool& pool){
	writer.writeHeader();

	program->write(writer);

	writer.writeEnd();

	pool.write(writer);
}

void Compiler::check(Program* program, Variables& variables){
	NodeIterator it = program->begin();
	NodeIterator end = program->end();

	for( ; it != end; ++it){
		ParseNode* node = *it;

		node->checkVariables(variables);
	}
}

void Compiler::checkStrings(Program* program, StringPool& pool){
	NodeIterator it = program->begin();
	NodeIterator end = program->end();

	for( ; it != end; ++it){
		ParseNode* node = *it;

		node->checkStrings(pool);
	}
}
<commit_msg>Remove old stuff<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// 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 <iostream>

#include <commons/Timer.hpp>

#include "StringPool.hpp"
#include "Variables.hpp"
#include "Compiler.hpp"
#include "Nodes.hpp"
#include "Parser.hpp"

using std::string;
using std::cout;
using std::endl;

void execCommand(string command);

int Compiler::compile(string file){
	cout << "Compile " << file << endl;

	Timer timer;

	string output = "a.out";

	int code = 0;
	try {
		lexer.lex(file);

		Parser parser(lexer);

		Program* program = parser.parse();

		Variables variables;
		StringPool* pool = new StringPool();

		//Semantical analysis
		check(program, variables);
		checkStrings(program, *pool);

		//Optimize the parse tree
		program->optimize();

		writer.open("output.asm");
		compile(program, *pool);

		delete program;
		delete pool;

		string asCommand = "as --32 -o output.o output.asm";

		execCommand(asCommand);

		string ldCommand = "ld -m elf_i386 -s -o ";
		ldCommand += output;
		ldCommand += " output.o";

		execCommand(ldCommand);
	} catch (CompilerException e){
		cout << e.what() << endl;
		code = 1;
	}

	lexer.close();
	writer.close();

	if(code != 0){
		remove(output.c_str());
	}

	cout << "Compilation took " << timer.elapsed() << "ms" << endl;

	return code;
}

void execCommand(string command){
	char buffer[1024];

	FILE* stream = popen(command.c_str(), "r");

	while(fgets(buffer, 1024, stream) != NULL){
		cout << buffer;
	}

	pclose(stream);
}

void Compiler::compile(Program* program, StringPool& pool){
	writer.writeHeader();

	program->write(writer);

	writer.writeEnd();

	pool.write(writer);
}

void Compiler::check(Program* program, Variables& variables){
	NodeIterator it = program->begin();
	NodeIterator end = program->end();

	for( ; it != end; ++it){
		ParseNode* node = *it;

		node->checkVariables(variables);
	}
}

void Compiler::checkStrings(Program* program, StringPool& pool){
	NodeIterator it = program->begin();
	NodeIterator end = program->end();

	for( ; it != end; ++it){
		ParseNode* node = *it;

		node->checkStrings(pool);
	}
}
<|endoftext|>


<commit_before>#include "ServerPickingSystem.h"
#include "Transform.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "RayPacket.h"

ServerPickingSystem::ServerPickingSystem()
	: EntitySystem(SystemType::ServerPickingSystem, 1, ComponentType::ShipModule)
{
}

ServerPickingSystem::~ServerPickingSystem()
{
}

void ServerPickingSystem::initialize()
{
}

void ServerPickingSystem::processEntities(const vector<Entity*>& p_entities)
{
	//DOES NOT PROCESS ENTITIES!

	float dt = m_world->getDelta();

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		handleRay(m_pickComponents[i], p_entities);
	}
}
void ServerPickingSystem::setRay(int p_index, AglVector3 p_o, AglVector3 p_d)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			physX->getController()->SetRay(p_o, p_d, m_pickComponents[i].m_rayIndex);
			return;
		}
	}

	//Create the ray
	PickComponent pc;
	pc.m_rayIndex = physX->getController()->AddRay(p_o, p_d);
	pc.m_clientIndex = p_index;
	m_pickComponents.push_back(pc);
}
void ServerPickingSystem::handleRay(PickComponent& p_pc, const vector<Entity*>& p_entities)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	vector<unsigned int> cols = physX->getPhysicsController()->LineCollidesWith(p_pc.m_rayIndex);
	if (cols.size() > 0)
	{
		p_pc.m_latestPick = cols[0];
	}
	else
		p_pc.m_latestPick = -1;
}<commit_msg>Added ability to determine the id of the picked module<commit_after>#include "ServerPickingSystem.h"
#include "Transform.h"
#include <AglMatrix.h>
#include <AglQuaternion.h>
#include "PhysicsSystem.h"
#include <PhysicsController.h>
#include "RayPacket.h"
#include "PhysicsBody.h"

ServerPickingSystem::ServerPickingSystem()
	: EntitySystem(SystemType::ServerPickingSystem, 1, ComponentType::ShipModule)
{
}

ServerPickingSystem::~ServerPickingSystem()
{
}

void ServerPickingSystem::initialize()
{
}

void ServerPickingSystem::processEntities(const vector<Entity*>& p_entities)
{
	//DOES NOT PROCESS ENTITIES!

	float dt = m_world->getDelta();

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		handleRay(m_pickComponents[i], p_entities);
	}
}
void ServerPickingSystem::setRay(int p_index, AglVector3 p_o, AglVector3 p_d)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	for (unsigned int i = 0; i < m_pickComponents.size(); i++)
	{
		if (m_pickComponents[i].m_clientIndex == p_index)
		{
			physX->getController()->SetRay(p_o, p_d, m_pickComponents[i].m_rayIndex);
			return;
		}
	}

	//Create the ray
	PickComponent pc;
	pc.m_rayIndex = physX->getController()->AddRay(p_o, p_d);
	pc.m_clientIndex = p_index;
	m_pickComponents.push_back(pc);
}
void ServerPickingSystem::handleRay(PickComponent& p_pc, const vector<Entity*>& p_entities)
{
	PhysicsSystem* physX = static_cast<PhysicsSystem*>(m_world->getSystem(
		SystemType::PhysicsSystem));

	vector<unsigned int> cols = physX->getPhysicsController()->LineCollidesWith(p_pc.m_rayIndex);
	if (cols.size() > 0)
	{
		for (unsigned int i = 0; i < p_entities.size(); i++)
		{
			PhysicsBody* pb = static_cast<PhysicsBody*>(p_entities[i]->getComponent(ComponentType::PhysicsBody));
			if (pb && pb->m_id == cols[0])
			{
				p_pc.m_latestPick = p_entities[i]->getIndex();
				break;
			}
		}
	}
	else
		p_pc.m_latestPick = -1;
}<|endoftext|>