<commit_before>//////////////////////////////////////////////////////////////////////////
//
//      SneezyMUD - All rights reserved, SneezyMUD Coding Team
//      "task.cc" - All functions related to tasks that keep mobs/PCs busy
//
//////////////////////////////////////////////////////////////////////////

#if 0
    Batopr 8-10-96:
  to start a task, do:
  start_task(this, obj, rp, TASK_MEDITATE, arg, 0, in_room, 1, 0, 40);

  obj and rp can be NULL
  arg is probably ""

  timeLeft: (the first 0)
    - generally used as a counter of the number of interations of
      CMD_TASK_CONTINUE that have been encountered.
    - can be any (int) value desired

  in_room: (sets ch->task->was_in_room)
    - task should check current room vs this.
      reason: start the task and let my group leader move me around mud.

  status (the 1)
    - a ubyte.
    - some tasks set this to one value in start_task and check in
      CMD_TASK_CONTINUE status.  If its not what it was initted to, do the
      continue code.  at the bottom of CONTINUE, set it to some new value.
      The reason for doing this is that the first call to CMD_TASK_CONTINUE is
      almost instantaneous with when it was started.
    - probably a better way to do this would be by initing timeLeft to 0
      in start_task and incrementing it 1 for each call to CONTINUE.  CONTINUE
      code would only execute if timeLeft > 0.  That would free the status byte
      for use any way we want.

  flags:
    - an int, use depends on the task.

  nextUpdate:
    - NOT WHAT IT SEEMS:
      start_task() says ch->task->nextUpdate = nextUpdate.
    - calls to CMD_TASK_CONTINUE occur if pulse > ch->task->nextUpdate
    - notice that because pulse is typically big, calls to TASK CONTINUE are
      virtually instantaneous.
    - it is not until the first call to CMD_TASK_CONTINUE that we typically set
      ch->task->nextUpdate = pulse + xxxx
    - this leads to the status trick defined above.
    - SO BASICALLY, THIS VALUE IS WORTHLESS
#endif

#include "stdsneezy.h"

//FYI: CMD_TASK_CONTINUE is checked once per PULSE_MOBACT

taskData::taskData() :
  task(TASK_BOGUS),
  nextUpdate(0),
  timeLeft(0),
  orig_arg(NULL),
  wasInRoom(0),
  status(0),
  flags(0),
  obj(NULL),
  room(NULL)
{
}

taskData::taskData(const taskData &a) :
  task(a.task),
  nextUpdate(a.nextUpdate),
  timeLeft(a.timeLeft),
  wasInRoom(a.wasInRoom),
  status(a.status),
  flags(a.flags),
  obj(a.obj),
  room(a.room)
{
  orig_arg = mud_str_dup(a.orig_arg);
}

taskData & taskData::operator=(const taskData &a)
{
  if (this == &a) return *this;
  task = a.task;
  status = a.status;
  nextUpdate = a.nextUpdate;
  timeLeft = a.timeLeft;
  flags = a.flags;
  wasInRoom = a.wasInRoom;
  obj = a.obj;
  room = a.room;
  delete [] orig_arg;
  orig_arg = mud_str_dup(a.orig_arg);
  return *this;
}

taskData::~taskData()
{
  delete [] orig_arg;
  orig_arg = NULL;

  if (obj)
    obj->setIsTaskObj(false);
}

void taskData::calcNextUpdate(int pulse, int interval)
{
  nextUpdate = pulse + interval;
  nextUpdate %= 2400;
}

void TBeing::stopTask()
{
  if (!task)
    return;

  delete [] task->orig_arg;
  task->orig_arg = NULL;

  if (task->obj)
    task->obj->setIsTaskObj(false);

  delete task;
  task = NULL;
}

int start_task(TBeing *ch, TThing *t, TRoom *rp, taskTypeT task, const char *arg, int timeLeft, ushort wasInRoom, ubyte status, int flags, int nextUpdate)
{
  if (!ch || (ch->task)) {
    vlogf(LOG_BUG, fmt("%s got to bad place in start_task (%d).  Tell Brutius or Batopr") %
       (ch ? ch->getName() : "Unknown") % task);
    if (ch)
      ch->sendTo("Problem in task.  Bug Brutius.\n\r");
    return FALSE;
  }
  if (!(ch->task = new taskData)) {
    vlogf(LOG_BUG, fmt("Couldn't allocate memory in start_task for %s") %  ch->getName());
    return FALSE;
  }

  ch->task->orig_arg = mud_str_dup(arg);
  ch->task->obj = dynamic_cast<TObj *>(t);
  ch->task->room = rp;
  ch->task->task = task;
  ch->task->timeLeft = timeLeft;
  ch->task->wasInRoom = wasInRoom;
  ch->task->status = status;
  ch->task->flags = flags;
  ch->task->nextUpdate = nextUpdate;

  if (ch->task->obj)
    ch->task->obj->setIsTaskObj(true);

  return TRUE;
}

void warn_busy(TBeing *ch)
{
  if (!ch || !(ch->task)) {
    vlogf(LOG_BUG, fmt("%s got to bad place in warn_busy.  Tell Brutius or Batopr") %
       (ch ? ch->getName() : "Unknown"));
    return;
  }
  ch->sendTo(tasks[ch->task->task].you_are_busy_msg);
  ch->sendTo("Type 'abort' or 'stop' to quit what you are doing.\n\r");
}

int task_bogus(TBeing *ch, cmdTypeT, const char *, int , TRoom *, TObj *)
{
  ch->sendTo("Um... you hit a buggy spot in the code.  Tell an immort or something.\n\r");
  vlogf(LOG_BUG, fmt("%s was busy doing a buggy task!  Yikes!") %  ch->getName());
  ch->stopTask();

  return FALSE;
}

// first argument, the task name, should be a verb for the "look" commands
// display and the stat command
TaskEntry tasks[NUM_TASKS] =
{
  {"performing a bogus task", "You are busy doing nothing.\n\r", task_bogus},
  {"sharpening a weapon", "You are too busy sharpening.\n\r", task_sharpening},
  {"blacksmithing", "You are too busy blacksmithing.\n\r", task_blacksmithing},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_dead},
  {"regrowing something", "You are too busy regrowing something.\n\r", task_repair_organic},
  {"regrowing something", "You are too busy regrowing something.\n\r", task_repair_wood},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_magical},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_rock},
  {"tinkering with something", "You are too busy tinkering with something.\n\r", task_blacksmithing_advanced},
  {"mending", "You are too busy mending.\n\r", task_mend_hide},
  {"mending", "You are too busy mending.\n\r", task_mend},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_spiritual},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_door},
  {"taking items", "You are too busy taking items from the room.\n\r", task_get},
  {"casting a spell", "You are too busy casting your spell.\n\r", task_spell_friends},
  {"meditating", "You are too busy meditating.\n\r", task_meditate},
  {"sitting","You rather like sitting.\n\r",task_sit},
  {"resting","You're far too laid back at the moment.\n\r",task_rest},
  {"sleeping","You're a wee bit too unconscious to try that.\n\r",task_sleep},
  {"picking a lock", "You don't feel like giving up on this lock just yet.\n\r",task_picklock},
  {"repenting", "You are too busy repenting.\n\r", task_penance},
  {"brewing", "You are brewing and must concentrate!\n\r", task_brew},
  {"smoothing", "You are too busy smoothing.\n\r", task_dulling},
  {"skinning", "You are too busy skinning.\n\r", task_skinning},
  {"scribing", "You are scribing and must concentrate!\n\r", task_scribe},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_container},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_mine},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_grenade},
  {"meditating", "You are too busy meditating.\n\r", task_yoginsa},
  {"attuning a symbol", "You are too busy attuning.\n\r", task_attuning},
  {"tracking", "You are too busy tracking.\n\r", task_tracking},
  // Until the seekwater task is stripped from the tracking task, need to make
  // the message comply.
  //  {"tracking down someone", "You are too busy tracking.\n\r", task_tracking},
  {"searching for water", "You are too busy searching for water.\n\r", task_seekwater},
  {"searching for secret exits", "You are too busy searching for secret exits.\n\r", task_search},
  {"starting a fire", "You are too busy trying to start a fire.\n\r", task_lightfire},
  {"planting seeds", "You are too busy planting some seeds.\n\r", task_plant},
  {"creating something", "You are too busy trying to create something.\n\r", task_createEngine},
  {"charging", "You are too busy barreling down on someone.\n\r", task_charge},
  {"whittling", "You are too busy using your whittle skills.\n\r", task_whittle},
  {"stave charging", "You are too busy charging a stave.\n\r", task_stavecharging},
  {"in a defensive trance", "Not while you're in a defensive trance!\n\r", task_trance_of_blades},
  {"sacrificing", "Not while you are performing the sacrificial ritual of life!\n\r", task_sacrifice},
  {"fishing", "You are too busy fishing.\n\r", task_fishing},
  {"logging", "You are too busy logging.\n\r", task_logging},
  {"extinguishing", "You are too busy putting a fire out.\n\r", task_extinguish_my_ass},
  {"butchering", "You are too busy butchering a corpse.\n\r", task_butchering},
  {"cooking", "You are too busy cooking.\n\r", task_cook},
  {"loading a handgonne", "You are too busy loading your handgonne.\n\r", task_handgonne_load},
  {"loading a cannon", "You are too busy loading your cannon.\n\r", task_cannon_load},
  {"trapping an arrow", "You are too busy trapping your arrow.\n\r", task_trap_arrow},
  {"riding", "You are too busy riding.\n\r", task_ride},
};

bool TBeing::nobrainerTaskCommand(cmdTypeT cmd)
{
  switch (cmd) {
    case CMD_SAY:
    case CMD_SAY2:
    case CMD_GLANCE:
    case CMD_TELL:
    case CMD_SHOUT:
    case CMD_WEATHER:
    case CMD_INVENTORY:
    case CMD_EQUIPMENT:
    case CMD_SMILE:
    case CMD_SHAKE:
    case CMD_NOD:
    case CMD_GT:
    case CMD_WIZNET:
    case CMD_REPLY:
      return TRUE;
    default:
      return FALSE;
  }
}

