<commit_before>#include <set>
#include <vector>

#include "entitysystem.h"
#include "cmapclient.h"
#include "cmapserver.h"
#include "connection.h"
#include "systems/chatsystem.h"
#include "systems/inventorysystem.h"
#include "systems/luasystem.h"
#include "systems/mapsystem.h"
#include "systems/movementsystem.h"
#include "systems/partysystem.h"
#include "systems/updatesystem.h"

using namespace RoseCommon;
EntitySystem::EntitySystem(CMapServer *server) : systemManager_(*this), server_(server) {
  systemManager_.add<Systems::MovementSystem>();
  systemManager_.add<Systems::UpdateSystem>();
  systemManager_.add<Systems::ChatSystem>();
  systemManager_.add<Systems::InventorySystem>();
  systemManager_.add<Systems::PartySystem>();
  systemManager_.add<Systems::MapSystem>();
  systemManager_.add<Systems::LuaSystem>();
}
EntityManager& EntitySystem::getEntityManager() { return entityManager_; }

Entity EntitySystem::buildItemEntity(Entity creator, RoseCommon::Item&& item) {
  Entity e = create();
  e.assign<Item>(std::move(item));
  auto pos = creator.component<Position>();
  e.assign<Position>(pos->x_, pos->y_, pos->map_, 0);
  auto basic = e.assign<BasicInfo>();
  basic->ownerId_ = creator.component<BasicInfo>()->id_;
  basic->id_ = id_manager_.get_free_id();
  itemToEntity_[basic->id_] = e;
  return e;
}

void EntitySystem::registerEntity(Entity entity) {
  if (!entity) return;
  auto basic = entity.component<BasicInfo>();
  if (!basic || basic->name_ == "" || !basic->id_) return;
  nameToEntity_[basic->name_] = entity;
  idToEntity_[basic->id_] = entity;
}

Entity EntitySystem::getItemEntity(uint32_t id) { return itemToEntity_[id]; }

Entity EntitySystem::getEntity(const std::string& name) { return nameToEntity_[name]; }

Entity EntitySystem::getEntity(uint32_t charId) { return idToEntity_[charId]; }

void EntitySystem::update(double dt) {
  std::lock_guard<std::mutex> lock(access_);
  for (auto& it : create_commands_) {
    it->execute(*this);
  }
  create_commands_.clear();
  while (toDispatch_.size()) {
    auto tmp = std::move(toDispatch_.front());
    systemManager_.dispatch(tmp.first, *tmp.second);
    toDispatch_.pop();
  }
  systemManager_.update(dt);
  for (auto& it : delete_commands_) {
    it->execute(*this);
  }
  delete_commands_.clear();
}

void EntitySystem::destroy(Entity entity) {
  if (!entity) return;
  std::unique_ptr<CommandBase> ptr{new Command([entity] (EntitySystem &) {
      if (!entity) return;
      if (auto client = getClient(entity); client)
        CMapServer::SendPacket(client, CMapServer::eSendType::EVERYONE_BUT_ME,
                               *makePacket<ePacketType::PAKWC_REMOVE_OBJECT>(entity));
      else
        CMapServer::SendPacket({}, CMapServer::eSendType::EVERYONE,
                               *makePacket<ePacketType::PAKWC_REMOVE_OBJECT>(entity));
      saveCharacter(entity.component<CharacterInfo>()->charId_, entity);
      auto basic = entity.component<BasicInfo>();
      nameToEntity_.erase(basic->name_);
      idToEntity_.erase(basic->id_);
      id_manager_.release_id(basic->id_);
      it.destroy();
    })};
  std::lock_guard<std::mutex> lock(access_);
  create_commands_.emplace_back(std::move(ptr));
}

Entity EntitySystem::create() { return entityManager_.create(); }

bool EntitySystem::isNearby(Entity a, Entity b) {
  return true;  // FIXME : actually implement the sight calculation instead of the distance
  if (!a || !b) return false;
  auto posa = a.component<Position>();
  auto posb = b.component<Position>();
  if (!posa || !posb) return false;  // FIXME : is it a bug if there is no position?
  if (posa->map_ != posb->map_) return false;
  double dist = (posa->x_ - posb->x_) * (posa->x_ - posb->x_) + (posa->y_ - posb->y_) * (posa->y_ - posb->y_);
  if (dist > NEARBY_DIST) return false;
  return true;
}

bool EntitySystem::dispatch(Entity entity, std::unique_ptr<RoseCommon::CRosePacket> packet) {
  if (!entity) return false;
  if (systemManager_.wouldDispatch(*packet)) {
    std::lock_guard<std::mutex> lock(access_);
    toDispatch_.emplace(std::make_pair(entity, std::move(packet)));
    return true;
  }
  return false;
}

Entity EntitySystem::loadCharacter(uint32_t charId, bool platinium) {
  auto conn = Core::connectionPool.getConnection(Core::osirose);
  Core::CharacterTable characters{};
  Core::InventoryTable inventoryTable{};
  Core::SkillTable skillsTable{};

  auto charRes = conn(sqlpp::select(sqlpp::count(characters.id), sqlpp::all_of(characters))
                          .from(characters)
                          .where(characters.id == charId));

  std::lock_guard<std::mutex> lock(access_);
  auto entity = create();
  if (static_cast<long>(charRes.front().count) != 1L) {
    entity.destroy();
    return Entity();
  }
  const auto& charRow = charRes.front();

  entity.assign<Position>(charRow);
  entity.assign<BasicInfo>(charRow, id_manager_.get_free_id());
  entity.assign<Stats>(charRow);
  entity.assign<AdvancedInfo>(charRow);
  entity.assign<CharacterGraphics>(charRow);
  entity.assign<CharacterInfo>(charRow, platinium, charId);

  // TODO : write the pat initialization code
  auto skills = entity.assign<Skills>();
  auto skillRes =
      conn(sqlpp::select(skillsTable.id, skillsTable.level).from(skillsTable).where(skillsTable.charId == charId));
  skills->loadFromResult(skillRes);

  // TODO : write the hotbar table and loading code
  entity.assign<Hotbar>();
  entity.assign<StatusEffects>();
  entity.assign<RidingItems>();
  entity.assign<BulletItems>();

  // TODO : write the inventory code
  // auto luaSystem = systemManager_.get<Systems::LuaSystem>();
  auto inventory = entity.assign<Inventory>();

  auto invRes =
      conn(sqlpp::select(sqlpp::all_of(inventoryTable)).from(inventoryTable).where(inventoryTable.charId == charId));
  inventory->loadFromResult(invRes, get<Systems::InventorySystem>());

  Systems::UpdateSystem::calculateSpeed(entity);

  entity.assign<Quests>();

  Core::WishTable wish{};
  auto wishRes = conn(sqlpp::select(sqlpp::all_of(wish)).from(wish).where(wish.charId == charId));
  auto wishlist = entity.assign<Wishlist>();
  wishlist->loadFromResult(wishRes, get<Systems::InventorySystem>());

  // auto lua = entity.assign<EntityAPI>();

  // luaSystem->loadScript(entity, "function onInit()\ndisplay('test')\nend");
  // lua->onInit();

  registerEntity(entity);
  return entity;
}

void EntitySystem::saveCharacter(uint32_t charId, Entity entity) {
  if (!entity) return;
  auto conn = Core::connectionPool.getConnection(Core::osirose);
  Core::CharacterTable characters{};

  using sqlpp::parameter;

  auto update = sqlpp::dynamic_update(conn.get(), characters).dynamic_set().where(characters.id == charId);
  entity.component<Position>()->commitToUpdate<decltype(characters)>(update);
  entity.component<BasicInfo>()->commitToUpdate<decltype(characters)>(update);
  entity.component<Stats>()->commitToUpdate<decltype(characters)>(update);
  entity.component<AdvancedInfo>()->commitToUpdate<decltype(characters)>(update);
  // entity.component<CharacterGraphics>()->commitToUpdate(update);
  entity.component<CharacterInfo>()->commitToUpdate<decltype(characters)>(update);
  // entity.component<Hotbar>()->commitToUpdate(update);
  // entity.component<StatusEffects>()->commitToUpdate(update);
  // entity.component<RidingItems>()->commitToUpdate(update);
  // entity.component<BulletItems>()->commitToUpdate(update);

  conn->run(update);

  // entity.component<Skills>()->commitToUpdate(updateSkills);

  Core::InventoryTable inv{};
  auto invRes = conn(sqlpp::select(sqlpp::all_of(inv)).from(inv).where(inv.charId == charId));

  const auto& items = entity.component<Inventory>()->items_;

  std::vector<size_t> toDelete;
  std::vector<size_t> toUpdate;
  std::set<size_t> modified;
  std::vector<size_t> toInsert;

  for (const auto& row : invRes) {
    if (row.slot >= Inventory::maxItems)
      toDelete.emplace_back(row.slot);  // FIXME: that should never happen
    else if (!items[row.slot])
      toDelete.emplace_back(row.slot);
    else if (items[row.slot] != Item(row))
      toUpdate.emplace_back(row.slot);
    modified.insert(row.slot);
  }
  size_t i = 0;
  for (const auto& item : items) {
    if (item && modified.find(i) == modified.end()) toInsert.emplace_back(i);
    ++i;
  }

  for (auto it : toDelete) conn(sqlpp::remove_from(inv).where(inv.charId == charId and inv.slot == it));
  for (auto it : toUpdate) {
    auto update = sqlpp::dynamic_update(conn.get(), inv).dynamic_set().where(inv.charId == charId and inv.slot == it);
    items[it].commitToUpdate<decltype(inv)>(update);
    conn->run(update);
  }
  for (auto it : toInsert) {
    auto insert = sqlpp::dynamic_insert_into(conn.get(), inv).dynamic_set();
    items[it].commitToInsert<decltype(inv)>(insert);
    insert.insert_list.add(inv.slot = it);
    insert.insert_list.add(inv.charId = charId);
    conn->run(insert);
  }
}

Entity EntitySystem::create_warpgate(std::string alias, int dest_map_id, float dest_x, float dest_y, float dest_z,
                    int map_id, float x, float y, float z, float angle,
                    float x_scale, float y_scale, float z_scale) {
  return {};
}

Entity EntitySystem::create_npc(std::string npc_lua, int npc_id, int map_id, float x, float y, float z, float angle) {
    Entity e = create();
    std::unique_ptr<CommandBase> ptr{new Command([npc_lua, npc_id, map_id, x, y, z, angle, e] (EntitySystem &es) mutable {
      if (!e) return;
      e.assign<BasicInfo>(es.id_manager_.get_free_id());
      e.assign<AdvancedInfo>();
      e.assign<CharacterInfo>();

      uint16_t dialog_id = 0;
      if (!npc_lua.empty()) {
        dialog_id = std::stoi(npc_lua);
      }
      e.assign<Npc>(npc_id, dialog_id);
      auto pos = e.assign<Position>(x * 100, y * 100, map_id, 0);

      pos->z_ = static_cast<uint16_t>(z);
      pos->angle_ = angle;
      //e.assign<EntityApi>();
    })};
    create_commands_.emplace_back(std::move(ptr));
    return e;
}

Entity EntitySystem::create_spawner(std::string alias, int mob_id, int mob_count,
                   int spawner_limit, int spawner_interval, int spawner_range,
                   int map_id, float x, float y, float z) {
  return {};
}

void EntitySystem::bulk_destroy(const std::vector<Entity>& s) {
  std::lock_guard<std::mutex> lock(access_);
  toDestroy_.insert(toDestroy_.end(), s.begin(), s.end());
}

LuaScript::ScriptLoader& EntitySystem::get_script_loader() noexcept {
  return server_->get_script_loader();
}
<commit_msg>Update entitysystem.cpp<commit_after>#include <set>
#include <vector>