bool TBeing::utilityTaskCommand(cmdTypeT cmd)
{
  switch (cmd) {
    case CMD_EQUIPMENT:
    case CMD_WIZLIST:
    case CMD_LOOK:
    case CMD_LIMBS:  // not realistic, but let's just be nice
    case CMD_SPELLS:
    case CMD_RITUALS:
    case CMD_GLANCE:
    case CMD_TIME:
    case CMD_SCORE:
    case CMD_TROPHY:
    case CMD_HELP:
    case CMD_ZONES:
    case CMD_WHO:
    case CMD_NEWS:
    case CMD_CREDITS:
    case CMD_WIZNEWS:
    case CMD_SAVE:
    case CMD_IDEA:
    case CMD_TYPO:
    case CMD_BUG:
    case CMD_LEVELS:
    case CMD_ATTRIBUTE:
    case CMD_WORLD:
    case CMD_CLS:
    case CMD_PROMPT:
    case CMD_ALIAS:
    case CMD_CLEAR:
    case CMD_HISTORY:
    case CMD_COLOR:
    case CMD_MOTD:
    case CMD_TITLE:
    case CMD_PRACTICE:
    case CMD_NOSHOUT:
    case CMD_DESCRIPTION:
    case CMD_LIST:  // for list faction
    case CMD_ATTACK:
    case CMD_GROUP:
    case CMD_AFK:
    case CMD_WEATHER:
    case CMD_TOGGLE:
      return TRUE;
    default:
      return FALSE;
  }
}

<commit_msg>-fixed a small issue with task processing with the GET_ALL tasking.  Since it doesnt use the standard tasking pump, ive removed object tracking. Please report any bugs found which involve "get all", deleting an object, and a crash.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//      SneezyMUD - All rights reserved, SneezyMUD Coding Team
//      "task.cc" - All functions related to tasks that keep mobs/PCs busy
//
//////////////////////////////////////////////////////////////////////////

#if 0
    Batopr 8-10-96:
  to start a task, do:
  start_task(this, obj, rp, TASK_MEDITATE, arg, 0, in_room, 1, 0, 40);

  obj and rp can be NULL
  arg is probably ""

  timeLeft: (the first 0)
    - generally used as a counter of the number of interations of
      CMD_TASK_CONTINUE that have been encountered.
    - can be any (int) value desired

  in_room: (sets ch->task->was_in_room)
    - task should check current room vs this.
      reason: start the task and let my group leader move me around mud.

  status (the 1)
    - a ubyte.
    - some tasks set this to one value in start_task and check in
      CMD_TASK_CONTINUE status.  If its not what it was initted to, do the
      continue code.  at the bottom of CONTINUE, set it to some new value.
      The reason for doing this is that the first call to CMD_TASK_CONTINUE is
      almost instantaneous with when it was started.
    - probably a better way to do this would be by initing timeLeft to 0
      in start_task and incrementing it 1 for each call to CONTINUE.  CONTINUE
      code would only execute if timeLeft > 0.  That would free the status byte
      for use any way we want.

  flags:
    - an int, use depends on the task.

  nextUpdate:
    - NOT WHAT IT SEEMS:
      start_task() says ch->task->nextUpdate = nextUpdate.
    - calls to CMD_TASK_CONTINUE occur if pulse > ch->task->nextUpdate
    - notice that because pulse is typically big, calls to TASK CONTINUE are
      virtually instantaneous.
    - it is not until the first call to CMD_TASK_CONTINUE that we typically set
      ch->task->nextUpdate = pulse + xxxx
    - this leads to the status trick defined above.
    - SO BASICALLY, THIS VALUE IS WORTHLESS
#endif

#include "stdsneezy.h"

//FYI: CMD_TASK_CONTINUE is checked once per PULSE_MOBACT

taskData::taskData() :
  task(TASK_BOGUS),
  nextUpdate(0),
  timeLeft(0),
  orig_arg(NULL),
  wasInRoom(0),
  status(0),
  flags(0),
  obj(NULL),
  room(NULL)
{
}

taskData::taskData(const taskData &a) :
  task(a.task),
  nextUpdate(a.nextUpdate),
  timeLeft(a.timeLeft),
  wasInRoom(a.wasInRoom),
  status(a.status),
  flags(a.flags),
  obj(a.obj),
  room(a.room)
{
  orig_arg = mud_str_dup(a.orig_arg);
}

taskData & taskData::operator=(const taskData &a)
{
  if (this == &a) return *this;
  task = a.task;
  status = a.status;
  nextUpdate = a.nextUpdate;
  timeLeft = a.timeLeft;
  flags = a.flags;
  wasInRoom = a.wasInRoom;
  obj = a.obj;
  room = a.room;
  delete [] orig_arg;
  orig_arg = mud_str_dup(a.orig_arg);
  return *this;
}

taskData::~taskData()
{
  delete [] orig_arg;
  orig_arg = NULL;

  if (obj)
    obj->setIsTaskObj(false);
}

void taskData::calcNextUpdate(int pulse, int interval)
{
  nextUpdate = pulse + interval;
  nextUpdate %= 2400;
}

void TBeing::stopTask()
{
  if (!task)
    return;

  delete [] task->orig_arg;
  task->orig_arg = NULL;

  if (task->obj)
    task->obj->setIsTaskObj(false);

  delete task;
  task = NULL;
}

int start_task(TBeing *ch, TThing *t, TRoom *rp, taskTypeT task, const char *arg, int timeLeft, ushort wasInRoom, ubyte status, int flags, int nextUpdate)
{
  if (!ch || (ch->task)) {
    vlogf(LOG_BUG, fmt("%s got to bad place in start_task (%d).  Tell Brutius or Batopr") %
       (ch ? ch->getName() : "Unknown") % task);
    if (ch)
      ch->sendTo("Problem in task.  Bug Brutius.\n\r");
    return FALSE;
  }
  if (!(ch->task = new taskData)) {
    vlogf(LOG_BUG, fmt("Couldn't allocate memory in start_task for %s") %  ch->getName());
    return FALSE;
  }

  ch->task->orig_arg = mud_str_dup(arg);
  ch->task->obj = dynamic_cast<TObj *>(t);
  ch->task->room = rp;
  ch->task->task = task;
  ch->task->timeLeft = timeLeft;
  ch->task->wasInRoom = wasInRoom;
  ch->task->status = status;
  ch->task->flags = flags;
  ch->task->nextUpdate = nextUpdate;

  // TASK_GET_ALL is wierd and doesn't use standard tasking processing - skip tracking of objs
  if (task != TASK_GET_ALL && ch->task->obj)
    ch->task->obj->setIsTaskObj(true);

  return TRUE;
}

void warn_busy(TBeing *ch)
{
  if (!ch || !(ch->task)) {
    vlogf(LOG_BUG, fmt("%s got to bad place in warn_busy.  Tell Brutius or Batopr") %
       (ch ? ch->getName() : "Unknown"));
    return;
  }
  ch->sendTo(tasks[ch->task->task].you_are_busy_msg);
  ch->sendTo("Type 'abort' or 'stop' to quit what you are doing.\n\r");
}

int task_bogus(TBeing *ch, cmdTypeT, const char *, int , TRoom *, TObj *)
{
  ch->sendTo("Um... you hit a buggy spot in the code.  Tell an immort or something.\n\r");
  vlogf(LOG_BUG, fmt("%s was busy doing a buggy task!  Yikes!") %  ch->getName());
  ch->stopTask();

  return FALSE;
}

// first argument, the task name, should be a verb for the "look" commands
// display and the stat command
TaskEntry tasks[NUM_TASKS] =
{
  {"performing a bogus task", "You are busy doing nothing.\n\r", task_bogus},
  {"sharpening a weapon", "You are too busy sharpening.\n\r", task_sharpening},
  {"blacksmithing", "You are too busy blacksmithing.\n\r", task_blacksmithing},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_dead},
  {"regrowing something", "You are too busy regrowing something.\n\r", task_repair_organic},
  {"regrowing something", "You are too busy regrowing something.\n\r", task_repair_wood},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_magical},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_rock},
  {"tinkering with something", "You are too busy tinkering with something.\n\r", task_blacksmithing_advanced},
  {"mending", "You are too busy mending.\n\r", task_mend_hide},
  {"mending", "You are too busy mending.\n\r", task_mend},
  {"fixing something", "You are too busy fixing something.\n\r", task_repair_spiritual},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_door},
  {"taking items", "You are too busy taking items from the room.\n\r", task_get},
  {"casting a spell", "You are too busy casting your spell.\n\r", task_spell_friends},
  {"meditating", "You are too busy meditating.\n\r", task_meditate},
  {"sitting","You rather like sitting.\n\r",task_sit},
  {"resting","You're far too laid back at the moment.\n\r",task_rest},
  {"sleeping","You're a wee bit too unconscious to try that.\n\r",task_sleep},
  {"picking a lock", "You don't feel like giving up on this lock just yet.\n\r",task_picklock},
  {"repenting", "You are too busy repenting.\n\r", task_penance},
  {"brewing", "You are brewing and must concentrate!\n\r", task_brew},
  {"smoothing", "You are too busy smoothing.\n\r", task_dulling},
  {"skinning", "You are too busy skinning.\n\r", task_skinning},
  {"scribing", "You are scribing and must concentrate!\n\r", task_scribe},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_container},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_mine},
  {"setting a trap", "You are too busy setting your trap.\n\r", task_trap_grenade},
  {"meditating", "You are too busy meditating.\n\r", task_yoginsa},
  {"attuning a symbol", "You are too busy attuning.\n\r", task_attuning},
  {"tracking", "You are too busy tracking.\n\r", task_tracking},
  // Until the seekwater task is stripped from the tracking task, need to make
  // the message comply.
  //  {"tracking down someone", "You are too busy tracking.\n\r", task_tracking},
  {"searching for water", "You are too busy searching for water.\n\r", task_seekwater},
  {"searching for secret exits", "You are too busy searching for secret exits.\n\r", task_search},
  {"starting a fire", "You are too busy trying to start a fire.\n\r", task_lightfire},
  {"planting seeds", "You are too busy planting some seeds.\n\r", task_plant},
  {"creating something", "You are too busy trying to create something.\n\r", task_createEngine},
  {"charging", "You are too busy barreling down on someone.\n\r", task_charge},
  {"whittling", "You are too busy using your whittle skills.\n\r", task_whittle},
  {"stave charging", "You are too busy charging a stave.\n\r", task_stavecharging},
  {"in a defensive trance", "Not while you're in a defensive trance!\n\r", task_trance_of_blades},
  {"sacrificing", "Not while you are performing the sacrificial ritual of life!\n\r", task_sacrifice},
  {"fishing", "You are too busy fishing.\n\r", task_fishing},
  {"logging", "You are too busy logging.\n\r", task_logging},
  {"extinguishing", "You are too busy putting a fire out.\n\r", task_extinguish_my_ass},
  {"butchering", "You are too busy butchering a corpse.\n\r", task_butchering},
  {"cooking", "You are too busy cooking.\n\r", task_cook},
  {"loading a handgonne", "You are too busy loading your handgonne.\n\r", task_handgonne_load},
  {"loading a cannon", "You are too busy loading your cannon.\n\r", task_cannon_load},
  {"trapping an arrow", "You are too busy trapping your arrow.\n\r", task_trap_arrow},
  {"riding", "You are too busy riding.\n\r", task_ride},
};