#include "entitysystem.h"
#include "cmapclient.h"
#include "cmapserver.h"
#include "connection.h"
#include "systems/chatsystem.h"
#include "systems/inventorysystem.h"
#include "systems/luasystem.h"
#include "systems/mapsystem.h"
#include "systems/movementsystem.h"
#include "systems/partysystem.h"
#include "systems/updatesystem.h"

using namespace RoseCommon;
EntitySystem::EntitySystem(CMapServer *server) : systemManager_(*this), server_(server) {
  systemManager_.add<Systems::MovementSystem>();
  systemManager_.add<Systems::UpdateSystem>();
  systemManager_.add<Systems::ChatSystem>();
  systemManager_.add<Systems::InventorySystem>();
  systemManager_.add<Systems::PartySystem>();
  systemManager_.add<Systems::MapSystem>();
  systemManager_.add<Systems::LuaSystem>();
}
EntityManager& EntitySystem::getEntityManager() { return entityManager_; }

Entity EntitySystem::buildItemEntity(Entity creator, RoseCommon::Item&& item) {
  Entity e = create();
  e.assign<Item>(std::move(item));
  auto pos = creator.component<Position>();
  e.assign<Position>(pos->x_, pos->y_, pos->map_, 0);
  auto basic = e.assign<BasicInfo>();
  basic->ownerId_ = creator.component<BasicInfo>()->id_;
  basic->id_ = id_manager_.get_free_id();
  itemToEntity_[basic->id_] = e;
  return e;
}

void EntitySystem::registerEntity(Entity entity) {
  if (!entity) return;
  auto basic = entity.component<BasicInfo>();
  if (!basic || basic->name_ == "" || !basic->id_) return;
  nameToEntity_[basic->name_] = entity;
  idToEntity_[basic->id_] = entity;
}

Entity EntitySystem::getItemEntity(uint32_t id) { return itemToEntity_[id]; }

Entity EntitySystem::getEntity(const std::string& name) { return nameToEntity_[name]; }

Entity EntitySystem::getEntity(uint32_t charId) { return idToEntity_[charId]; }

void EntitySystem::update(double dt) {
  std::lock_guard<std::mutex> lock(access_);
  for (auto& it : create_commands_) {
    it->execute(*this);
  }
  create_commands_.clear();
  while (toDispatch_.size()) {
    auto tmp = std::move(toDispatch_.front());
    systemManager_.dispatch(tmp.first, *tmp.second);
    toDispatch_.pop();
  }
  systemManager_.update(dt);
  for (auto& it : delete_commands_) {
    it->execute(*this);
  }
  delete_commands_.clear();
}

void EntitySystem::destroy(Entity entity) {
  if (!entity) return;
  std::unique_ptr<CommandBase> ptr{new Command([entity] (EntitySystem &) {
      if (!entity) return;
      if (auto client = getClient(entity); client)
        CMapServer::SendPacket(client, CMapServer::eSendType::EVERYONE_BUT_ME,
                               *makePacket<ePacketType::PAKWC_REMOVE_OBJECT>(entity));
      else
        CMapServer::SendPacket({}, CMapServer::eSendType::EVERYONE,
                               *makePacket<ePacketType::PAKWC_REMOVE_OBJECT>(entity));
      saveCharacter(entity.component<CharacterInfo>()->charId_, entity);
      auto basic = entity.component<BasicInfo>();
      nameToEntity_.erase(basic->name_);
      idToEntity_.erase(basic->id_);
      id_manager_.release_id(basic->id_);
      it.destroy();
    })};
  std::lock_guard<std::mutex> lock(access_);
  create_commands_.emplace_back(std::move(ptr));
}

Entity EntitySystem::create() { return entityManager_.create(); }

bool EntitySystem::isNearby(Entity a, Entity b) {
  return true;  // FIXME : actually implement the sight calculation instead of the distance
  if (!a || !b) return false;
  auto posa = a.component<Position>();
  auto posb = b.component<Position>();
  if (!posa || !posb) return false;  // FIXME : is it a bug if there is no position?
  if (posa->map_ != posb->map_) return false;
  double dist = (posa->x_ - posb->x_) * (posa->x_ - posb->x_) + (posa->y_ - posb->y_) * (posa->y_ - posb->y_);
  if (dist > NEARBY_DIST) return false;
  return true;
}

bool EntitySystem::dispatch(Entity entity, std::unique_ptr<RoseCommon::CRosePacket> packet) {
  if (!entity) return false;
  if (systemManager_.wouldDispatch(*packet)) {
    std::lock_guard<std::mutex> lock(access_);
    toDispatch_.emplace(std::make_pair(entity, std::move(packet)));
    return true;
  }
  return false;
}

Entity EntitySystem::loadCharacter(uint32_t charId, bool platinium) {
  auto conn = Core::connectionPool.getConnection(Core::osirose);
  Core::CharacterTable characters{};
  Core::InventoryTable inventoryTable{};
  Core::SkillTable skillsTable{};

  auto charRes = conn(sqlpp::select(sqlpp::count(characters.id), sqlpp::all_of(characters))
                          .from(characters)
                          .where(characters.id == charId));

  std::lock_guard<std::mutex> lock(access_);
  auto entity = create();
  if (static_cast<long>(charRes.front().count) != 1L) {
    entity.destroy();
    return Entity();
  }
  const auto& charRow = charRes.front();

  entity.assign<Position>(charRow);
  entity.assign<BasicInfo>(charRow, id_manager_.get_free_id());
  entity.assign<Stats>(charRow);
  entity.assign<AdvancedInfo>(charRow);
  entity.assign<CharacterGraphics>(charRow);
  entity.assign<CharacterInfo>(charRow, platinium, charId);

  // TODO : write the pat initialization code
  auto skills = entity.assign<Skills>();
  auto skillRes =
      conn(sqlpp::select(skillsTable.id, skillsTable.level).from(skillsTable).where(skillsTable.charId == charId));
  skills->loadFromResult(skillRes);

  // TODO : write the hotbar table and loading code
  entity.assign<Hotbar>();
  entity.assign<StatusEffects>();
  entity.assign<RidingItems>();
  entity.assign<BulletItems>();

  // TODO : write the inventory code
  // auto luaSystem = systemManager_.get<Systems::LuaSystem>();
  auto inventory = entity.assign<Inventory>();

  auto invRes =
      conn(sqlpp::select(sqlpp::all_of(inventoryTable)).from(inventoryTable).where(inventoryTable.charId == charId));
  inventory->loadFromResult(invRes, get<Systems::InventorySystem>());

  Systems::UpdateSystem::calculateSpeed(entity);

  entity.assign<Quests>();

  Core::WishTable wish{};
  auto wishRes = conn(sqlpp::select(sqlpp::all_of(wish)).from(wish).where(wish.charId == charId));
  auto wishlist = entity.assign<Wishlist>();
  wishlist->loadFromResult(wishRes, get<Systems::InventorySystem>());

  // auto lua = entity.assign<EntityAPI>();

  // luaSystem->loadScript(entity, "function onInit()\ndisplay('test')\nend");
  // lua->onInit();

  registerEntity(entity);
  return entity;
}

void EntitySystem::saveCharacter(uint32_t charId, Entity entity) {
  if (!entity) return;
  auto conn = Core::connectionPool.getConnection(Core::osirose);
  Core::CharacterTable characters{};

  using sqlpp::parameter;

  auto update = sqlpp::dynamic_update(conn.get(), characters).dynamic_set().where(characters.id == charId);
  entity.component<Position>()->commitToUpdate<decltype(characters)>(update);
  entity.component<BasicInfo>()->commitToUpdate<decltype(characters)>(update);
  entity.component<Stats>()->commitToUpdate<decltype(characters)>(update);
  entity.component<AdvancedInfo>()->commitToUpdate<decltype(characters)>(update);
  // entity.component<CharacterGraphics>()->commitToUpdate(update);
  entity.component<CharacterInfo>()->commitToUpdate<decltype(characters)>(update);
  // entity.component<Hotbar>()->commitToUpdate(update);
  // entity.component<StatusEffects>()->commitToUpdate(update);
  // entity.component<RidingItems>()->commitToUpdate(update);
  // entity.component<BulletItems>()->commitToUpdate(update);

  conn->run(update);

  // entity.component<Skills>()->commitToUpdate(updateSkills);

  Core::InventoryTable inv{};
  auto invRes = conn(sqlpp::select(sqlpp::all_of(inv)).from(inv).where(inv.charId == charId));

  const auto& items = entity.component<Inventory>()->items_;

  std::vector<size_t> toDelete;
  std::vector<size_t> toUpdate;
  std::set<size_t> modified;
  std::vector<size_t> toInsert;

  for (const auto& row : invRes) {
    if (row.slot >= Inventory::maxItems)
      toDelete.emplace_back(row.slot);  // FIXME: that should never happen
    else if (!items[row.slot])
      toDelete.emplace_back(row.slot);
    else if (items[row.slot] != Item(row))
      toUpdate.emplace_back(row.slot);
    modified.insert(row.slot);
  }
  size_t i = 0;
  for (const auto& item : items) {
    if (item && modified.find(i) == modified.end()) toInsert.emplace_back(i);
    ++i;
  }

  for (auto it : toDelete) conn(sqlpp::remove_from(inv).where(inv.charId == charId and inv.slot == it));
  for (auto it : toUpdate) {
    auto update = sqlpp::dynamic_update(conn.get(), inv).dynamic_set().where(inv.charId == charId and inv.slot == it);
    items[it].commitToUpdate<decltype(inv)>(update);
    conn->run(update);
  }
  for (auto it : toInsert) {
    auto insert = sqlpp::dynamic_insert_into(conn.get(), inv).dynamic_set();
    items[it].commitToInsert<decltype(inv)>(insert);
    insert.insert_list.add(inv.slot = it);
    insert.insert_list.add(inv.charId = charId);
    conn->run(insert);
  }
}

Entity EntitySystem::create_warpgate(std::string alias, int dest_map_id, float dest_x, float dest_y, float dest_z,
                    int map_id, float x, float y, float z, float angle,
                    float x_scale, float y_scale, float z_scale) {
  return {};
}

Entity EntitySystem::create_npc(std::string npc_lua, int npc_id, int map_id, float x, float y, float z, float angle) {
    Entity e = create();
    std::unique_ptr<CommandBase> ptr{new Command([npc_lua, npc_id, map_id, x, y, z, angle, e] (EntitySystem &es) mutable {
      if (!e) return;
      e.assign<BasicInfo>(es.id_manager_.get_free_id());
      e.assign<AdvancedInfo>();
      e.assign<CharacterInfo>();

      uint16_t dialog_id = 0;
      if (!npc_lua.empty()) {
        dialog_id = std::stoi(npc_lua);
      }
      e.assign<Npc>(npc_id, dialog_id);
      auto pos = e.assign<Position>(x * 100, y * 100, map_id, 0);

      pos->z_ = static_cast<uint16_t>(z);
      pos->angle_ = angle;
      //e.assign<EntityApi>();
    })};
    create_commands_.emplace_back(std::move(ptr));
    return e;
}

Entity EntitySystem::create_spawner(std::string alias, int mob_id, int mob_count,
                   int spawner_limit, int spawner_interval, int spawner_range,
                   int map_id, float x, float y, float z) {
  return {};
}

void EntitySystem::bulk_destroy(const std::vector<Entity>& s) {
  std::lock_guard<std::mutex> lock(access_);
  toDestroy_.insert(toDestroy_.end(), s.begin(), s.end());
}

LuaScript::ScriptLoader& EntitySystem::get_script_loader() noexcept {
  return server_->get_script_loader();
}