bool TBeing::nobrainerTaskCommand(cmdTypeT cmd)
{
  switch (cmd) {
    case CMD_SAY:
    case CMD_SAY2:
    case CMD_GLANCE:
    case CMD_TELL:
    case CMD_SHOUT:
    case CMD_WEATHER:
    case CMD_INVENTORY:
    case CMD_EQUIPMENT:
    case CMD_SMILE:
    case CMD_SHAKE:
    case CMD_NOD:
    case CMD_GT:
    case CMD_WIZNET:
    case CMD_REPLY:
      return TRUE;
    default:
      return FALSE;
  }
}

bool TBeing::utilityTaskCommand(cmdTypeT cmd)
{
  switch (cmd) {
    case CMD_EQUIPMENT:
    case CMD_WIZLIST:
    case CMD_LOOK:
    case CMD_LIMBS:  // not realistic, but let's just be nice
    case CMD_SPELLS:
    case CMD_RITUALS:
    case CMD_GLANCE:
    case CMD_TIME:
    case CMD_SCORE:
    case CMD_TROPHY:
    case CMD_HELP:
    case CMD_ZONES:
    case CMD_WHO:
    case CMD_NEWS:
    case CMD_CREDITS:
    case CMD_WIZNEWS:
    case CMD_SAVE:
    case CMD_IDEA:
    case CMD_TYPO:
    case CMD_BUG:
    case CMD_LEVELS:
    case CMD_ATTRIBUTE:
    case CMD_WORLD:
    case CMD_CLS:
    case CMD_PROMPT:
    case CMD_ALIAS:
    case CMD_CLEAR:
    case CMD_HISTORY:
    case CMD_COLOR:
    case CMD_MOTD:
    case CMD_TITLE:
    case CMD_PRACTICE:
    case CMD_NOSHOUT:
    case CMD_DESCRIPTION:
    case CMD_LIST:  // for list faction
    case CMD_ATTACK:
    case CMD_GROUP:
    case CMD_AFK:
    case CMD_WEATHER:
    case CMD_TOGGLE:
      return TRUE;
    default:
      return FALSE;
  }
}

<|endoftext|>


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

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/time.h> //fps calculations
#include <pcl/io/hdl_grabber.h>
#include <pcl/visualization/point_cloud_color_handlers.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/image_viewer.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/console/parse.h>
#include <pcl/visualization/boost.h>
#include <pcl/visualization/mouse_event.h>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <typeinfo>

using namespace std;
using namespace pcl;
using namespace pcl::console;
using namespace pcl::visualization;

#define SHOW_FPS 0
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = getTime ();\
    double now = getTime (); \
    ++count; \
    if (now - last >= 1.0) \
    { \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointType>
class SimpleHDLViewer
{
  public:
    typedef PointCloud<PointType> Cloud;
    typedef typename Cloud::ConstPtr CloudConstPtr;

    SimpleHDLViewer (Grabber& grabber,
                     PointCloudColorHandler<PointType> &handler)
      : cloud_viewer_ (new PCLVisualizer ("PCL HDL Cloud"))
      , grabber_ (grabber)
      , handler_ (handler)
    {
    }

    void
    cloud_callback (const CloudConstPtr& cloud)
    {
      FPS_CALC ("cloud callback");
      boost::mutex::scoped_lock lock (cloud_mutex_);
      cloud_ = cloud;
      //std::cout << cloud->points[0] << " " << cloud->size () << std::endl;
    }

    void
    cloud_callback (const CloudConstPtr& cloud, float startAngle,
                    float endAngle)
    {
      FPS_CALC ("cloud callback");
      boost::mutex::scoped_lock lock (cloud_mutex_);
      cloud_ = cloud;
    }

    void
    keyboard_callback (const KeyboardEvent& event,
                       void* cookie)
    {
      if (event.keyUp ())
      {
        return;
      }
    }

    void
    mouse_callback (const MouseEvent& mouse_event,
                    void* cookie)
    {
      if (mouse_event.getType () == MouseEvent::MouseButtonPress &&
          mouse_event.getButton () == MouseEvent::LeftButton)
      {
        cout << mouse_event.getX () << " , " << mouse_event.getY () << endl;
      }
    }

    void
    run ()
    {
      cloud_viewer_->addCoordinateSystem (3.0);
      cloud_viewer_->setBackgroundColor (0, 0, 0);
      cloud_viewer_->initCameraParameters ();
      cloud_viewer_->setCameraPosition (0.0, 0.0, 30.0, 0.0, 1.0, 0.0, 0);
      cloud_viewer_->setCameraClipDistances (0.0, 50.0);
      //cloud_viewer_->registerMouseCallback(&SimpleHDLViewer::mouse_callback, *this);
      //cloud_viewer_->registerKeyboardCallback (&SimpleHDLViewer::keyboard_callback, *this);

      //boost::function<void(const CloudConstPtr&, float, float)> cloud_cb = boost::bind(&SimpleHDLViewer::cloud_callback, this, _1, _2, _3);
      boost::function<void (const CloudConstPtr&)> cloud_cb = boost::bind (
          &SimpleHDLViewer::cloud_callback, this, _1);
      boost::signals2::connection cloud_connection = grabber_.registerCallback (
          cloud_cb);

      grabber_.start ();

      while (!cloud_viewer_->wasStopped ())
      {
        CloudConstPtr cloud;

        // See if we can get a cloud
        if (cloud_mutex_.try_lock ())
        {
          cloud_.swap (cloud);
          cloud_mutex_.unlock ();
        }

        if (cloud)
        {
          FPS_CALC("drawing cloud");
          handler_.setInputCloud (cloud);
          if (!cloud_viewer_->updatePointCloud (cloud, handler_, "HDL"))
            cloud_viewer_->addPointCloud (cloud, handler_, "HDL");

          cloud_viewer_->spinOnce ();
        }

        if (!grabber_.isRunning ())
          cloud_viewer_->spin ();

        boost::this_thread::sleep (boost::posix_time::microseconds (100));
      }

      grabber_.stop ();

      cloud_connection.disconnect ();
    }

    boost::shared_ptr<PCLVisualizer> cloud_viewer_;
    boost::shared_ptr<ImageViewer> image_viewer_;

    Grabber& grabber_;
    boost::mutex cloud_mutex_;
    boost::mutex image_mutex_;

    CloudConstPtr cloud_;
    PointCloudColorHandler<PointType> &handler_;
};

void
usage (char ** argv)
{
  cout << "usage: " << argv[0]
      << " [-hdlCalibration <path-to-calibration-file>] [-pcapFile <path-to-pcap-file>] [-h | --help] [-format XYZ(default)|XYZI|XYZRGB]"
      << endl;
  cout << argv[0] << " -h | --help : shows this help" << endl;
  return;
}

int
main (int argc, char ** argv)
{
  std::string hdlCalibration, pcapFile, format ("XYZ");

  if (find_switch (argc, argv, "-h") ||
      find_switch (argc, argv, "--help"))
  {
    usage (argv);
    return (0);
  }

  parse_argument (argc, argv, "-calibrationFile", hdlCalibration);
  parse_argument (argc, argv, "-pcapFile", pcapFile);
  parse_argument (argc, argv, "-format", format);

  HDLGrabber grabber (hdlCalibration, pcapFile);

  if (boost::iequals (format, std::string ("XYZ")))
  {
    std::vector<double> fcolor (3); fcolor[0] = fcolor[1] = fcolor[2] = 255.0;
    pcl::console::parse_3x_arguments (argc, argv, "-fc", fcolor[0], fcolor[1], fcolor[2]);
    PointCloudColorHandlerCustom<PointXYZ> color_handler (fcolor[0], fcolor[1], fcolor[2]);

    SimpleHDLViewer<PointXYZ> v (grabber, color_handler);
    v.run ();
  }
  else if (boost::iequals (format, std::string ("XYZI")))
  {
    PointCloudColorHandlerGenericField<PointXYZI> color_handler ("intensity");

    SimpleHDLViewer<PointXYZI> v (grabber, color_handler);
    v.run ();
  }
  else if (boost::iequals (format, std::string ("XYZRGB")))
  {
    PointCloudColorHandlerRGBField<PointXYZRGBA> color_handler;

    SimpleHDLViewer<PointXYZRGBA> v (grabber, color_handler);
    v.run ();
  }
  return (0);
}

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

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/time.h> //fps calculations
#include <pcl/io/hdl_grabber.h>
#include <pcl/visualization/point_cloud_color_handlers.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/visualization/image_viewer.h>
#include <pcl/io/openni_camera/openni_driver.h>
#include <pcl/console/parse.h>
#include <pcl/visualization/boost.h>
#include <pcl/visualization/mouse_event.h>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <typeinfo>

using namespace std;
using namespace pcl;
using namespace pcl::console;
using namespace pcl::visualization;

#define SHOW_FPS 0
#if SHOW_FPS
#define FPS_CALC(_WHAT_) \
do \
{ \
    static unsigned count = 0;\
    static double last = getTime ();\
    double now = getTime (); \
    ++count; \
    if (now - last >= 1.0) \
    { \
      std::cout << "Average framerate("<< _WHAT_ << "): " << double(count)/double(now - last) << " Hz" <<  std::endl; \
      count = 0; \
      last = now; \
    } \
}while(false)
#else
#define FPS_CALC(_WHAT_) \
do \
{ \
}while(false)
#endif

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename PointType>
class SimpleHDLViewer
{
  public:
    typedef PointCloud<PointType> Cloud;
    typedef typename Cloud::ConstPtr CloudConstPtr;

    SimpleHDLViewer (Grabber& grabber,
                     PointCloudColorHandler<PointType> &handler)
      : cloud_viewer_ (new PCLVisualizer ("PCL HDL Cloud"))
      , grabber_ (grabber)
      , handler_ (handler)
    {
    }

    void
    cloud_callback (const CloudConstPtr& cloud)
    {
      FPS_CALC ("cloud callback");
      boost::mutex::scoped_lock lock (cloud_mutex_);
      cloud_ = cloud;
      //std::cout << cloud->points[0] << " " << cloud->size () << std::endl;
    }

    void
    cloud_callback (const CloudConstPtr& cloud, float startAngle,
                    float endAngle)
    {
      FPS_CALC ("cloud callback");
      boost::mutex::scoped_lock lock (cloud_mutex_);
      cloud_ = cloud;
    }

    void
    keyboard_callback (const KeyboardEvent& event,
                       void* cookie)
    {
      if (event.keyUp ())
      {
        return;
      }
    }

    void
    mouse_callback (const MouseEvent& mouse_event,
                    void* cookie)
    {
      if (mouse_event.getType () == MouseEvent::MouseButtonPress &&
          mouse_event.getButton () == MouseEvent::LeftButton)
      {
        cout << mouse_event.getX () << " , " << mouse_event.getY () << endl;
      }
    }

    void
    run ()
    {
      cloud_viewer_->addCoordinateSystem (3.0);
      cloud_viewer_->setBackgroundColor (0, 0, 0);
      cloud_viewer_->initCameraParameters ();
      cloud_viewer_->setCameraPosition (0.0, 0.0, 30.0, 0.0, 1.0, 0.0, 0);
      cloud_viewer_->setCameraClipDistances (0.0, 50.0);
      //cloud_viewer_->registerMouseCallback(&SimpleHDLViewer::mouse_callback, *this);
      //cloud_viewer_->registerKeyboardCallback (&SimpleHDLViewer::keyboard_callback, *this);

      //boost::function<void(const CloudConstPtr&, float, float)> cloud_cb = boost::bind(&SimpleHDLViewer::cloud_callback, this, _1, _2, _3);
      boost::function<void (const CloudConstPtr&)> cloud_cb = boost::bind (
          &SimpleHDLViewer::cloud_callback, this, _1);
      boost::signals2::connection cloud_connection = grabber_.registerCallback (
          cloud_cb);

      grabber_.start ();

      while (!cloud_viewer_->wasStopped ())
      {
        CloudConstPtr cloud;

        // See if we can get a cloud
        if (cloud_mutex_.try_lock ())
        {
          cloud_.swap (cloud);
          cloud_mutex_.unlock ();
        }

        if (cloud)
        {
          FPS_CALC("drawing cloud");
          handler_.setInputCloud (cloud);
          if (!cloud_viewer_->updatePointCloud (cloud, handler_, "HDL"))
            cloud_viewer_->addPointCloud (cloud, handler_, "HDL");

          cloud_viewer_->spinOnce ();
        }

        if (!grabber_.isRunning ())
          cloud_viewer_->spin ();

        boost::this_thread::sleep (boost::posix_time::microseconds (100));
      }

      grabber_.stop ();

      cloud_connection.disconnect ();
    }

    boost::shared_ptr<PCLVisualizer> cloud_viewer_;
    boost::shared_ptr<ImageViewer> image_viewer_;

    Grabber& grabber_;
    boost::mutex cloud_mutex_;
    boost::mutex image_mutex_;

    CloudConstPtr cloud_;
    PointCloudColorHandler<PointType> &handler_;
};

void
usage (char ** argv)
{
  cout << "usage: " << argv[0]
      << " [-hdlCalibration <path-to-calibration-file>] [-pcapFile <path-to-pcap-file>] [-h | --help] [-format XYZ(default)|XYZI|XYZRGB]"
      << endl;
  cout << argv[0] << " -h | --help : shows this help" << endl;
  return;
}

int
main (int argc, char ** argv)
{
  std::string hdlCalibration, pcapFile, format ("XYZ");

  if (find_switch (argc, argv, "-h") ||
      find_switch (argc, argv, "--help"))
  {
    usage (argv);
    return (0);
  }

  parse_argument (argc, argv, "-calibrationFile", hdlCalibration);
  parse_argument (argc, argv, "-pcapFile", pcapFile);
  parse_argument (argc, argv, "-format", format);

  HDLGrabber grabber (hdlCalibration, pcapFile);

  cout << format << endl;
  if (boost::iequals (format, std::string ("XYZ")))
  {
    std::vector<double> fcolor (3); fcolor[0] = fcolor[1] = fcolor[2] = 255.0;
    pcl::console::parse_3x_arguments (argc, argv, "-fc", fcolor[0], fcolor[1], fcolor[2]);
    PointCloudColorHandlerCustom<PointXYZ> color_handler (fcolor[0], fcolor[1], fcolor[2]);

    SimpleHDLViewer<PointXYZ> v (grabber, color_handler);
    v.run ();
  }
  else if (boost::iequals (format, std::string ("XYZI")))
  {
    PointCloudColorHandlerGenericField<PointXYZI> color_handler ("intensity");

    SimpleHDLViewer<PointXYZI> v (grabber, color_handler);
    v.run ();
  }
  else if (boost::iequals (format, std::string ("XYZRGB")))
  {
    PointCloudColorHandlerRGBField<PointXYZRGBA> color_handler;

    SimpleHDLViewer<PointXYZRGBA> v (grabber, color_handler);
    v.run ();
  }
  return (0);
}

<|endoftext|>


<commit_before>#include "doocore/io/EasyTuple.h"

// from STL
#include <string>
#include <sstream>
#include <vector>

// from Boost
#include <boost/assign/std/vector.hpp>
using namespace boost::assign;

// from ROOT
#include "TFile.h"
#include "TTree.h"

// from RooFit
#include "RooArgSet.h"
#include "RooLinkedListIter.h"
#include "RooAbsArg.h"
#include "RooDataSet.h"
#include "RooFormulaVar.h"
#include "RooCategory.h"
#include "RooRealVar.h"
#include "RooCmdArg.h"

// from project
#include "doocore/io/MsgStream.h"

using namespace ROOT;
using namespace RooFit;

doocore::io::EasyTuple::EasyTuple(const std::string& file_name, const std::string& tree_name, const RooArgSet& argset)
: file_(NULL),
  tree_(NULL),
  argset_(NULL),
  dataset_(NULL),
  tree_name_(tree_name),
  num_maximum_events_(-1),
  cut_variable_range_(kCutExclusive)
{
  file_ = new TFile(file_name.c_str());
  argset_ = new RooArgSet(argset);

  if (file_ == NULL || file_->IsZombie() || file_->GetNkeys() <= 0) {
    serr << "File " << file_name << " could not be opened properly." << endmsg;
    throw 1;
  }

  tree_ = dynamic_cast<TTree*>(file_->Get(tree_name.c_str()));
  if (tree_ == NULL) {
    serr << "Tree " << tree_name << " could not be opened properly." << endmsg;
    throw 2;
  }

  if (argset.getSize() > 0) tree_->SetBranchStatus("*", 0);

  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;

  while ((arg=(RooAbsArg*)it->Next())) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
    RooCategory* cat = dynamic_cast<RooCategory*>(arg);

    if (var != NULL || cat != NULL) {
      if (tree_->GetBranch(arg->GetName()) == NULL) {
        swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
      } else {
        tree_->SetBranchStatus(arg->GetName(), 1);
      }
    }
  }
  delete it;
}

doocore::io::EasyTuple::EasyTuple(TTree* tree, const RooArgSet& argset)
: file_(NULL),
tree_(tree),
argset_(NULL),
dataset_(NULL),
num_maximum_events_(-1),
cut_variable_range_(kCutExclusive)
{
  argset_ = new RooArgSet(argset);

  if (argset.getSize() > 0) tree_->SetBranchStatus("*", 0);

  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;

  while ((arg=(RooAbsArg*)it->Next())) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
    RooCategory* cat = dynamic_cast<RooCategory*>(arg);

    if (var != NULL || cat != NULL) {
      if (tree_->GetBranch(arg->GetName()) == NULL) {
        swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
      } else {
        tree_->SetBranchStatus(arg->GetName(), 1);
      }
    }
  }
  delete it;
}

doocore::io::EasyTuple::EasyTuple(const EasyTuple& other)
: file_(NULL),
tree_(NULL),
argset_(NULL),
dataset_(NULL),
tree_name_(other.tree_name_),
num_maximum_events_(other.num_maximum_events_),
cut_variable_range_(other.cut_variable_range_)
{
  argset_ = new RooArgSet(*other.argset_);

  if (other.file_ == NULL) {
    tree_ = other.tree_;
  } else {
    file_ = new TFile(other.file_->GetName());

    if (file_ == NULL || file_->IsZombie() || file_->GetNkeys() <= 0) {
      serr << "File could not be opened properly." << endmsg;
      throw 1;
    }

    tree_ = dynamic_cast<TTree*>(file_->Get(tree_name_.c_str()));
    if (tree_ == NULL) {
      serr << "Tree " << tree_name_ << " could not be opened properly." << endmsg;
      throw 2;
    }

    if (argset_->getSize() > 0) tree_->SetBranchStatus("*", 0);

    RooLinkedListIter* it  = (RooLinkedListIter*)argset_->createIterator();
    RooAbsArg*         arg = NULL;

    while ((arg=(RooAbsArg*)it->Next())) {
      RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
      RooCategory* cat = dynamic_cast<RooCategory*>(arg);

      if (var != NULL || cat != NULL) {
        if (tree_->GetBranch(arg->GetName()) == NULL) {
          swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
        } else {
          tree_->SetBranchStatus(arg->GetName(), 1);
        }
      }
    }
    delete it;

    if (num_maximum_events_>=0) {
      set_num_maximum_events(num_maximum_events_);
    }

    if (other.dataset_ != NULL) {
      dataset_ = new RooDataSet(*other.dataset_);
    }
  }
}

doocore::io::EasyTuple::~EasyTuple() {
  if (dataset_ != NULL) delete dataset_;
  if (argset_ != NULL) delete argset_;
  if (tree_ != NULL && file_!= NULL) delete tree_;
  if (file_ != NULL) delete file_;
}