void EntitySystem::SendPacket(const std::shared_ptr<CMapClient>& sender, CMapServer::eSendType type,
                            CRosePacket& _buffer) {
  server_->SendPacket(sender, type, _buffer);
}

void EntitySystem::SendPacket(const CMapClient& sender, CMapServer::eSendType type, CRosePacket& _buffer) {
  server_->SendPacket(sender, type, _buffer);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>
using namespace std;

int main(int _argc, char *_argv[])
{
	if (_argc < 3)
	{
		cerr << "Generator: No n provded" << endl;
		return -1;
	}
	srand(stoi(_argv[1]));
	int n = stoi(string(_argv[2]));
	for (int i = 0; i < n; i++)
	{
		putchar((rand()%('z' - 'a' + 1)) + 'a');
	}
	return rand();
}
<commit_msg>Update generator.cpp<commit_after>#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>
using namespace std;

int main(int _argc, char *_argv[])
{
	if (_argc < 3)
	{
		cerr << "Generator: No n provided" << endl;
		return -1;
	}
	srand(stoi(_argv[1]));
	int n = stoi(string(_argv[2]));
	for (int i = 0; i < n; i++)
	{
		putchar((rand()%('z' - 'a' + 1)) + 'a');
	}
	return rand();
}
<|endoftext|>


<commit_before>#include "numeric/numeric_type.h"
#include "numeric/numeric_op.h"
#include "numeric/wide_op.h"

#include "iroha/test_util.h"

#include <assert.h>
#include <iostream>

using namespace iroha;
using namespace std;

namespace {

class Tool {
public:
  static uint64_t GetValue(const Numeric &n, int idx) {
    ASSERT(n.type_.IsWide());
    return n.GetArray().value_[idx];
  }
};

}  // namespace

void Shift() {
  TEST_CASE("Shift");
  Numeric n;
  n.type_.SetWidth(512);
  Op::Clear(n.type_, n.GetMutableArray());
  n.SetValue0(0xfffffffffffffff0ULL);
  cout << "n=" << n.Format() << "\n";
  ASSERT_EQ(0xfffffffffffffff0UL, n.GetValue0());
  ASSERT_EQ(0, Tool::GetValue(n, 1));

  Numeric m;
  m.type_.SetWidth(512);
  Op::Clear(m.type_, m.GetMutableArray());
  // Left
  cout << "Left Shift\n";
  WideOp::Shift(n.GetArray(), 1, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 1));

  WideOp::Shift(n.GetArray(), 64, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(0, Tool::GetValue(m, 0));
  ASSERT_EQ(Tool::GetValue(n, 0), Tool::GetValue(m, 1));

  WideOp::Shift(n.GetArray(), 65, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 2));

  WideOp::Shift(n.GetArray(), 385, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 7));

  // Right
  cout << "Right Shift\n";
  n = m;
  WideOp::Shift(n.GetArray(), 0, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 7));

  WideOp::Shift(n.GetArray(), 64, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 6));

  WideOp::Shift(n.GetArray(), 65, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(0xfffffffffffffff0ULL, Tool::GetValue(m, 5));
}

void Concat() {
  TEST_CASE("Concat");
  Numeric m, n;
  m.type_.SetWidth(64);
  m.SetValue0(0x5555555555555550ULL);
  n.type_.SetWidth(63);
  n.SetValue0(0x5555555555555550ULL);
  Numeric r;
  Op::Concat(m.GetArray(), m.type_, n.GetArray(), n.type_,
	     r.GetMutableArray(), &r.type_);
  cout << "r=" << r.Format() << "\n";
  ASSERT(r.type_.GetWidth() == 127);
  ASSERT_EQ(0x5555555555555550ULL, Tool::GetValue(r, 0));
  ASSERT_EQ(0x2aaaaaaaaaaaaaa8ULL, Tool::GetValue(r, 1));
}

void Fixup() {
  TEST_CASE("Fixup");
  Numeric n;
  n.type_.SetWidth(68);
  n.SetValue0(0xfffffffffffffff0ULL);
  Numeric m;
  WideOp::Shift(n.GetArray(), 16, true, m.GetMutableArray());
  m.type_ = n.type_;
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(65535, Tool::GetValue(m, 1));

  Op::FixupWidth(m.type_, &m);
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(15, Tool::GetValue(m, 1));
}

void Basic() {
  TEST_CASE("Basic");
  Numeric n;
  n.type_.SetWidth(64);
  n.type_.SetIsSigned(true);
  n.SetValue0(0xfffffffffffffff0ULL);
  cout << "n=" << n.Format() << "\n";
  n.SetValue0(15);
  cout << "n=" << n.Format() << "\n";

  Numeric w;
  w.type_.SetWidth(512);
  Op::Clear(w.type_, w.GetMutableArray());
  cout << "w=" << w.Format() << "\n";
  ASSERT(Op::IsZero(w.type_, w.GetArray()));
}

void ExtraWide() {
  TEST_CASE("ExtraWide");
  Numeric n;
  Numeric::Clear(n.type_, n.GetMutableArray());
  n.SetValue0(2);
  n.type_.SetWidth(1024);
  Numeric::MayExpandStorage(nullptr, &n);
  ASSERT(n.GetValue0() == 2);

  Numeric nn;
  nn.type_.SetWidth(768);
  Numeric::MayPopulateStorage(nn.type_, nullptr, nn.GetMutableArray());

  Op::SelectBits(n.GetArray(), n.type_,
		 768, 1, nn.GetMutableArray(), nullptr);
  ASSERT(nn.GetValue0() == 1);
}

int main(int argc, char **argv) {
  cout << "sizeof(width)=" << sizeof(NumericWidth) << "\n";
  cout << "sizeof(numeric)=" << sizeof(Numeric) << "\n";

  Basic();
  Shift();
  Concat();
  Fixup();
  ExtraWide();

  return 0;
}
<commit_msg>Fix valgrid complaints in numeric_test.<commit_after>#include "numeric/numeric_type.h"
#include "numeric/numeric_op.h"
#include "numeric/wide_op.h"

#include "iroha/test_util.h"

#include <assert.h>
#include <iostream>

using namespace iroha;
using namespace std;

namespace {

class Tool {
public:
  static uint64_t GetValue(const Numeric &n, int idx) {
    ASSERT(n.type_.IsWide());
    return n.GetArray().value_[idx];
  }
};

}  // namespace

void Shift() {
  TEST_CASE("Shift");
  Numeric n;
  n.type_.SetWidth(512);
  Op::Clear(n.type_, n.GetMutableArray());
  n.SetValue0(0xfffffffffffffff0ULL);
  cout << "n=" << n.Format() << "\n";
  ASSERT_EQ(0xfffffffffffffff0UL, n.GetValue0());
  ASSERT_EQ(0, Tool::GetValue(n, 1));

  Numeric m;
  m.type_.SetWidth(512);
  Op::Clear(m.type_, m.GetMutableArray());
  // Left
  cout << "Left Shift\n";
  WideOp::Shift(n.GetArray(), 1, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 1));

  WideOp::Shift(n.GetArray(), 64, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(0, Tool::GetValue(m, 0));
  ASSERT_EQ(Tool::GetValue(n, 0), Tool::GetValue(m, 1));

  WideOp::Shift(n.GetArray(), 65, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 2));

  WideOp::Shift(n.GetArray(), 385, true, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 7));

  // Right
  cout << "Right Shift\n";
  n = m;
  WideOp::Shift(n.GetArray(), 0, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 7));

  WideOp::Shift(n.GetArray(), 64, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(1, Tool::GetValue(m, 6));

  WideOp::Shift(n.GetArray(), 65, false, m.GetMutableArray());
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(0xfffffffffffffff0ULL, Tool::GetValue(m, 5));
}

void Concat() {
  TEST_CASE("Concat");
  Numeric m, n;
  Numeric::Clear(m.type_, m.GetMutableArray());
  m.type_.SetWidth(64);
  m.SetValue0(0x5555555555555550ULL);
  Numeric::Clear(n.type_, n.GetMutableArray());
  n.type_.SetWidth(63);
  n.SetValue0(0x5555555555555550ULL);
  Numeric r;
  Op::Concat(m.GetArray(), m.type_, n.GetArray(), n.type_,
	     r.GetMutableArray(), &r.type_);
  cout << "r=" << r.Format() << "\n";
  ASSERT(r.type_.GetWidth() == 127);
  ASSERT_EQ(0x5555555555555550ULL, Tool::GetValue(r, 0));
  ASSERT_EQ(0x2aaaaaaaaaaaaaa8ULL, Tool::GetValue(r, 1));
}

void Fixup() {
  TEST_CASE("Fixup");
  Numeric n;
  Numeric::Clear(n.type_, n.GetMutableArray());
  n.type_.SetWidth(68);
  n.SetValue0(0xfffffffffffffff0ULL);
  Numeric m;
  WideOp::Shift(n.GetArray(), 16, true, m.GetMutableArray());
  m.type_ = n.type_;
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(65535, Tool::GetValue(m, 1));

  Op::FixupWidth(m.type_, &m);
  cout << "m=" << m.Format() << "\n";
  ASSERT_EQ(15, Tool::GetValue(m, 1));
}

void Basic() {
  TEST_CASE("Basic");
  Numeric n;
  n.type_.SetWidth(64);
  n.type_.SetIsSigned(true);
  n.SetValue0(0xfffffffffffffff0ULL);
  cout << "n=" << n.Format() << "\n";
  n.SetValue0(15);
  cout << "n=" << n.Format() << "\n";

  Numeric w;
  w.type_.SetWidth(512);
  Op::Clear(w.type_, w.GetMutableArray());
  cout << "w=" << w.Format() << "\n";
  ASSERT(Op::IsZero(w.type_, w.GetArray()));
}

void ExtraWide() {
  TEST_CASE("ExtraWide");
  Numeric n;
  Numeric::Clear(n.type_, n.GetMutableArray());
  n.SetValue0(2);
  n.type_.SetWidth(1024);
  Numeric::MayExpandStorage(nullptr, &n);
  ASSERT(n.GetValue0() == 2);

  Numeric nn;
  nn.type_.SetWidth(768);
  Numeric::MayPopulateStorage(nn.type_, nullptr, nn.GetMutableArray());

  Op::SelectBits(n.GetArray(), n.type_,
		 768, 1, nn.GetMutableArray(), nullptr);
  ASSERT(nn.GetValue0() == 1);
}

int main(int argc, char **argv) {
  cout << "sizeof(width)=" << sizeof(NumericWidth) << "\n";
  cout << "sizeof(numeric)=" << sizeof(Numeric) << "\n";

  Basic();
  Shift();
  Concat();
  Fixup();
  ExtraWide();

  return 0;
}
<|endoftext|>