RooDataSet& doocore::io::EasyTuple::ConvertToDataSet(const RooCmdArg& arg1,
                                                     const RooCmdArg& arg2,
                                                     const RooCmdArg& arg3,
                                                     const RooCmdArg& arg4,
                                                     const RooCmdArg& arg5,
                                                     const RooCmdArg& arg6,
                                                     const RooCmdArg& arg7) {
  if (argset_ == NULL) {
    serr << "Internal argset not set. Cannot convert to RooDataSet without this." << endmsg;
    throw 4;
  }

  return ConvertToDataSet(*argset_, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}

RooDataSet& doocore::io::EasyTuple::ConvertToDataSet(const RooArgSet& argset,
                                                     const RooCmdArg& arg1,
                                                     const RooCmdArg& arg2,
                                                     const RooCmdArg& arg3,
                                                     const RooCmdArg& arg4,
                                                     const RooCmdArg& arg5,
                                                     const RooCmdArg& arg6,
                                                     const RooCmdArg& arg7) {
  if (dataset_ != NULL) {
    serr << "Dataset was converted before. Maybe you want to use doocore::io::EasyTuple::dataset()." << endmsg;
    throw 3;
  }

  // filter out formula vars and additionally cut on all variable ranges
  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;
  RooArgSet          new_set;
  std::vector<RooFormulaVar*> formulas;
  std::string        cut_variables="";
  std::stringstream  stream_cut_variables;
  std::string        less_operator = cut_variable_range_==kCutInclusive ? "<=" : "<";
  std::string        greater_operator = cut_variable_range_==kCutInclusive ? ">=" : ">";

  while ((arg=(RooAbsArg*)it->Next())) {
    RooFormulaVar* formula = dynamic_cast<RooFormulaVar*>(arg);
    RooRealVar*    var     = dynamic_cast<RooRealVar*>(arg);

    if (formula == NULL) {
      new_set.add(*arg);

      if (var != NULL && cut_variable_range_ != kNoCuts) {
        if (var->hasMin()) stream_cut_variables << "&&" << var->GetName() << greater_operator << var->getMin();
        if (var->hasMax()) stream_cut_variables << "&&" << var->GetName() << less_operator << var->getMax();
      }
    } else {
      formulas.push_back(formula);
    }
  }
  delete it;

  // 	RooCmdArg(const char* name, Int_t i1 = 0, Int_t i2 = 0, Double_t d1 = 0, Double_t d2 = 0, const char* s1 = 0, const char* s2 = 0, const TObject* o1 = 0, const TObject* o2 = 0, const RooCmdArg* ca = 0, const char* s3 = 0, const RooArgSet* c1 = 0, const RooArgSet* c2 = 0)
  // RooCmdArg("CutSpec",0,0,0,0,cutSpec,0,0,0) ;

  std::vector<RooCmdArg> args;
  args += arg1, arg2, arg3, arg4, arg5, arg6, arg7;

  bool found_cut_arg = false;
  for (std::vector<RooCmdArg>::iterator it=args.begin(), end=args.end();
       it != end; ++it) {
    std::string name = it->GetName();
    if (name == "CutSpec") {
      if ((void*)it->getString(0) != NULL) {
        std::string user_cut_string(it->getString(0));
        if (user_cut_string.length() > 0) stream_cut_variables << "&&" << user_cut_string;
      }
      cut_variables = stream_cut_variables.str();
      if (cut_variables.length() > 2) {
        cut_variables = cut_variables.substr(2);
      }

      sinfo << "Converting dataset with cut '" << cut_variables << "'" <<  endmsg;
      *it = Cut(cut_variables.c_str());
      found_cut_arg = true;
    }
  }
  if (!found_cut_arg) {
    cut_variables = stream_cut_variables.str();
    if (cut_variables.length() > 0) {
      cut_variables = cut_variables.substr(2);
      std::string name = args[6].GetName();
      if (name != "") {
        swarn << "doocore::io::EasyTuple::ConvertToDataSet(...): Have to delete last passed RooCmdArg " << name << " to apply necessary cut." << endmsg;
      }
      sinfo << "Converting dataset with cut " << cut_variables << endmsg;
      args[6] = Cut(cut_variables.c_str());
    }
  }

  //temp: copy tree
  //tree_ = tree_->CopyTree("", "", 800000);
  //tree_->SetEntries(300000);

  dataset_ = new RooDataSet("dataset","dataset",new_set,Import(*tree_), args[0],
                            args[1], args[2], args[3], args[4], args[5], args[6]);

  for (std::vector<RooFormulaVar*>::const_iterator it = formulas.begin();
       it != formulas.end(); ++it) {
    sinfo << "Adding formula " << (*it)->GetName() << " to dataset." << endmsg;
    dataset_->addColumn(**it);
  }

  return *dataset_;
}

RooRealVar& doocore::io::EasyTuple::Var(const std::string& name) {
  if (dataset_ != NULL && dataset_->get()->find(name.c_str()) != NULL) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(dataset_->get()->find(name.c_str()));
    if (var != NULL) {
      return *var;
    } else {
      serr << "Variable " << name << " in dataset is not of type RooRealVar." << endmsg;
      throw 5;
    }
  } else {
    serr << "Variable " << name << " not in dataset or tuple not converted to dataset." << endmsg;
    throw 5;
  }
}

const RooRealVar& doocore::io::EasyTuple::Var(const std::string& name) const {
  return const_cast<doocore::io::EasyTuple*>(this)->Var(name);
}
<commit_msg>EasyTuple: default cut behaviour changed to inclusive cuts<commit_after>#include "doocore/io/EasyTuple.h"

// from STL
#include <string>
#include <sstream>
#include <vector>

// from Boost
#include <boost/assign/std/vector.hpp>
using namespace boost::assign;

// from ROOT
#include "TFile.h"
#include "TTree.h"

// from RooFit
#include "RooArgSet.h"
#include "RooLinkedListIter.h"
#include "RooAbsArg.h"
#include "RooDataSet.h"
#include "RooFormulaVar.h"
#include "RooCategory.h"
#include "RooRealVar.h"
#include "RooCmdArg.h"

// from project
#include "doocore/io/MsgStream.h"

using namespace ROOT;
using namespace RooFit;

doocore::io::EasyTuple::EasyTuple(const std::string& file_name, const std::string& tree_name, const RooArgSet& argset)
: file_(NULL),
  tree_(NULL),
  argset_(NULL),
  dataset_(NULL),
  tree_name_(tree_name),
  num_maximum_events_(-1),
  cut_variable_range_(kCutInclusive)
{
  file_ = new TFile(file_name.c_str());
  argset_ = new RooArgSet(argset);

  if (file_ == NULL || file_->IsZombie() || file_->GetNkeys() <= 0) {
    serr << "File " << file_name << " could not be opened properly." << endmsg;
    throw 1;
  }

  tree_ = dynamic_cast<TTree*>(file_->Get(tree_name.c_str()));
  if (tree_ == NULL) {
    serr << "Tree " << tree_name << " could not be opened properly." << endmsg;
    throw 2;
  }

  if (argset.getSize() > 0) tree_->SetBranchStatus("*", 0);

  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;

  while ((arg=(RooAbsArg*)it->Next())) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
    RooCategory* cat = dynamic_cast<RooCategory*>(arg);

    if (var != NULL || cat != NULL) {
      if (tree_->GetBranch(arg->GetName()) == NULL) {
        swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
      } else {
        tree_->SetBranchStatus(arg->GetName(), 1);
      }
    }
  }
  delete it;
}

doocore::io::EasyTuple::EasyTuple(TTree* tree, const RooArgSet& argset)
: file_(NULL),
tree_(tree),
argset_(NULL),
dataset_(NULL),
num_maximum_events_(-1),
cut_variable_range_(kCutInclusive)
{
  argset_ = new RooArgSet(argset);

  if (argset.getSize() > 0) tree_->SetBranchStatus("*", 0);

  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;

  while ((arg=(RooAbsArg*)it->Next())) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
    RooCategory* cat = dynamic_cast<RooCategory*>(arg);

    if (var != NULL || cat != NULL) {
      if (tree_->GetBranch(arg->GetName()) == NULL) {
        swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
      } else {
        tree_->SetBranchStatus(arg->GetName(), 1);
      }
    }
  }
  delete it;
}

doocore::io::EasyTuple::EasyTuple(const EasyTuple& other)
: file_(NULL),
tree_(NULL),
argset_(NULL),
dataset_(NULL),
tree_name_(other.tree_name_),
num_maximum_events_(other.num_maximum_events_),
cut_variable_range_(other.cut_variable_range_)
{
  argset_ = new RooArgSet(*other.argset_);

  if (other.file_ == NULL) {
    tree_ = other.tree_;
  } else {
    file_ = new TFile(other.file_->GetName());

    if (file_ == NULL || file_->IsZombie() || file_->GetNkeys() <= 0) {
      serr << "File could not be opened properly." << endmsg;
      throw 1;
    }

    tree_ = dynamic_cast<TTree*>(file_->Get(tree_name_.c_str()));
    if (tree_ == NULL) {
      serr << "Tree " << tree_name_ << " could not be opened properly." << endmsg;
      throw 2;
    }

    if (argset_->getSize() > 0) tree_->SetBranchStatus("*", 0);

    RooLinkedListIter* it  = (RooLinkedListIter*)argset_->createIterator();
    RooAbsArg*         arg = NULL;

    while ((arg=(RooAbsArg*)it->Next())) {
      RooRealVar* var = dynamic_cast<RooRealVar*>(arg);
      RooCategory* cat = dynamic_cast<RooCategory*>(arg);

      if (var != NULL || cat != NULL) {
        if (tree_->GetBranch(arg->GetName()) == NULL) {
          swarn << "Branch " << arg->GetName() << " not in tree. Ignoring." << endmsg;
        } else {
          tree_->SetBranchStatus(arg->GetName(), 1);
        }
      }
    }
    delete it;

    if (num_maximum_events_>=0) {
      set_num_maximum_events(num_maximum_events_);
    }

    if (other.dataset_ != NULL) {
      dataset_ = new RooDataSet(*other.dataset_);
    }
  }
}

doocore::io::EasyTuple::~EasyTuple() {
  if (dataset_ != NULL) delete dataset_;
  if (argset_ != NULL) delete argset_;
  if (tree_ != NULL && file_!= NULL) delete tree_;
  if (file_ != NULL) delete file_;
}

RooDataSet& doocore::io::EasyTuple::ConvertToDataSet(const RooCmdArg& arg1,
                                                     const RooCmdArg& arg2,
                                                     const RooCmdArg& arg3,
                                                     const RooCmdArg& arg4,
                                                     const RooCmdArg& arg5,
                                                     const RooCmdArg& arg6,
                                                     const RooCmdArg& arg7) {
  if (argset_ == NULL) {
    serr << "Internal argset not set. Cannot convert to RooDataSet without this." << endmsg;
    throw 4;
  }

  return ConvertToDataSet(*argset_, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}

RooDataSet& doocore::io::EasyTuple::ConvertToDataSet(const RooArgSet& argset,
                                                     const RooCmdArg& arg1,
                                                     const RooCmdArg& arg2,
                                                     const RooCmdArg& arg3,
                                                     const RooCmdArg& arg4,
                                                     const RooCmdArg& arg5,
                                                     const RooCmdArg& arg6,
                                                     const RooCmdArg& arg7) {
  if (dataset_ != NULL) {
    serr << "Dataset was converted before. Maybe you want to use doocore::io::EasyTuple::dataset()." << endmsg;
    throw 3;
  }

  // filter out formula vars and additionally cut on all variable ranges
  RooLinkedListIter* it  = (RooLinkedListIter*)argset.createIterator();
  RooAbsArg*         arg = NULL;
  RooArgSet          new_set;
  std::vector<RooFormulaVar*> formulas;
  std::string        cut_variables="";
  std::stringstream  stream_cut_variables;
  std::string        less_operator = cut_variable_range_==kCutInclusive ? "<=" : "<";
  std::string        greater_operator = cut_variable_range_==kCutInclusive ? ">=" : ">";

  while ((arg=(RooAbsArg*)it->Next())) {
    RooFormulaVar* formula = dynamic_cast<RooFormulaVar*>(arg);
    RooRealVar*    var     = dynamic_cast<RooRealVar*>(arg);

    if (formula == NULL) {
      new_set.add(*arg);

      if (var != NULL && cut_variable_range_ != kNoCuts) {
        if (var->hasMin()) stream_cut_variables << "&&" << var->GetName() << greater_operator << var->getMin();
        if (var->hasMax()) stream_cut_variables << "&&" << var->GetName() << less_operator << var->getMax();
      }
    } else {
      formulas.push_back(formula);
    }
  }
  delete it;

  // 	RooCmdArg(const char* name, Int_t i1 = 0, Int_t i2 = 0, Double_t d1 = 0, Double_t d2 = 0, const char* s1 = 0, const char* s2 = 0, const TObject* o1 = 0, const TObject* o2 = 0, const RooCmdArg* ca = 0, const char* s3 = 0, const RooArgSet* c1 = 0, const RooArgSet* c2 = 0)
  // RooCmdArg("CutSpec",0,0,0,0,cutSpec,0,0,0) ;

  std::vector<RooCmdArg> args;
  args += arg1, arg2, arg3, arg4, arg5, arg6, arg7;

  bool found_cut_arg = false;
  for (std::vector<RooCmdArg>::iterator it=args.begin(), end=args.end();
       it != end; ++it) {
    std::string name = it->GetName();
    if (name == "CutSpec") {
      if ((void*)it->getString(0) != NULL) {
        std::string user_cut_string(it->getString(0));
        if (user_cut_string.length() > 0) stream_cut_variables << "&&" << user_cut_string;
      }
      cut_variables = stream_cut_variables.str();
      if (cut_variables.length() > 2) {
        cut_variables = cut_variables.substr(2);
      }

      sinfo << "Converting dataset with cut '" << cut_variables << "'" <<  endmsg;
      *it = Cut(cut_variables.c_str());
      found_cut_arg = true;
    }
  }
  if (!found_cut_arg) {
    cut_variables = stream_cut_variables.str();
    if (cut_variables.length() > 0) {
      cut_variables = cut_variables.substr(2);
      std::string name = args[6].GetName();
      if (name != "") {
        swarn << "doocore::io::EasyTuple::ConvertToDataSet(...): Have to delete last passed RooCmdArg " << name << " to apply necessary cut." << endmsg;
      }
      sinfo << "Converting dataset with cut " << cut_variables << endmsg;
      args[6] = Cut(cut_variables.c_str());
    }
  }

  //temp: copy tree
  //tree_ = tree_->CopyTree("", "", 800000);
  //tree_->SetEntries(300000);

  dataset_ = new RooDataSet("dataset","dataset",new_set,Import(*tree_), args[0],
                            args[1], args[2], args[3], args[4], args[5], args[6]);

  for (std::vector<RooFormulaVar*>::const_iterator it = formulas.begin();
       it != formulas.end(); ++it) {
    sinfo << "Adding formula " << (*it)->GetName() << " to dataset." << endmsg;
    dataset_->addColumn(**it);
  }

  return *dataset_;
}

RooRealVar& doocore::io::EasyTuple::Var(const std::string& name) {
  if (dataset_ != NULL && dataset_->get()->find(name.c_str()) != NULL) {
    RooRealVar* var = dynamic_cast<RooRealVar*>(dataset_->get()->find(name.c_str()));
    if (var != NULL) {
      return *var;
    } else {
      serr << "Variable " << name << " in dataset is not of type RooRealVar." << endmsg;
      throw 5;
    }
  } else {
    serr << "Variable " << name << " not in dataset or tuple not converted to dataset." << endmsg;
    throw 5;
  }
}

const RooRealVar& doocore::io::EasyTuple::Var(const std::string& name) const {
  return const_cast<doocore::io::EasyTuple*>(this)->Var(name);
}
<|endoftext|>


<commit_before>#include "command.hpp"
#include <vector>
#include <string>

namespace cygscript {

class ExecCommand : public ICommand
{
	std::vector<std::wstring> _args;

public:
	/**
	 * Constructor.
	 *
	 * @param std::vector<std::wstring> args Wide arguments from main function
	 */
	ExecCommand(std::vector<std::wstring> args) : _args(args) {
	}

	/**
	 * Run command.
	 *
	 * @return int Exit code
	 */
	int run();

private:
	/**
	 * Get the arguments for script execution.
	 *
	 * @return std::vector<std::wstring> A list of wstring arguments
	 */
	std::vector<std::wstring> _getExecArgs();

	/**
	 * Get the command line for /bin/sh.
	 *
	 * @param const std::vector<std::wstring> args Wide arguments
	 * @return std::wstring Command line
	 */
	std::wstring _getExecCmd(const std::vector<std::wstring> args);

	/**
	 * Execute script using a given command line.
	 *
	 * @param std::wstring cmd_line Command line
	 * @throws std::runtime_error on failure
	 */
	void _execute(const std::wstring& cmd_line);

	/**
	 * Check whether given path exists and is a regular file or symlink.
	 *
	 * @param std::wstring path Path
	 * @return bool True if file exists
	 */
	bool _fileExists(const std::wstring& path);

	/**
	 * Check whether given path is in Windows format.
	 *
	 * @param std::wstring path Path
	 * @param bool must_exist Whether file must exist
	 * @return bool True if path is in Windows format
	 */
	bool _isWinPath(const std::wstring& path, bool must_exist);

	/**
	 * Convert Windows path to POSIX format.
	 *
	 * @param std::wstring path Windows formatted path
	 * @return std::string POSIX path in UTF-8 charset
	 */
	std::string _pathWinToPosix(const std::wstring& path);

	/**
	 * Convert 8.3 short path to long path format.
	 *
	 * @param const std::wstring& path Short path
	 * @return std::wstring Long path
	 */
	std::wstring _toLongPath(const std::wstring& path);

	/**
	 * Escape command line argument with Windows semantics.
	 *
	 * @param std::wstring arg Argument
	 * @return std::wstring Escaped argument
	 */
	std::wstring _escapeWinArg(const std::wstring& arg);

	/**
	 * Escape command line argument with Posix semantics.
	 *
	 * @param std::wstring arg Argument
	 * @return std::wstring Escaped argument
	 */
	std::wstring _escapePosixArg(const std::wstring& arg);

	/**
	 * Replace all occurences of a string.
	 *
	 * @param std::wstring& str String to modify
	 * @param const std::wstring& from Substring to search
	 * @param const std::wstring& to Replacement string
	 */
	void _replaceAll(std::wstring& str, const std::wstring& from,
	                 const std::wstring& to);

	/**
	 * Get readable script name for the shell window title.
	 *
	 * @return std::wstring
	 */
	std::wstring _getScriptName(const std::wstring& path);
};

}
<commit_msg>Fix comment<commit_after>#include "command.hpp"
#include <vector>
#include <string>

namespace cygscript {

class ExecCommand : public ICommand
{
	std::vector<std::wstring> _args;

public:
	/**
	 * Constructor.
	 *
	 * @param std::vector<std::wstring> args Wide arguments from main function
	 */
	ExecCommand(std::vector<std::wstring> args) : _args(args) {
	}

	/**
	 * Run command.
	 *
	 * @return int Exit code
	 */
	int run();

private:
	/**
	 * Get the arguments for script execution.
	 *
	 * @return std::vector<std::wstring> A list of wstring arguments
	 */
	std::vector<std::wstring> _getExecArgs();

	/**
	 * Get the command line for /bin/bash.
	 *
	 * @param const std::vector<std::wstring> args Wide arguments
	 * @return std::wstring Command line
	 */
	std::wstring _getExecCmd(const std::vector<std::wstring> args);

	/**
	 * Execute script using a given command line.
	 *
	 * @param std::wstring cmd_line Command line
	 * @throws std::runtime_error on failure
	 */
	void _execute(const std::wstring& cmd_line);

	/**
	 * Check whether given path exists and is a regular file or symlink.
	 *
	 * @param std::wstring path Path
	 * @return bool True if file exists
	 */
	bool _fileExists(const std::wstring& path);

	/**
	 * Check whether given path is in Windows format.
	 *
	 * @param std::wstring path Path
	 * @param bool must_exist Whether file must exist
	 * @return bool True if path is in Windows format
	 */
	bool _isWinPath(const std::wstring& path, bool must_exist);

	/**
	 * Convert Windows path to POSIX format.
	 *
	 * @param std::wstring path Windows formatted path
	 * @return std::string POSIX path in UTF-8 charset
	 */
	std::string _pathWinToPosix(const std::wstring& path);

	/**
	 * Convert 8.3 short path to long path format.
	 *
	 * @param const std::wstring& path Short path
	 * @return std::wstring Long path
	 */
	std::wstring _toLongPath(const std::wstring& path);

	/**
	 * Escape command line argument with Windows semantics.
	 *
	 * @param std::wstring arg Argument
	 * @return std::wstring Escaped argument
	 */
	std::wstring _escapeWinArg(const std::wstring& arg);

	/**
	 * Escape command line argument with Posix semantics.
	 *
	 * @param std::wstring arg Argument
	 * @return std::wstring Escaped argument
	 */
	std::wstring _escapePosixArg(const std::wstring& arg);

	/**
	 * Replace all occurences of a string.
	 *
	 * @param std::wstring& str String to modify
	 * @param const std::wstring& from Substring to search
	 * @param const std::wstring& to Replacement string
	 */
	void _replaceAll(std::wstring& str, const std::wstring& from,
	                 const std::wstring& to);

	/**
	 * Get readable script name for the shell window title.
	 *
	 * @return std::wstring
	 */
	std::wstring _getScriptName(const std::wstring& path);
};

}
<|endoftext|>


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

#include "GrGradientEffects.h"
#include "gl/GrGLProgramStage.h"
#include "GrProgramStageFactory.h"

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

class GrGLRadialGradient : public GrGLProgramStage {

public:

    GrGLRadialGradient(const GrProgramStageFactory& factory,
                       const GrCustomStage&) : INHERITED (factory) { }
    virtual ~GrGLRadialGradient() { }

    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) { return 0; }

private:

    typedef GrGLProgramStage INHERITED;

};