<commit_before>/*
	This file is part of the E_Rendering library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "E_MeshBuilder.h"

#include "../Mesh/E_Mesh.h"
#include "../Mesh/E_VertexDescription.h"
#include "../Texture/E_Texture.h"

#include <E_Geometry/E_Vec2.h>
#include <E_Geometry/E_Vec3.h>
#include <E_Geometry/E_Matrix4x4.h>
#include <E_Geometry/E_SRT.h>
#include <E_Geometry/E_Sphere.h>
#include <E_Geometry/E_Box.h>
#include <E_Util/Graphics/E_Color.h>
#include <E_Util/Graphics/E_Bitmap.h>
#include <E_Util/Graphics/E_PixelAccessor.h>
#include <Rendering/Mesh/VertexAttributeIds.h>
#include <Rendering/MeshUtils/MeshUtils.h>

#include <EScript/Basics.h>
#include <EScript/StdObjects.h>

#include <cmath>

using namespace Rendering;
using namespace Rendering::MeshUtils;

namespace E_Rendering {

//! (static)
EScript::Type * E_MeshBuilder::getTypeObject() {
	// E_MeshBuilder ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! initMembers
void E_MeshBuilder::init(EScript::Namespace & lib) {
	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	// (static)
	//! @name Deprecated
	//! @{

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createArrow(Number radius, Number length)
	//! @deprecated use Rendering.createArrow(...) instead.
	ES_FUN(typeObject,"createArrow", 2, 2, (MeshBuilder::createArrow(parameter[0].toFloat(), parameter[1].toFloat())))

	//! [ESF] (static) Mesh Rendering.MeshBuilder.createCone(Number radius, Number height, Number segments)
	//! @deprecated use Rendering.createCone(...) instead.
	ES_FUN(typeObject,"createCone", 3, 3, (MeshBuilder::createCone(parameter[0].toFloat(), parameter[1].toFloat(), parameter[2].to<uint32_t>(rt))))

	//! [ESF] (static) Mesh Rendering.MeshBuilder.createConicalFrustum(Number radiusBottom, Number radiusTop, Number height, Number segments)
	//! @deprecated use Rendering.createConicalFrustum(...) instead.
	ES_FUN(typeObject,"createConicalFrustum", 4, 4, (MeshBuilder::createConicalFrustum(parameter[0].toFloat(), parameter[1].toFloat(), parameter[2].toFloat(), parameter[3].to<uint32_t>(rt))))

	//! [ESF] (static) Mesh Rendering.MeshBuilder.createDiscSector(Number radius, Number segments, Number angle)
	//! @deprecated use Rendering.createDiscSector(...) instead.
	ES_FUNCTION(typeObject,"createDiscSector",2,3,{
		if (parameter.count() == 2) {
			return EScript::create(MeshBuilder::createDiscSector(parameter[0].toFloat(), parameter[1].to<uint32_t>(rt)));
		} else {
			return EScript::create(MeshBuilder::createDiscSector(parameter[0].toFloat(), parameter[1].to<uint32_t>(rt), parameter[2].toFloat()));
		}
	})

	/*! [ESF] (static) Mesh Rendering.MeshBuilder.createDome(radius=100,
								int horiRes = 40, int vertRes = 40,
								double halfSphereFraction = 1.0,
								double imagePercentage = 1.0)
								 @deprecated use Rendering.createDome(...) instead. */
	ES_FUN(typeObject,"createDome",0,5,(MeshBuilder::createDome(
				parameter[0].toFloat(100.0),
				parameter[1].toInt(40),
				parameter[2].toInt(40),
				parameter[3].toFloat(1.0),
				parameter[4].toFloat(1.0))))

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createRectangle([VertexDescription],width,height)
	//! @deprecated use Rendering.createRectangle(...) instead.
	ES_FUNCTION(typeObject, "createRectangle", 2, 3, {
		if (parameter.count() == 3) {
			return EScript::create(MeshBuilder::createRectangle(parameter[0].to<const VertexDescription&>(rt),parameter[1].toFloat(), parameter[2].toFloat()));
		} else {
			Rendering::VertexDescription vertexDescription;
			vertexDescription.appendPosition3D();
			vertexDescription.appendNormalFloat();
			vertexDescription.appendColorRGBFloat();
			vertexDescription.appendTexCoord();
			return EScript::create(MeshBuilder::createRectangle(vertexDescription,parameter[0].toFloat(), parameter[1].toFloat()));
		}
	})

	//! [ESF] (static) Mesh Rendering.MeshBuilder.createRingSector(Number innerRadius, Number outerRadius, Number segments, Number angle)
	//! @deprecated use Rendering.createRingSector(...) instead.
	ES_FUNCTION(typeObject,"createRingSector",3,4,{
		if (parameter.count() == 3) {
			return EScript::create(MeshBuilder::createRingSector(parameter[0].toFloat(), parameter[1].toFloat(), parameter[2].to<uint32_t>(rt)));
		} else {
			return EScript::create(MeshBuilder::createRingSector(parameter[0].toFloat(), parameter[1].toFloat(), parameter[2].to<uint32_t>(rt), parameter[3].toFloat()));
		}
	})

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createSphere(Number, Number)
	//! @deprecated use Rendering.(...) instead.
	ES_FUNCTION(typeObject, "createSphere", 2, 2, {
		Rendering::VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		vertexDescription.appendNormalFloat();
		vertexDescription.appendColorRGBFloat();
		vertexDescription.appendTexCoord();
		return EScript::create(MeshBuilder::createSphere(vertexDescription, parameter[0].to<uint32_t>(rt), parameter[1].to<uint32_t>(rt)));
	})

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createBox(Box)
	//! @deprecated use Rendering.(...) instead.
	ES_FUNCTION(typeObject, "createBox", 1, 1, {
		Rendering::VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		vertexDescription.appendNormalFloat();
		vertexDescription.appendColorRGBFloat();
		vertexDescription.appendTexCoord();
		return EScript::create(MeshBuilder::createBox(vertexDescription, parameter[0].to<Geometry::Box>(rt)));
	})

	// EXPERIMENTAL!!!!!!!!!!!!!!
	//!	[ESMF] new Rendering.MeshBuilder.createMeshFromBitmaps(Util.Bitmap depth[, Util.Bitmap color[, Util.Bitmap normals]])
	//! @deprecated use Rendering.createMeshFromBitmaps(...) instead.
	ES_FUNCTION(typeObject,"createMeshFromBitmaps",1,3,{
		Util::Reference<Util::Bitmap> depth = parameter[0].to<Util::Reference<Util::Bitmap>>(rt);
		Util::Reference<Util::Bitmap> color;
		Util::Reference<Util::Bitmap> normal;

		Rendering::VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		if(parameter.count()>1){
			color = parameter[1].to<Util::Reference<Util::Bitmap>>(rt);
			vertexDescription.appendColorRGBAByte();
		}
		if(parameter.count()>2){
			normal = parameter[2].to<Util::Reference<Util::Bitmap>>(rt);
			vertexDescription.appendNormalByte();
		}
		Mesh * m=MeshBuilder::createMeshFromBitmaps(vertexDescription,
													std::move(depth),
													std::move(color),
													std::move(normal));
		if(m)
			return EScript::create(m);
		else return nullptr;
	})

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createHexGrid(VertexDescription, Number width, Number height, Number rows, Number columns)
	//! @deprecated use Rendering.createHexGrid(...) instead.
	ES_FUN(typeObject,"createHexGrid", 5, 5,(
		MeshBuilder::createHexGrid(parameter[0].to<const VertexDescription&>(rt), parameter[1].toFloat(), parameter[2].toFloat(), parameter[3].toUInt(), parameter[4].toUInt())
	))
	// ----

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createVoxelMesh(VertexDescription, Util.PixelAccessor voxelBitmap, Number depth)
	//! @deprecated use Rendering.createVoxelMesh(...) instead.
	ES_FUN(typeObject,"createVoxelMesh", 3, 3,(
		MeshBuilder::createVoxelMesh(parameter[0].to<const VertexDescription&>(rt), parameter[1].to<Util::PixelAccessor&>(rt), parameter[2].toUInt())
	))
	// ----

	//!	[ESF] (static) Mesh Rendering.MeshBuilder.createTorus(Number, Number, Number, Number)
	//! @deprecated use Rendering.createTorus(...) instead.
	ES_FUNCTION(typeObject, "createTorus", 4, 4, {
		Rendering::VertexDescription vertexDescription;
		vertexDescription.appendPosition3D();
		vertexDescription.appendNormalFloat();
		vertexDescription.appendColorRGBFloat();
		vertexDescription.appendTexCoord();
		return EScript::create(MeshBuilder::createTorus(vertexDescription, parameter[0].toFloat(), parameter[1].toFloat(), parameter[2].toUInt(), parameter[3].toUInt()));
	})
	//! @}

	// --------------------------------------------------

	//!	[ESMF] new Rendering.MeshBuilder( [VertexDescription] )
	ES_CONSTRUCTOR(typeObject,0,1, {
		if(parameter.count()==0)
			return EScript::create(new MeshBuilder);
		else
			return EScript::create(new MeshBuilder(parameter[0].to<const VertexDescription&>(rt)));
	})

	//!	[ESMF] thisEObj MeshBuilder.addIndex( idx )
	ES_MFUN(typeObject,MeshBuilder,"addIndex",1,1,
				(thisObj->addIndex( parameter[0].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addQuad( idx,idx,idx,idx )
	ES_MFUN(typeObject,MeshBuilder,"addQuad",4,4,
				(thisObj->addQuad( parameter[0].to<uint32_t>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt),parameter[3].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addSphere( Sphere,inclinationSegments,azimuthSegments )
	//ES_MFUN(typeObject,MeshBuilder,"addSphere",3,3,
	//			(MeshBuilder::addSphere(*thisObj,parameter[0].to<Geometry::Sphere_f>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addBox( Box )
	//ES_MFUN(typeObject,MeshBuilder,"addBox",1,1,
	//			(MeshBuilder::addBox(*thisObj,parameter[0].to<Geometry::Box>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addTriangle( idx,idx,idx )
	ES_MFUN(typeObject,MeshBuilder,"addTriangle",3,3,
				(thisObj->addTriangle( parameter[0].to<uint32_t>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] Number MeshBuilder.addVertex( [Vec3f pos ,Vec3 normal, float r, g, b, a, float u, v )
	ES_MFUNCTION(typeObject,MeshBuilder,"addVertex",0,8,{
		uint32_t index=0;
		if(parameter.count() == 8) {
			index=thisObj->addVertex(
					parameter[0].to<Geometry::Vec3>(rt), // pos
					parameter[1].to<Geometry::Vec3>(rt), // normal
					parameter[2].toFloat(),	parameter[3].toFloat(),	parameter[4].toFloat(), parameter[5].toFloat(),	 // color
					parameter[6].toFloat(),	parameter[7].toFloat()); // tex0
		}
		else {
			assertParamCount(rt,parameter.count(),0,0);
			index=thisObj->addVertex();
		}
		return index;
	})

	//!	[ESMF] thisEObj MeshBuilder.addMesh( Mesh )
	ES_MFUN(typeObject,MeshBuilder,"addMesh",1,1,
				(thisObj->addMesh(parameter[0].to<Rendering::Mesh*>(rt)),thisEObj))

	//!	[ESMF] E_Mesh MeshBuilder.buildMesh()
	ES_MFUN(typeObject,MeshBuilder, "buildMesh", 0, 0, thisObj->buildMesh())

	//! int MeshBuilder.getNextIndex()
	ES_MFUN(typeObject,MeshBuilder,"getNextIndex",0,0,thisObj->getNextIndex())

	//! Matrix4x4 MeshBuilder.getTransformation()
	ES_MFUN(typeObject,MeshBuilder,"getTransformation",0,0,thisObj->getTransformation())

	//! bool MeshBuilder.isEmpty()
	ES_MFUN(typeObject,MeshBuilder,"isEmpty",0,0,thisObj->isEmpty())

	//!	[ESMF] thisEObj MeshBuilder.position( Vec3, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"position",1,2,
				( thisObj->position( parameter[0].to<Geometry::Vec3>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.position2D(Vec2, [String attribute])
	ES_MFUN(typeObject,MeshBuilder, "position2D", 1, 2,
				 (thisObj->position(parameter[0].to<Geometry::Vec2>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

 	//!	[ESMF] thisEObj MeshBuilder.position4D(Vec4, [String attribute])
 	ES_MFUN(typeObject,MeshBuilder, "position4D", 1, 2,
 				 (thisObj->position(parameter[0].to<Geometry::Vec4>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

 	//!	[ESMF] thisEObj MeshBuilder.normal( Vec3, [String attribute] )
 	ES_MFUN(typeObject,MeshBuilder,"normal",1,2,
 				( thisObj->normal( parameter[0].to<Geometry::Vec3>(rt), parameter[1].toString(VertexAttributeIds::NORMAL.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.color( Color4f | Color4ub, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"color",1,2,
				( thisObj->color(parameter[0].to<Util::Color4f>(rt), parameter[1].toString(VertexAttributeIds::COLOR.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.texCoord0( Vec2, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"texCoord0",1,2,
				( thisObj->texCoord0( parameter[0].to<Geometry::Vec2>(rt), parameter[1].toString(VertexAttributeIds::TEXCOORD0.toString())),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.value(Number value, String attribute)
	ES_MFUN(typeObject,MeshBuilder,"value",2,2,(thisObj->value(parameter[0].toFloat(), parameter[1].toString()),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.values(Array values, String attribute)
	ES_MFUNCTION(typeObject,MeshBuilder,"values",2,2,{
		EScript::Array * a=parameter[0].to<EScript::Array*>(rt);
		std::vector<float> values;
		for(auto v : *a)
			values.push_back(v.toFloat());
		thisObj->values(values, parameter[1].toString());
		return thisEObj;
	})

	//! [ESMF] thisEObj MeshBuilder.valueUInt(Number value, String attribute)
	ES_MFUN(typeObject,MeshBuilder,"valueUInt",2,2,(thisObj->value(parameter[0].toUInt(), parameter[1].toString()),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.valuesUInt(Array values, String attribute)
	ES_MFUNCTION(typeObject,MeshBuilder,"valuesUInt",2,2,{
		EScript::Array * a=parameter[0].to<EScript::Array*>(rt);
		std::vector<uint32_t> values;
		for(auto v : *a)
			values.push_back(v.toUInt());
		thisObj->values(values, parameter[1].toString());
		return thisEObj;
	})

	//!	[ESMF] thisEObj MeshBuilder.setTransformation( Matrix4x4 | SRT )
	ES_MFUNCTION(typeObject,MeshBuilder,"setTransformation",1,1,{
		E_Geometry::E_Matrix4x4 * em = parameter[0].toType<E_Geometry::E_Matrix4x4>();
		if(em){
			thisObj->setTransformation(em->ref());
		}else{
			thisObj->setTransformation(parameter[0].to<const Geometry::SRT&>(rt));
		}
		return thisEObj;
	})

}

}
<commit_msg>removed bindings for deprecated functions<commit_after>/*
	This file is part of the E_Rendering library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "E_MeshBuilder.h"

#include "../Mesh/E_Mesh.h"
#include "../Mesh/E_VertexDescription.h"
#include "../Texture/E_Texture.h"

#include <E_Geometry/E_Vec2.h>
#include <E_Geometry/E_Vec3.h>
#include <E_Geometry/E_Matrix4x4.h>
#include <E_Geometry/E_SRT.h>
#include <E_Geometry/E_Sphere.h>
#include <E_Geometry/E_Box.h>
#include <E_Util/Graphics/E_Color.h>
#include <E_Util/Graphics/E_Bitmap.h>
#include <E_Util/Graphics/E_PixelAccessor.h>
#include <Rendering/Mesh/VertexAttributeIds.h>
#include <Rendering/MeshUtils/MeshUtils.h>

#include <EScript/Basics.h>
#include <EScript/StdObjects.h>

#include <cmath>

using namespace Rendering;
using namespace Rendering::MeshUtils;

namespace E_Rendering {

//! (static)
EScript::Type * E_MeshBuilder::getTypeObject() {
	// E_MeshBuilder ---|> Object
	static EScript::ERef<EScript::Type> typeObject = new EScript::Type(EScript::Object::getTypeObject());
	return typeObject.get();
}

//! initMembers
void E_MeshBuilder::init(EScript::Namespace & lib) {
	EScript::Type * typeObject = getTypeObject();
	declareConstant(&lib,getClassName(),typeObject);

	//!	[ESMF] new Rendering.MeshBuilder( [VertexDescription] )
	ES_CONSTRUCTOR(typeObject,0,1, {
		if(parameter.count()==0)
			return EScript::create(new MeshBuilder);
		else
			return EScript::create(new MeshBuilder(parameter[0].to<const VertexDescription&>(rt)));
	})

	//!	[ESMF] thisEObj MeshBuilder.addIndex( idx )
	ES_MFUN(typeObject,MeshBuilder,"addIndex",1,1,
				(thisObj->addIndex( parameter[0].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addQuad( idx,idx,idx,idx )
	ES_MFUN(typeObject,MeshBuilder,"addQuad",4,4,
				(thisObj->addQuad( parameter[0].to<uint32_t>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt),parameter[3].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addSphere( Sphere,inclinationSegments,azimuthSegments )
	//ES_MFUN(typeObject,MeshBuilder,"addSphere",3,3,
	//			(MeshBuilder::addSphere(*thisObj,parameter[0].to<Geometry::Sphere_f>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addBox( Box )
	//ES_MFUN(typeObject,MeshBuilder,"addBox",1,1,
	//			(MeshBuilder::addBox(*thisObj,parameter[0].to<Geometry::Box>(rt)),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.addTriangle( idx,idx,idx )
	ES_MFUN(typeObject,MeshBuilder,"addTriangle",3,3,
				(thisObj->addTriangle( parameter[0].to<uint32_t>(rt),parameter[1].to<uint32_t>(rt),parameter[2].to<uint32_t>(rt)),thisEObj))

	//!	[ESMF] Number MeshBuilder.addVertex()
	ES_MFUN(typeObject,MeshBuilder,"addVertex",0,0, thisObj->addVertex())

	//!	[ESMF] thisEObj MeshBuilder.addMesh( Mesh )
	ES_MFUN(typeObject,MeshBuilder,"addMesh",1,1,
				(thisObj->addMesh(parameter[0].to<Rendering::Mesh*>(rt)),thisEObj))

	//!	[ESMF] E_Mesh MeshBuilder.buildMesh()
	ES_MFUN(typeObject,MeshBuilder, "buildMesh", 0, 0, thisObj->buildMesh())

	//! int MeshBuilder.getNextIndex()
	ES_MFUN(typeObject,MeshBuilder,"getNextIndex",0,0,thisObj->getNextIndex())

	//! Matrix4x4 MeshBuilder.getTransformation()
	ES_MFUN(typeObject,MeshBuilder,"getTransformation",0,0,thisObj->getTransformation())

	//! bool MeshBuilder.isEmpty()
	ES_MFUN(typeObject,MeshBuilder,"isEmpty",0,0,thisObj->isEmpty())

	//!	[ESMF] thisEObj MeshBuilder.position( Vec3, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"position",1,2,
				( thisObj->position( parameter[0].to<Geometry::Vec3>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.position2D(Vec2, [String attribute])
	ES_MFUN(typeObject,MeshBuilder, "position2D", 1, 2,
				 (thisObj->position(parameter[0].to<Geometry::Vec2>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

 	//!	[ESMF] thisEObj MeshBuilder.position4D(Vec4, [String attribute])
 	ES_MFUN(typeObject,MeshBuilder, "position4D", 1, 2,
 				 (thisObj->position(parameter[0].to<Geometry::Vec4>(rt), parameter[1].toString(VertexAttributeIds::POSITION.toString())),thisEObj))

 	//!	[ESMF] thisEObj MeshBuilder.normal( Vec3, [String attribute] )
 	ES_MFUN(typeObject,MeshBuilder,"normal",1,2,
 				( thisObj->normal( parameter[0].to<Geometry::Vec3>(rt), parameter[1].toString(VertexAttributeIds::NORMAL.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.color( Color4f | Color4ub, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"color",1,2,
				( thisObj->color(parameter[0].to<Util::Color4f>(rt), parameter[1].toString(VertexAttributeIds::COLOR.toString())),thisEObj))

	//!	[ESMF] thisEObj MeshBuilder.texCoord0( Vec2, [String attribute] )
	ES_MFUN(typeObject,MeshBuilder,"texCoord0",1,2,
				( thisObj->texCoord0( parameter[0].to<Geometry::Vec2>(rt), parameter[1].toString(VertexAttributeIds::TEXCOORD0.toString())),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.value(Number value, String attribute)
	ES_MFUN(typeObject,MeshBuilder,"value",2,2,(thisObj->value(parameter[0].toFloat(), parameter[1].toString()),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.values(Array values, String attribute)
	ES_MFUNCTION(typeObject,MeshBuilder,"values",2,2,{
		EScript::Array * a=parameter[0].to<EScript::Array*>(rt);
		std::vector<float> values;
		for(auto v : *a)
			values.push_back(v.toFloat());
		thisObj->values(values, parameter[1].toString());
		return thisEObj;
	})

	//! [ESMF] thisEObj MeshBuilder.valueUInt(Number value, String attribute)
	ES_MFUN(typeObject,MeshBuilder,"valueUInt",2,2,(thisObj->value(parameter[0].toUInt(), parameter[1].toString()),thisEObj))

	//! [ESMF] thisEObj MeshBuilder.valuesUInt(Array values, String attribute)
	ES_MFUNCTION(typeObject,MeshBuilder,"valuesUInt",2,2,{
		EScript::Array * a=parameter[0].to<EScript::Array*>(rt);
		std::vector<uint32_t> values;
		for(auto v : *a)
			values.push_back(v.toUInt());
		thisObj->values(values, parameter[1].toString());
		return thisEObj;
	})

	//!	[ESMF] thisEObj MeshBuilder.setTransformation( Matrix4x4 | SRT )
	ES_MFUNCTION(typeObject,MeshBuilder,"setTransformation",1,1,{
		E_Geometry::E_Matrix4x4 * em = parameter[0].toType<E_Geometry::E_Matrix4x4>();
		if(em){
			thisObj->setTransformation(em->ref());
		}else{
			thisObj->setTransformation(parameter[0].to<const Geometry::SRT&>(rt));
		}
		return thisEObj;
	})

}

}
<|endoftext|>


<commit_before><commit_msg>Align doxygen asterisks.<commit_after><|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2018

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

#ifndef ROOT_RFILTER
#define ROOT_RFILTER

#include "ROOT/RDF/ColumnReaderUtils.hxx"
#include "ROOT/RDF/RColumnReaderBase.hxx"
#include "ROOT/RDF/RCutFlowReport.hxx"
#include "ROOT/RDF/Utils.hxx"
#include "ROOT/RDF/RFilterBase.hxx"
#include "ROOT/RDF/RLoopManager.hxx"
#include "ROOT/TypeTraits.hxx"
#include "RtypesCore.h"

#include <algorithm>
#include <cassert>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility> // std::index_sequence
#include <vector>

namespace ROOT {

namespace Internal {
namespace RDF {
using namespace ROOT::Detail::RDF;

// fwd decl for RFilter
namespace GraphDrawing {
std::shared_ptr<GraphNode>
CreateFilterNode(const RFilterBase *filterPtr, std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);

std::shared_ptr<GraphNode> AddDefinesToGraph(std::shared_ptr<GraphNode> node,
                                             const RDFInternal::RColumnRegister &colRegister,
                                             const std::vector<std::string> &prevNodeDefines,
                                             std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
} // ns GraphDrawing

} // ns RDF
} // ns Internal

namespace Detail {
namespace RDF {
using namespace ROOT::TypeTraits;
namespace RDFGraphDrawing = ROOT::Internal::RDF::GraphDrawing;

template <typename FilterF, typename PrevNode>
class R__CLING_PTRCHECK(off) RFilter final : public RFilterBase {
   using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
   using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;

   FilterF fFilter;
   /// Column readers per slot and per input column
   std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>> fValues;
   const std::shared_ptr<PrevNode> fPrevNodePtr;
   PrevNode &fPrevNode;

   std::unordered_map<std::string, std::shared_ptr<RFilterBase>> fVariedFilters;

public:
   RFilter(FilterF f, const ROOT::RDF::ColumnNames_t &columns, std::shared_ptr<PrevNode> pd,
           const RDFInternal::RColumnRegister &colRegister, std::string_view name = "",
           const std::string &variationName = "nominal")
      : RFilterBase(pd->GetLoopManagerUnchecked(), name, pd->GetLoopManagerUnchecked()->GetNSlots(), colRegister,
                    columns, pd->GetVariations(), variationName),
        fFilter(std::move(f)), fValues(pd->GetLoopManagerUnchecked()->GetNSlots()), fPrevNodePtr(std::move(pd)),
        fPrevNode(*fPrevNodePtr)
   {
   }

   RFilter(const RFilter &) = delete;
   RFilter &operator=(const RFilter &) = delete;
   ~RFilter() {
      // must Deregister objects from the RLoopManager here, before the fPrevNode data member is destroyed:
      // otherwise if fPrevNode is the RLoopManager, it will be destroyed before the calls to Deregister happen.
      fColRegister.Clear(); // triggers RDefine deregistration
      fLoopManager->Deregister(this);
   }

   bool CheckFilters(unsigned int slot, Long64_t entry) final
   {
      if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
         if (!fPrevNode.CheckFilters(slot, entry)) {
            // a filter upstream returned false, cache the result
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = false;
         } else {
            // evaluate this filter, cache the result
            auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
            passed ? ++fAccepted[slot * RDFInternal::CacheLineStep<ULong64_t>()]
                   : ++fRejected[slot * RDFInternal::CacheLineStep<ULong64_t>()];
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = passed;
         }
         fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
      }
      return fLastResult[slot * RDFInternal::CacheLineStep<int>()];
   }

   template <typename... ColTypes, std::size_t... S>
   bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
   {
      // silence "unused parameter" warnings in gcc
      (void)slot;
      (void)entry;
      return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
   }

   void InitSlot(TTreeReader *r, unsigned int slot) final
   {
      RDFInternal::RColumnReadersInfo info{fColumnNames, fColRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
                                           fLoopManager->GetDataSource()};
      fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation);
      fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
   }

   // recursive chain of `Report`s
   void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }

   void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
   {
      fPrevNode.PartialReport(rep);
      FillReport(rep);
   }

   void StopProcessing() final
   {
      ++fNStopsReceived;
      if (fNStopsReceived == fNChildren)
         fPrevNode.StopProcessing();
   }

   void IncrChildrenCount() final
   {
      ++fNChildren;
      // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
      if (fNChildren == 1 && fName.empty())
         fPrevNode.IncrChildrenCount();
   }

   void TriggerChildrenCount() final
   {
      assert(!fName.empty()); // this method is to only be called on named filters
      fPrevNode.IncrChildrenCount();
   }

   void AddFilterName(std::vector<std::string> &filters)
   {
      fPrevNode.AddFilterName(filters);
      auto name = (HasName() ? fName : "Unnamed Filter");
      filters.push_back(name);
   }

   /// Clean-up operations to be performed at the end of a task.
   void FinalizeSlot(unsigned int slot) final
   {
      for (auto &v : fValues[slot])
         v.reset();
   }

   std::shared_ptr<RDFGraphDrawing::GraphNode>
   GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap)
   {
      // Recursively call for the previous node.
      auto prevNode = fPrevNode.GetGraph(visitedMap);
      auto prevColumns = prevNode->GetDefinedColumns();

      auto thisNode = RDFGraphDrawing::CreateFilterNode(this, visitedMap);

      /* If the returned node is not new, there is no need to perform any other operation.
       * This is a likely scenario when building the entire graph in which branches share
       * some nodes. */
      if (!thisNode->GetIsNew()) {
         return thisNode;
      }

      auto upmostNode = AddDefinesToGraph(thisNode, fColRegister, prevColumns, visitedMap);

      // Keep track of the columns defined up to this point.
      thisNode->AddDefinedColumns(fColRegister.GetNames());

      upmostNode->SetPrevNode(prevNode);
      return thisNode;
   }

   /// Return a clone of this Filter that works with values in the variationName "universe".
   std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
   {
      auto it = fVariedFilters.find(variationName);
      if (it != fVariedFilters.end())
         return it->second;

      auto prevNode = fPrevNodePtr;
      if ((void *)fPrevNodePtr.get() != (void *)fLoopManager && variationName != "nominal")
         prevNode = std::static_pointer_cast<PrevNode>(prevNode->GetVariedFilter(variationName));

      // the varied filters get a copy of the callable object.
      // TODO document this
      auto variedFilter = std::unique_ptr<RFilterBase>(
         new RFilter(fFilter, fColumnNames, std::move(prevNode), fColRegister, fName, variationName));
      fLoopManager->Book(variedFilter.get());
      auto e = fVariedFilters.insert({variationName, std::move(variedFilter)});
      return e.first->second;
   }
};

} // ns RDF
} // ns Detail
} // ns ROOT

#endif // ROOT_RFILTER
<commit_msg>[DF] Simplify GetVariedFilter<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2018

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

#ifndef ROOT_RFILTER
#define ROOT_RFILTER

#include "ROOT/RDF/ColumnReaderUtils.hxx"
#include "ROOT/RDF/RColumnReaderBase.hxx"
#include "ROOT/RDF/RCutFlowReport.hxx"
#include "ROOT/RDF/Utils.hxx"
#include "ROOT/RDF/RFilterBase.hxx"
#include "ROOT/RDF/RLoopManager.hxx"
#include "ROOT/TypeTraits.hxx"
#include "RtypesCore.h"

#include <algorithm>
#include <cassert>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility> // std::index_sequence
#include <vector>

namespace ROOT {

namespace Internal {
namespace RDF {
using namespace ROOT::Detail::RDF;

// fwd decl for RFilter
namespace GraphDrawing {
std::shared_ptr<GraphNode>
CreateFilterNode(const RFilterBase *filterPtr, std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);

std::shared_ptr<GraphNode> AddDefinesToGraph(std::shared_ptr<GraphNode> node,
                                             const RDFInternal::RColumnRegister &colRegister,
                                             const std::vector<std::string> &prevNodeDefines,
                                             std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
} // ns GraphDrawing

} // ns RDF
} // ns Internal

namespace Detail {
namespace RDF {
using namespace ROOT::TypeTraits;
namespace RDFGraphDrawing = ROOT::Internal::RDF::GraphDrawing;

template <typename FilterF, typename PrevNode>
class R__CLING_PTRCHECK(off) RFilter final : public RFilterBase {
   using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
   using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;

   FilterF fFilter;
   /// Column readers per slot and per input column
   std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>> fValues;
   const std::shared_ptr<PrevNode> fPrevNodePtr;
   PrevNode &fPrevNode;

   std::unordered_map<std::string, std::shared_ptr<RFilterBase>> fVariedFilters;

public:
   RFilter(FilterF f, const ROOT::RDF::ColumnNames_t &columns, std::shared_ptr<PrevNode> pd,
           const RDFInternal::RColumnRegister &colRegister, std::string_view name = "",
           const std::string &variationName = "nominal")
      : RFilterBase(pd->GetLoopManagerUnchecked(), name, pd->GetLoopManagerUnchecked()->GetNSlots(), colRegister,
                    columns, pd->GetVariations(), variationName),
        fFilter(std::move(f)), fValues(pd->GetLoopManagerUnchecked()->GetNSlots()), fPrevNodePtr(std::move(pd)),
        fPrevNode(*fPrevNodePtr)
   {
   }

   RFilter(const RFilter &) = delete;
   RFilter &operator=(const RFilter &) = delete;
   ~RFilter() {
      // must Deregister objects from the RLoopManager here, before the fPrevNode data member is destroyed:
      // otherwise if fPrevNode is the RLoopManager, it will be destroyed before the calls to Deregister happen.
      fColRegister.Clear(); // triggers RDefine deregistration
      fLoopManager->Deregister(this);
   }

   bool CheckFilters(unsigned int slot, Long64_t entry) final
   {
      if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
         if (!fPrevNode.CheckFilters(slot, entry)) {
            // a filter upstream returned false, cache the result
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = false;
         } else {
            // evaluate this filter, cache the result
            auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
            passed ? ++fAccepted[slot * RDFInternal::CacheLineStep<ULong64_t>()]
                   : ++fRejected[slot * RDFInternal::CacheLineStep<ULong64_t>()];
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = passed;
         }
         fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
      }
      return fLastResult[slot * RDFInternal::CacheLineStep<int>()];
   }

   template <typename... ColTypes, std::size_t... S>
   bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
   {
      // silence "unused parameter" warnings in gcc
      (void)slot;
      (void)entry;
      return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
   }

   void InitSlot(TTreeReader *r, unsigned int slot) final
   {
      RDFInternal::RColumnReadersInfo info{fColumnNames, fColRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
                                           fLoopManager->GetDataSource()};
      fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation);
      fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
   }

   // recursive chain of `Report`s
   void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }

   void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
   {
      fPrevNode.PartialReport(rep);
      FillReport(rep);
   }

   void StopProcessing() final
   {
      ++fNStopsReceived;
      if (fNStopsReceived == fNChildren)
         fPrevNode.StopProcessing();
   }

   void IncrChildrenCount() final
   {
      ++fNChildren;
      // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
      if (fNChildren == 1 && fName.empty())
         fPrevNode.IncrChildrenCount();
   }

   void TriggerChildrenCount() final
   {
      assert(!fName.empty()); // this method is to only be called on named filters
      fPrevNode.IncrChildrenCount();
   }

   void AddFilterName(std::vector<std::string> &filters)
   {
      fPrevNode.AddFilterName(filters);
      auto name = (HasName() ? fName : "Unnamed Filter");
      filters.push_back(name);
   }

   /// Clean-up operations to be performed at the end of a task.
   void FinalizeSlot(unsigned int slot) final
   {
      for (auto &v : fValues[slot])
         v.reset();
   }

   std::shared_ptr<RDFGraphDrawing::GraphNode>
   GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap)
   {
      // Recursively call for the previous node.
      auto prevNode = fPrevNode.GetGraph(visitedMap);
      auto prevColumns = prevNode->GetDefinedColumns();

      auto thisNode = RDFGraphDrawing::CreateFilterNode(this, visitedMap);

      /* If the returned node is not new, there is no need to perform any other operation.
       * This is a likely scenario when building the entire graph in which branches share
       * some nodes. */
      if (!thisNode->GetIsNew()) {
         return thisNode;
      }

      auto upmostNode = AddDefinesToGraph(thisNode, fColRegister, prevColumns, visitedMap);

      // Keep track of the columns defined up to this point.
      thisNode->AddDefinedColumns(fColRegister.GetNames());

      upmostNode->SetPrevNode(prevNode);
      return thisNode;
   }

   /// Return a clone of this Filter that works with values in the variationName "universe".
   std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
   {
      // nobody should ask for a varied filter for the nominal variation: they can just
      // use the nominal filter!
      assert(variationName != "nominal");

      auto it = fVariedFilters.find(variationName);
      if (it != fVariedFilters.end())
         return it->second;

      auto prevNode = fPrevNodePtr;
      if ((void *)fPrevNodePtr.get() != (void *)fLoopManager)
         prevNode = std::static_pointer_cast<PrevNode>(prevNode->GetVariedFilter(variationName));

      // the varied filters get a copy of the callable object.
      // TODO document this
      auto variedFilter = std::unique_ptr<RFilterBase>(
         new RFilter(fFilter, fColumnNames, std::move(prevNode), fColRegister, fName, variationName));
      fLoopManager->Book(variedFilter.get());
      auto e = fVariedFilters.insert({variationName, std::move(variedFilter)});
      return e.first->second;
   }
};

} // ns RDF
} // ns Detail
} // ns ROOT

#endif // ROOT_RFILTER
<|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2018

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

#ifndef ROOT_RFILTER
#define ROOT_RFILTER

#include "ROOT/RDF/ColumnReaderUtils.hxx"
#include "ROOT/RDF/RColumnReaderBase.hxx"
#include "ROOT/RDF/RCutFlowReport.hxx"
#include "ROOT/RDF/Utils.hxx"
#include "ROOT/RDF/RFilterBase.hxx"
#include "ROOT/RDF/RLoopManager.hxx"
#include "ROOT/TypeTraits.hxx"
#include "RtypesCore.h"

#include <algorithm>
#include <cassert>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility> // std::index_sequence
#include <vector>

namespace ROOT {

namespace Internal {
namespace RDF {
using namespace ROOT::Detail::RDF;

// fwd decl for RFilter
namespace GraphDrawing {
std::shared_ptr<GraphNode>
CreateFilterNode(const RFilterBase *filterPtr, std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);

std::shared_ptr<GraphNode> AddDefinesToGraph(std::shared_ptr<GraphNode> node,
                                             const RDFInternal::RColumnRegister &colRegister,
                                             const std::vector<std::string> &prevNodeDefines,
                                             std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
} // ns GraphDrawing

} // ns RDF
} // ns Internal

namespace Detail {
namespace RDF {
using namespace ROOT::TypeTraits;
namespace RDFGraphDrawing = ROOT::Internal::RDF::GraphDrawing;

template <typename FilterF, typename PrevNode>
class R__CLING_PTRCHECK(off) RFilter final : public RFilterBase {
   using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
   using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;

   FilterF fFilter;
   /// Column readers per slot and per input column
   std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>> fValues;
   const std::shared_ptr<PrevNode> fPrevNodePtr;
   PrevNode &fPrevNode;

   std::unordered_map<std::string, std::shared_ptr<RFilterBase>> fVariedFilters;

public:
   RFilter(FilterF f, const ROOT::RDF::ColumnNames_t &columns, std::shared_ptr<PrevNode> pd,
           const RDFInternal::RColumnRegister &colRegister, std::string_view name = "",
           const std::string &variationName = "nominal")
      : RFilterBase(pd->GetLoopManagerUnchecked(), name, pd->GetLoopManagerUnchecked()->GetNSlots(), colRegister,
                    columns, pd->GetVariations(), variationName),
        fFilter(std::move(f)), fValues(pd->GetLoopManagerUnchecked()->GetNSlots()), fPrevNodePtr(std::move(pd)),
        fPrevNode(*fPrevNodePtr)
   {
   }

   RFilter(const RFilter &) = delete;
   RFilter &operator=(const RFilter &) = delete;
   ~RFilter() {
      // must Deregister objects from the RLoopManager here, before the fPrevNode data member is destroyed:
      // otherwise if fPrevNode is the RLoopManager, it will be destroyed before the calls to Deregister happen.
      fColRegister.Clear(); // triggers RDefine deregistration
      fLoopManager->Deregister(this);
   }

   bool CheckFilters(unsigned int slot, Long64_t entry) final
   {
      if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
         if (!fPrevNode.CheckFilters(slot, entry)) {
            // a filter upstream returned false, cache the result
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = false;
         } else {
            // evaluate this filter, cache the result
            auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
            passed ? ++fAccepted[slot * RDFInternal::CacheLineStep<ULong64_t>()]
                   : ++fRejected[slot * RDFInternal::CacheLineStep<ULong64_t>()];
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = passed;
         }
         fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
      }
      return fLastResult[slot * RDFInternal::CacheLineStep<int>()];
   }

   template <typename... ColTypes, std::size_t... S>
   bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
   {
      // silence "unused parameter" warnings in gcc
      (void)slot;
      (void)entry;
      return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
   }

   void InitSlot(TTreeReader *r, unsigned int slot) final
   {
      RDFInternal::RColumnReadersInfo info{fColumnNames, fColRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
                                           fLoopManager->GetDataSource()};
      fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation);
      fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
   }

   // recursive chain of `Report`s
   void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }

   void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
   {
      fPrevNode.PartialReport(rep);
      FillReport(rep);
   }

   void StopProcessing() final
   {
      ++fNStopsReceived;
      if (fNStopsReceived == fNChildren)
         fPrevNode.StopProcessing();
   }

   void IncrChildrenCount() final
   {
      ++fNChildren;
      // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
      if (fNChildren == 1 && fName.empty())
         fPrevNode.IncrChildrenCount();
   }

   void TriggerChildrenCount() final
   {
      assert(!fName.empty()); // this method is to only be called on named filters
      fPrevNode.IncrChildrenCount();
   }

   void AddFilterName(std::vector<std::string> &filters)
   {
      fPrevNode.AddFilterName(filters);
      auto name = (HasName() ? fName : "Unnamed Filter");
      filters.push_back(name);
   }

   /// Clean-up operations to be performed at the end of a task.
   void FinalizeSlot(unsigned int slot) final
   {
      for (auto &v : fValues[slot])
         v.reset();
   }

   std::shared_ptr<RDFGraphDrawing::GraphNode>
   GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap)
   {
      // Recursively call for the previous node.
      auto prevNode = fPrevNode.GetGraph(visitedMap);
      auto prevColumns = prevNode->GetDefinedColumns();

      auto thisNode = RDFGraphDrawing::CreateFilterNode(this, visitedMap);

      /* If the returned node is not new, there is no need to perform any other operation.
       * This is a likely scenario when building the entire graph in which branches share
       * some nodes. */
      if (!thisNode->GetIsNew()) {
         return thisNode;
      }

      auto upmostNode = AddDefinesToGraph(thisNode, fColRegister, prevColumns, visitedMap);

      // Keep track of the columns defined up to this point.
      thisNode->AddDefinedColumns(fColRegister.GetNames());

      upmostNode->SetPrevNode(prevNode);
      return thisNode;
   }

   /// Return a clone of this Filter that works with values in the variationName "universe".
   std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
   {
      // nobody should ask for a varied filter for the nominal variation: they can just
      // use the nominal filter!
      assert(variationName != "nominal");

      auto it = fVariedFilters.find(variationName);
      if (it != fVariedFilters.end())
         return it->second;

      auto prevNode = fPrevNodePtr;
      if ((void *)fPrevNodePtr.get() != (void *)fLoopManager)
         prevNode = std::static_pointer_cast<PrevNode>(prevNode->GetVariedFilter(variationName));

      // the varied filters get a copy of the callable object.
      // TODO document this
      auto variedFilter = std::unique_ptr<RFilterBase>(
         new RFilter(fFilter, fColumnNames, std::move(prevNode), fColRegister, fName, variationName));
      fLoopManager->Book(variedFilter.get());
      auto e = fVariedFilters.insert({variationName, std::move(variedFilter)});
      return e.first->second;
   }
};

} // ns RDF
} // ns Detail
} // ns ROOT

#endif // ROOT_RFILTER
<commit_msg>[DF] Compare pointers to base rather than pointers to void<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  09/2018

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

#ifndef ROOT_RFILTER
#define ROOT_RFILTER

#include "ROOT/RDF/ColumnReaderUtils.hxx"
#include "ROOT/RDF/RColumnReaderBase.hxx"
#include "ROOT/RDF/RCutFlowReport.hxx"
#include "ROOT/RDF/Utils.hxx"
#include "ROOT/RDF/RFilterBase.hxx"
#include "ROOT/RDF/RLoopManager.hxx"
#include "ROOT/TypeTraits.hxx"
#include "RtypesCore.h"

#include <algorithm>
#include <cassert>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility> // std::index_sequence
#include <vector>

namespace ROOT {

namespace Internal {
namespace RDF {
using namespace ROOT::Detail::RDF;

// fwd decl for RFilter
namespace GraphDrawing {
std::shared_ptr<GraphNode>
CreateFilterNode(const RFilterBase *filterPtr, std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);

std::shared_ptr<GraphNode> AddDefinesToGraph(std::shared_ptr<GraphNode> node,
                                             const RDFInternal::RColumnRegister &colRegister,
                                             const std::vector<std::string> &prevNodeDefines,
                                             std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
} // ns GraphDrawing

} // ns RDF
} // ns Internal

namespace Detail {
namespace RDF {
using namespace ROOT::TypeTraits;
namespace RDFGraphDrawing = ROOT::Internal::RDF::GraphDrawing;

template <typename FilterF, typename PrevNode>
class R__CLING_PTRCHECK(off) RFilter final : public RFilterBase {
   using ColumnTypes_t = typename CallableTraits<FilterF>::arg_types;
   using TypeInd_t = std::make_index_sequence<ColumnTypes_t::list_size>;

   FilterF fFilter;
   /// Column readers per slot and per input column
   std::vector<std::array<std::unique_ptr<RColumnReaderBase>, ColumnTypes_t::list_size>> fValues;
   const std::shared_ptr<PrevNode> fPrevNodePtr;
   PrevNode &fPrevNode;

   std::unordered_map<std::string, std::shared_ptr<RFilterBase>> fVariedFilters;

public:
   RFilter(FilterF f, const ROOT::RDF::ColumnNames_t &columns, std::shared_ptr<PrevNode> pd,
           const RDFInternal::RColumnRegister &colRegister, std::string_view name = "",
           const std::string &variationName = "nominal")
      : RFilterBase(pd->GetLoopManagerUnchecked(), name, pd->GetLoopManagerUnchecked()->GetNSlots(), colRegister,
                    columns, pd->GetVariations(), variationName),
        fFilter(std::move(f)), fValues(pd->GetLoopManagerUnchecked()->GetNSlots()), fPrevNodePtr(std::move(pd)),
        fPrevNode(*fPrevNodePtr)
   {
   }

   RFilter(const RFilter &) = delete;
   RFilter &operator=(const RFilter &) = delete;
   ~RFilter() {
      // must Deregister objects from the RLoopManager here, before the fPrevNode data member is destroyed:
      // otherwise if fPrevNode is the RLoopManager, it will be destroyed before the calls to Deregister happen.
      fColRegister.Clear(); // triggers RDefine deregistration
      fLoopManager->Deregister(this);
   }

   bool CheckFilters(unsigned int slot, Long64_t entry) final
   {
      if (entry != fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()]) {
         if (!fPrevNode.CheckFilters(slot, entry)) {
            // a filter upstream returned false, cache the result
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = false;
         } else {
            // evaluate this filter, cache the result
            auto passed = CheckFilterHelper(slot, entry, ColumnTypes_t{}, TypeInd_t{});
            passed ? ++fAccepted[slot * RDFInternal::CacheLineStep<ULong64_t>()]
                   : ++fRejected[slot * RDFInternal::CacheLineStep<ULong64_t>()];
            fLastResult[slot * RDFInternal::CacheLineStep<int>()] = passed;
         }
         fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = entry;
      }
      return fLastResult[slot * RDFInternal::CacheLineStep<int>()];
   }

   template <typename... ColTypes, std::size_t... S>
   bool CheckFilterHelper(unsigned int slot, Long64_t entry, TypeList<ColTypes...>, std::index_sequence<S...>)
   {
      // silence "unused parameter" warnings in gcc
      (void)slot;
      (void)entry;
      return fFilter(fValues[slot][S]->template Get<ColTypes>(entry)...);
   }

   void InitSlot(TTreeReader *r, unsigned int slot) final
   {
      RDFInternal::RColumnReadersInfo info{fColumnNames, fColRegister, fIsDefine.data(), fLoopManager->GetDSValuePtrs(),
                                           fLoopManager->GetDataSource()};
      fValues[slot] = RDFInternal::MakeColumnReaders(slot, r, ColumnTypes_t{}, info, fVariation);
      fLastCheckedEntry[slot * RDFInternal::CacheLineStep<Long64_t>()] = -1;
   }

   // recursive chain of `Report`s
   void Report(ROOT::RDF::RCutFlowReport &rep) const final { PartialReport(rep); }

   void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
   {
      fPrevNode.PartialReport(rep);
      FillReport(rep);
   }

   void StopProcessing() final
   {
      ++fNStopsReceived;
      if (fNStopsReceived == fNChildren)
         fPrevNode.StopProcessing();
   }

   void IncrChildrenCount() final
   {
      ++fNChildren;
      // propagate "children activation" upstream. named filters do the propagation via `TriggerChildrenCount`.
      if (fNChildren == 1 && fName.empty())
         fPrevNode.IncrChildrenCount();
   }

   void TriggerChildrenCount() final
   {
      assert(!fName.empty()); // this method is to only be called on named filters
      fPrevNode.IncrChildrenCount();
   }

   void AddFilterName(std::vector<std::string> &filters)
   {
      fPrevNode.AddFilterName(filters);
      auto name = (HasName() ? fName : "Unnamed Filter");
      filters.push_back(name);
   }

   /// Clean-up operations to be performed at the end of a task.
   void FinalizeSlot(unsigned int slot) final
   {
      for (auto &v : fValues[slot])
         v.reset();
   }

   std::shared_ptr<RDFGraphDrawing::GraphNode>
   GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap)
   {
      // Recursively call for the previous node.
      auto prevNode = fPrevNode.GetGraph(visitedMap);
      auto prevColumns = prevNode->GetDefinedColumns();

      auto thisNode = RDFGraphDrawing::CreateFilterNode(this, visitedMap);

      /* If the returned node is not new, there is no need to perform any other operation.
       * This is a likely scenario when building the entire graph in which branches share
       * some nodes. */
      if (!thisNode->GetIsNew()) {
         return thisNode;
      }

      auto upmostNode = AddDefinesToGraph(thisNode, fColRegister, prevColumns, visitedMap);

      // Keep track of the columns defined up to this point.
      thisNode->AddDefinedColumns(fColRegister.GetNames());

      upmostNode->SetPrevNode(prevNode);
      return thisNode;
   }

   /// Return a clone of this Filter that works with values in the variationName "universe".
   std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
   {
      // nobody should ask for a varied filter for the nominal variation: they can just
      // use the nominal filter!
      assert(variationName != "nominal");

      auto it = fVariedFilters.find(variationName);
      if (it != fVariedFilters.end())
         return it->second;

      auto prevNode = fPrevNodePtr;
      if (static_cast<RNodeBase *>(fPrevNodePtr.get()) != static_cast<RNodeBase *>(fLoopManager))
         prevNode = std::static_pointer_cast<PrevNode>(prevNode->GetVariedFilter(variationName));

      // the varied filters get a copy of the callable object.
      // TODO document this
      auto variedFilter = std::unique_ptr<RFilterBase>(
         new RFilter(fFilter, fColumnNames, std::move(prevNode), fColRegister, fName, variationName));
      fLoopManager->Book(variedFilter.get());
      auto e = fVariedFilters.insert({variationName, std::move(variedFilter)});
      return e.first->second;
   }
};

} // ns RDF
} // ns Detail
} // ns ROOT

#endif // ROOT_RFILTER
<|endoftext|>


<commit_before>// XDRFileMarshaller.cc

// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: Patrick West <pwest@ucar.edu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// (c) COPYRIGHT URI/MIT 1994-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>

#include "XDRFileMarshaller.h"

#include "Vector.h"
#include "util.h"
#include "InternalErr.h"

namespace libdap {

XDRFileMarshaller::XDRFileMarshaller( FILE *out )
    : _sink( 0 )
{
    _sink = new_xdrstdio( out, XDR_ENCODE ) ;
}

XDRFileMarshaller::XDRFileMarshaller()
    : Marshaller(),
      _sink( 0 )
{
    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
}

XDRFileMarshaller::XDRFileMarshaller( const XDRFileMarshaller &m )
    : Marshaller( m ),
      _sink( 0 )
{
    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
}

XDRFileMarshaller &
XDRFileMarshaller::operator=( const XDRFileMarshaller & )
{
    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;

    return *this ;
}

XDRFileMarshaller::~XDRFileMarshaller( )
{
    delete_xdrstdio( _sink ) ;
}

void
XDRFileMarshaller::put_byte( dods_byte val )
{
    if( !xdr_char( _sink, (char *)&val ) )
        throw Error("Network I/O Error. Could not send byte data.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int16( dods_int16 val )
{
    if( !XDR_INT16( _sink, &val ) )
        throw Error("Network I/O Error. Could not send int 16 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int32( dods_int32 val )
{
#ifdef _MSC_VER
    if( !XDR_INT32( _sink, (int *)&val ) )
#else
    if( !XDR_INT32( _sink, &val ) )
#endif
        throw Error("Network I/O Error. Could not read int 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_float32( dods_float32 val )
{
    if( !xdr_float( _sink, &val ) )
        throw Error("Network I/O Error. Could not send float 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_float64( dods_float64 val )
{
    if( !xdr_double( _sink, &val ) )
        throw Error("Network I/O Error. Could not send float 64 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_uint16( dods_uint16 val )
{
    if( !XDR_UINT16( _sink, &val ) )
        throw Error("Network I/O Error. Could not send uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
}

void
XDRFileMarshaller::put_uint32( dods_uint32 val )
{
    if( !XDR_UINT32( _sink, &val ) )
        throw Error("Network I/O Error. Could not send uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
}

void
XDRFileMarshaller::put_str( const string &val )
{
    const char *out_tmp = val.c_str() ;

    if( !xdr_string( _sink, (char **)&out_tmp, max_str_len) )
        throw Error("Network I/O Error. Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_url( const string &val )
{
    put_str( val ) ;
}

void
XDRFileMarshaller::put_opaque( char *val, unsigned int len )
{
    if( !xdr_opaque( _sink, val, len ) )
        throw Error("Network I/O Error. Could not send opaque data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int( int val )
{
    if( !xdr_int( _sink, &val) )
	throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_vector( char *val, int num, Vector & )
{
    if (!val)
	throw InternalErr(__FILE__, __LINE__,
			  "Buffer pointer is not set.");

    put_int( num ) ;

    if( !xdr_bytes( _sink, (char **)&val,
		    (unsigned int *) &num,
		    DODS_MAX_ARRAY) )
    {
	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
    }
}

void
XDRFileMarshaller::put_vector( char *val, int num, int width, Vector &vec )
{
    if (!val)
	throw InternalErr(__FILE__, __LINE__,
			  "Buffer pointer is not set.");

    put_int( num ) ;

    BaseType *var = vec.var() ;
    if( !xdr_array( _sink, (char **)&val,
		    (unsigned int *) & num,
		    DODS_MAX_ARRAY, width,
		    XDRUtils::xdr_coder( var->type() ) ) )
    {
	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
    }
}

void
XDRFileMarshaller::dump(ostream &strm) const
{
    strm << DapIndent::LMarg << "XDRFileMarshaller::dump - ("
         << (void *)this << ")" << endl ;
}

} // namespace libdap

<commit_msg>Added patch from Anna Nokolov.<commit_after>// XDRFileMarshaller.cc

// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: Patrick West <pwest@ucar.edu>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// (c) COPYRIGHT URI/MIT 1994-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
//      pwest       Patrick West <pwest@ucar.edu>

#include "XDRFileMarshaller.h"

#include "Vector.h"
#include "util.h"
#include "InternalErr.h"

namespace libdap {

XDRFileMarshaller::XDRFileMarshaller( FILE *out )
    : _sink( 0 )
{
    _sink = new_xdrstdio( out, XDR_ENCODE ) ;
}

XDRFileMarshaller::XDRFileMarshaller()
    : Marshaller(),
      _sink( 0 )
{
    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
}

XDRFileMarshaller::XDRFileMarshaller( const XDRFileMarshaller &m )
    : Marshaller( m ),
      _sink( 0 )
{
    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
}

XDRFileMarshaller &
XDRFileMarshaller::operator=( const XDRFileMarshaller & )
{
    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;

    return *this ;
}

XDRFileMarshaller::~XDRFileMarshaller( )
{
    delete_xdrstdio( _sink ) ;
}

void
XDRFileMarshaller::put_byte( dods_byte val )
{
    if( !xdr_char( _sink, (char *)&val ) )
        throw Error("Network I/O Error. Could not send byte data.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int16( dods_int16 val )
{
    if( !XDR_INT16( _sink, &val ) )
        throw Error("Network I/O Error. Could not send int 16 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int32( dods_int32 val )
{
#ifdef _MSC_VER
    if( !XDR_INT32( _sink, (int *)&val ) )
#else
    if( !XDR_INT32( _sink, &val ) )
#endif
        throw Error("Network I/O Error. Could not read int 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_float32( dods_float32 val )
{
    if( !xdr_float( _sink, &val ) )
        throw Error("Network I/O Error. Could not send float 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_float64( dods_float64 val )
{
    if( !xdr_double( _sink, &val ) )
        throw Error("Network I/O Error. Could not send float 64 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_uint16( dods_uint16 val )
{
    if( !XDR_UINT16( _sink, &val ) )
        throw Error("Network I/O Error. Could not send uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
}

void
XDRFileMarshaller::put_uint32( dods_uint32 val )
{
#ifdef _MSC_VER
    if( !XDR_UINT32( _sink, (unsigned int *)&val ) )
#else
  	if( !XDR_UINT32( _sink, &val ) )
#endif
        throw Error("Network I/O Error. Could not send uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
}

void
XDRFileMarshaller::put_str( const string &val )
{
    const char *out_tmp = val.c_str() ;

    if( !xdr_string( _sink, (char **)&out_tmp, max_str_len) )
        throw Error("Network I/O Error. Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_url( const string &val )
{
    put_str( val ) ;
}

void
XDRFileMarshaller::put_opaque( char *val, unsigned int len )
{
    if( !xdr_opaque( _sink, val, len ) )
        throw Error("Network I/O Error. Could not send opaque data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_int( int val )
{
    if( !xdr_int( _sink, &val) )
	throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
}

void
XDRFileMarshaller::put_vector( char *val, int num, Vector & )
{
    if (!val)
	throw InternalErr(__FILE__, __LINE__,
			  "Buffer pointer is not set.");

    put_int( num ) ;

    if( !xdr_bytes( _sink, (char **)&val,
		    (unsigned int *) &num,
		    DODS_MAX_ARRAY) )
    {
	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
    }
}

void
XDRFileMarshaller::put_vector( char *val, int num, int width, Vector &vec )
{
    if (!val)
	throw InternalErr(__FILE__, __LINE__,
			  "Buffer pointer is not set.");

    put_int( num ) ;

    BaseType *var = vec.var() ;
    if( !xdr_array( _sink, (char **)&val,
		    (unsigned int *) & num,
		    DODS_MAX_ARRAY, width,
		    XDRUtils::xdr_coder( var->type() ) ) )
    {
	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
    }
}

void
XDRFileMarshaller::dump(ostream &strm) const
{
    strm << DapIndent::LMarg << "XDRFileMarshaller::dump - ("
         << (void *)this << ")" << endl ;
}

} // namespace libdap

<|endoftext|>