void GrGLRadialGradient::emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) {
    state->fSampleCoords.printf("vec2(length(%s.xy), 0.5)",
                                state->fSampleCoords.c_str());
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

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

GrRadialGradient::GrRadialGradient() {

}

GrRadialGradient::~GrRadialGradient() {

}

const GrProgramStageFactory& GrRadialGradient::getFactory() const {
    return GrTProgramStageFactory<GrRadialGradient>::getInstance();
}

bool GrRadialGradient::isEqual(const GrCustomStage& sBase) const {
    return true;
}

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

class GrGLRadial2Gradient : public GrGLProgramStage {

public:

    GrGLRadial2Gradient(const GrProgramStageFactory& factory,
                        const GrCustomStage&);
    virtual ~GrGLRadial2Gradient() { }

    virtual void setupVariables(GrGLShaderBuilder* state,
                                int stage) SK_OVERRIDE;
    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE;
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;
    virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
    virtual void setData(const GrGLInterface*,
                         const GrGLTexture&,
                         const GrCustomStage&,
                         int stageNum) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) {
        return (static_cast<const GrRadial2Gradient&>(s).isDegenerate());
    }

protected:

    const GrGLShaderVar* fParamVar;
    GrGLint fParamLocation;

    const char* fVSVaryingName;
    const char* fFSVaryingName;

    bool fIsDegenerate;

    // @{
    /// Values last uploaded as uniforms

    GrScalar fCachedCenter;
    GrScalar fCachedRadius;
    SkBool8  fCachedPosRoot;

    // @}

private:

    typedef GrGLProgramStage INHERITED;

};

GrGLRadial2Gradient::GrGLRadial2Gradient(
        const GrProgramStageFactory& factory,
        const GrCustomStage& baseData)
    : INHERITED(factory)
    , fParamVar(NULL)
    , fVSVaryingName(NULL)
    , fFSVaryingName(NULL)
    , fCachedCenter(GR_ScalarMax)
    , fCachedRadius(-GR_ScalarMax)
    , fCachedPosRoot(0) {

    const GrRadial2Gradient& data =
        static_cast<const GrRadial2Gradient&>(baseData);
    fIsDegenerate = data.isDegenerate();
}

void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* state, int stage) {
    fParamVar = &state->addUniform(
        GrGLShaderBuilder::kBoth_VariableLifetime,
        kFloat_GrSLType, "uRadial2Params", stage, 6);

    fParamLocation = GrGLProgramStage::kUseUniform;

    // For radial gradients without perspective we can pass the linear
    // part of the quadratic as a varying.
    if (state->fVaryingDims == state->fCoordDims) {
        state->addVarying(kFloat_GrSLType, "Radial2BCoeff", stage,
                          &fVSVaryingName, &fFSVaryingName);
    }
}

void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) {
    GrStringBuilder* code = &state->fVSCode;
    GrStringBuilder p2;
    GrStringBuilder p3;
    fParamVar->appendArrayAccess(2, &p2);
    fParamVar->appendArrayAccess(3, &p3);

    // For radial gradients without perspective we can pass the linear
    // part of the quadratic as a varying.
    if (state->fVaryingDims == state->fCoordDims) {
        // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
        code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
                      fVSVaryingName, p2.c_str(),
                      vertexCoords, p3.c_str());
    }
}

void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) {
    GrStringBuilder* code = &state->fFSCode;
    GrStringBuilder cName("c");
    GrStringBuilder ac4Name("ac4");
    GrStringBuilder rootName("root");
    GrStringBuilder p0;
    GrStringBuilder p1;
    GrStringBuilder p2;
    GrStringBuilder p3;
    GrStringBuilder p4;
    GrStringBuilder p5;
    fParamVar->appendArrayAccess(0, &p0);
    fParamVar->appendArrayAccess(1, &p1);
    fParamVar->appendArrayAccess(2, &p2);
    fParamVar->appendArrayAccess(3, &p3);
    fParamVar->appendArrayAccess(4, &p4);
    fParamVar->appendArrayAccess(5, &p5);

    // If we we're able to interpolate the linear component,
    // bVar is the varying; otherwise compute it
    GrStringBuilder bVar;
    if (state->fCoordDims == state->fVaryingDims) {
        bVar = fFSVaryingName;
        GrAssert(2 == state->fVaryingDims);
    } else {
        GrAssert(3 == state->fVaryingDims);
        bVar = "b";
        //bVar.appendS32(stageNum);
        code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
                      bVar.c_str(), p2.c_str(),
                      state->fSampleCoords.c_str(), p3.c_str());
    }

    // c = (x^2)+(y^2) - params[4]
    code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
                  cName.c_str(), state->fSampleCoords.c_str(),
                  state->fSampleCoords.c_str(),
                  p4.c_str());

    // If we aren't degenerate, emit some extra code, and accept a slightly
    // more complex coord.
    if (fIsDegenerate) {

        // ac4 = 4.0 * params[0] * c
        code->appendf("\tfloat %s = %s * 4.0 * %s;\n",
                      ac4Name.c_str(), p0.c_str(),
                      cName.c_str());

        // root = sqrt(b^2-4ac)
        // (abs to avoid exception due to fp precision)
        code->appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
                      rootName.c_str(), bVar.c_str(), bVar.c_str(),
                      ac4Name.c_str());

        // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
        // y coord is 0.5 (texture is effectively 1D)
        state->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)",
                            bVar.c_str(), p5.c_str(),
                            rootName.c_str(), p1.c_str());
    } else {
        // x coord is: -c/b
        // y coord is 0.5 (texture is effectively 1D)
        state->fSampleCoords.printf("vec2((-%s / %s), 0.5)",
                            cName.c_str(), bVar.c_str());
    }
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

void GrGLRadial2Gradient::initUniforms(const GrGLInterface* gl, int programID) {
    GR_GL_CALL_RET(gl, fParamLocation,
        GetUniformLocation(programID, fParamVar->getName().c_str()));
}

void GrGLRadial2Gradient::setData(const GrGLInterface* gl,
                                 const GrGLTexture& texture,
                                 const GrCustomStage& baseData,
                                 int stageNum) {
    const GrRadial2Gradient& data =
        static_cast<const GrRadial2Gradient&>(baseData);
    GrAssert(data.isDegenerate() == fIsDegenerate);
    GrScalar centerX1 = data.center();
    GrScalar radius0 = data.radius();
    if (fCachedCenter != centerX1 ||
        fCachedRadius != radius0 ||
        fCachedPosRoot != data.isPosRoot()) {

        GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;

        // When we're in the degenerate (linear) case, the second
        // value will be INF but the program doesn't read it. (We
        // use the same 6 uniforms even though we don't need them
        // all in the linear case just to keep the code complexity
        // down).
        float values[6] = {
            GrScalarToFloat(a),
            1 / (2.f * GrScalarToFloat(a)),
            GrScalarToFloat(centerX1),
            GrScalarToFloat(radius0),
            GrScalarToFloat(GrMul(radius0, radius0)),
            data.isPosRoot() ? 1.f : -1.f
        };

        GR_GL_CALL(gl, Uniform1fv(fParamLocation, 6, values));
        fCachedCenter = centerX1;
        fCachedRadius = radius0;
        fCachedPosRoot = data.isPosRoot();
    }
}

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

GrRadial2Gradient::GrRadial2Gradient(GrScalar center,
                                     GrScalar radius,
                                     bool posRoot)
    : fCenterX1 (center)
    , fRadius0 (radius)
    , fPosRoot (posRoot) {

}

GrRadial2Gradient::~GrRadial2Gradient() {

}

const GrProgramStageFactory& GrRadial2Gradient::getFactory() const {
    return GrTProgramStageFactory<GrRadial2Gradient>::getInstance();
}

bool GrRadial2Gradient::isEqual(const GrCustomStage& sBase) const {
    const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
    return (this->isDegenerate() == s.isDegenerate());
}

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

class GrGLSweepGradient : public GrGLProgramStage {

public:

    GrGLSweepGradient(const GrProgramStageFactory& factory,
                      const GrCustomStage&) : INHERITED (factory) { }
    virtual ~GrGLSweepGradient() { }

    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) { return 0; }

private:

    typedef GrGLProgramStage INHERITED;

};

void GrGLSweepGradient::emitFS(GrGLShaderBuilder* state,
                              const char* outputColor,
                              const char* inputColor,
                              const char* samplerName) {
    state->fSampleCoords.printf(
        "vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)",
        state->fSampleCoords.c_str(), state->fSampleCoords.c_str());
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

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

GrSweepGradient::GrSweepGradient() {

}

GrSweepGradient::~GrSweepGradient() {

}

const GrProgramStageFactory& GrSweepGradient::getFactory() const {
    return GrTProgramStageFactory<GrSweepGradient>::getInstance();
}

bool GrSweepGradient::isEqual(const GrCustomStage& sBase) const {
    return true;
}

<commit_msg>SkBool8 -> bool to suppress warning (verbal LGTM from TomH)<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGradientEffects.h"
#include "gl/GrGLProgramStage.h"
#include "GrProgramStageFactory.h"

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

class GrGLRadialGradient : public GrGLProgramStage {

public:

    GrGLRadialGradient(const GrProgramStageFactory& factory,
                       const GrCustomStage&) : INHERITED (factory) { }
    virtual ~GrGLRadialGradient() { }

    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) { return 0; }

private:

    typedef GrGLProgramStage INHERITED;

};

void GrGLRadialGradient::emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) {
    state->fSampleCoords.printf("vec2(length(%s.xy), 0.5)",
                                state->fSampleCoords.c_str());
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

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

GrRadialGradient::GrRadialGradient() {

}

GrRadialGradient::~GrRadialGradient() {

}

const GrProgramStageFactory& GrRadialGradient::getFactory() const {
    return GrTProgramStageFactory<GrRadialGradient>::getInstance();
}

bool GrRadialGradient::isEqual(const GrCustomStage& sBase) const {
    return true;
}

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

class GrGLRadial2Gradient : public GrGLProgramStage {

public:

    GrGLRadial2Gradient(const GrProgramStageFactory& factory,
                        const GrCustomStage&);
    virtual ~GrGLRadial2Gradient() { }

    virtual void setupVariables(GrGLShaderBuilder* state,
                                int stage) SK_OVERRIDE;
    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE;
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;
    virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE;
    virtual void setData(const GrGLInterface*,
                         const GrGLTexture&,
                         const GrCustomStage&,
                         int stageNum) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) {
        return (static_cast<const GrRadial2Gradient&>(s).isDegenerate());
    }

protected:

    const GrGLShaderVar* fParamVar;
    GrGLint fParamLocation;

    const char* fVSVaryingName;
    const char* fFSVaryingName;

    bool fIsDegenerate;

    // @{
    /// Values last uploaded as uniforms

    GrScalar fCachedCenter;
    GrScalar fCachedRadius;
    bool     fCachedPosRoot;

    // @}

private:

    typedef GrGLProgramStage INHERITED;

};

GrGLRadial2Gradient::GrGLRadial2Gradient(
        const GrProgramStageFactory& factory,
        const GrCustomStage& baseData)
    : INHERITED(factory)
    , fParamVar(NULL)
    , fVSVaryingName(NULL)
    , fFSVaryingName(NULL)
    , fCachedCenter(GR_ScalarMax)
    , fCachedRadius(-GR_ScalarMax)
    , fCachedPosRoot(0) {

    const GrRadial2Gradient& data =
        static_cast<const GrRadial2Gradient&>(baseData);
    fIsDegenerate = data.isDegenerate();
}

void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* state, int stage) {
    fParamVar = &state->addUniform(
        GrGLShaderBuilder::kBoth_VariableLifetime,
        kFloat_GrSLType, "uRadial2Params", stage, 6);

    fParamLocation = GrGLProgramStage::kUseUniform;

    // For radial gradients without perspective we can pass the linear
    // part of the quadratic as a varying.
    if (state->fVaryingDims == state->fCoordDims) {
        state->addVarying(kFloat_GrSLType, "Radial2BCoeff", stage,
                          &fVSVaryingName, &fFSVaryingName);
    }
}

void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) {
    GrStringBuilder* code = &state->fVSCode;
    GrStringBuilder p2;
    GrStringBuilder p3;
    fParamVar->appendArrayAccess(2, &p2);
    fParamVar->appendArrayAccess(3, &p3);

    // For radial gradients without perspective we can pass the linear
    // part of the quadratic as a varying.
    if (state->fVaryingDims == state->fCoordDims) {
        // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
        code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
                      fVSVaryingName, p2.c_str(),
                      vertexCoords, p3.c_str());
    }
}

void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) {
    GrStringBuilder* code = &state->fFSCode;
    GrStringBuilder cName("c");
    GrStringBuilder ac4Name("ac4");
    GrStringBuilder rootName("root");
    GrStringBuilder p0;
    GrStringBuilder p1;
    GrStringBuilder p2;
    GrStringBuilder p3;
    GrStringBuilder p4;
    GrStringBuilder p5;
    fParamVar->appendArrayAccess(0, &p0);
    fParamVar->appendArrayAccess(1, &p1);
    fParamVar->appendArrayAccess(2, &p2);
    fParamVar->appendArrayAccess(3, &p3);
    fParamVar->appendArrayAccess(4, &p4);
    fParamVar->appendArrayAccess(5, &p5);

    // If we we're able to interpolate the linear component,
    // bVar is the varying; otherwise compute it
    GrStringBuilder bVar;
    if (state->fCoordDims == state->fVaryingDims) {
        bVar = fFSVaryingName;
        GrAssert(2 == state->fVaryingDims);
    } else {
        GrAssert(3 == state->fVaryingDims);
        bVar = "b";
        //bVar.appendS32(stageNum);
        code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
                      bVar.c_str(), p2.c_str(),
                      state->fSampleCoords.c_str(), p3.c_str());
    }

    // c = (x^2)+(y^2) - params[4]
    code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
                  cName.c_str(), state->fSampleCoords.c_str(),
                  state->fSampleCoords.c_str(),
                  p4.c_str());

    // If we aren't degenerate, emit some extra code, and accept a slightly
    // more complex coord.
    if (fIsDegenerate) {

        // ac4 = 4.0 * params[0] * c
        code->appendf("\tfloat %s = %s * 4.0 * %s;\n",
                      ac4Name.c_str(), p0.c_str(),
                      cName.c_str());

        // root = sqrt(b^2-4ac)
        // (abs to avoid exception due to fp precision)
        code->appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
                      rootName.c_str(), bVar.c_str(), bVar.c_str(),
                      ac4Name.c_str());

        // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
        // y coord is 0.5 (texture is effectively 1D)
        state->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)",
                            bVar.c_str(), p5.c_str(),
                            rootName.c_str(), p1.c_str());
    } else {
        // x coord is: -c/b
        // y coord is 0.5 (texture is effectively 1D)
        state->fSampleCoords.printf("vec2((-%s / %s), 0.5)",
                            cName.c_str(), bVar.c_str());
    }
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

void GrGLRadial2Gradient::initUniforms(const GrGLInterface* gl, int programID) {
    GR_GL_CALL_RET(gl, fParamLocation,
        GetUniformLocation(programID, fParamVar->getName().c_str()));
}

void GrGLRadial2Gradient::setData(const GrGLInterface* gl,
                                 const GrGLTexture& texture,
                                 const GrCustomStage& baseData,
                                 int stageNum) {
    const GrRadial2Gradient& data =
        static_cast<const GrRadial2Gradient&>(baseData);
    GrAssert(data.isDegenerate() == fIsDegenerate);
    GrScalar centerX1 = data.center();
    GrScalar radius0 = data.radius();
    if (fCachedCenter != centerX1 ||
        fCachedRadius != radius0 ||
        fCachedPosRoot != data.isPosRoot()) {

        GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;

        // When we're in the degenerate (linear) case, the second
        // value will be INF but the program doesn't read it. (We
        // use the same 6 uniforms even though we don't need them
        // all in the linear case just to keep the code complexity
        // down).
        float values[6] = {
            GrScalarToFloat(a),
            1 / (2.f * GrScalarToFloat(a)),
            GrScalarToFloat(centerX1),
            GrScalarToFloat(radius0),
            GrScalarToFloat(GrMul(radius0, radius0)),
            data.isPosRoot() ? 1.f : -1.f
        };

        GR_GL_CALL(gl, Uniform1fv(fParamLocation, 6, values));
        fCachedCenter = centerX1;
        fCachedRadius = radius0;
        fCachedPosRoot = data.isPosRoot();
    }
}

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

GrRadial2Gradient::GrRadial2Gradient(GrScalar center,
                                     GrScalar radius,
                                     bool posRoot)
    : fCenterX1 (center)
    , fRadius0 (radius)
    , fPosRoot (posRoot) {

}

GrRadial2Gradient::~GrRadial2Gradient() {

}

const GrProgramStageFactory& GrRadial2Gradient::getFactory() const {
    return GrTProgramStageFactory<GrRadial2Gradient>::getInstance();
}

bool GrRadial2Gradient::isEqual(const GrCustomStage& sBase) const {
    const GrRadial2Gradient& s = static_cast<const GrRadial2Gradient&>(sBase);
    return (this->isDegenerate() == s.isDegenerate());
}

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

class GrGLSweepGradient : public GrGLProgramStage {

public:

    GrGLSweepGradient(const GrProgramStageFactory& factory,
                      const GrCustomStage&) : INHERITED (factory) { }
    virtual ~GrGLSweepGradient() { }

    virtual void emitVS(GrGLShaderBuilder* state,
                        const char* vertexCoords) SK_OVERRIDE { }
    virtual void emitFS(GrGLShaderBuilder* state,
                        const char* outputColor,
                        const char* inputColor,
                        const char* samplerName) SK_OVERRIDE;

    static StageKey GenKey(const GrCustomStage& s) { return 0; }

private:

    typedef GrGLProgramStage INHERITED;

};

void GrGLSweepGradient::emitFS(GrGLShaderBuilder* state,
                              const char* outputColor,
                              const char* inputColor,
                              const char* samplerName) {
    state->fSampleCoords.printf(
        "vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)",
        state->fSampleCoords.c_str(), state->fSampleCoords.c_str());
    state->fComplexCoord = true;

    state->emitDefaultFetch(outputColor, samplerName);
}

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

GrSweepGradient::GrSweepGradient() {

}

GrSweepGradient::~GrSweepGradient() {

}

const GrProgramStageFactory& GrSweepGradient::getFactory() const {
    return GrTProgramStageFactory<GrSweepGradient>::getInstance();
}

bool GrSweepGradient::isEqual(const GrCustomStage& sBase) const {
    return true;
}

<|endoftext|>