<commit_before>#ifndef __chaiscriptdispatchkit_dynamic_cast_conversion_hpp__
#define __chaiscriptdispatchkit_dynamic_cast_conversion_hpp__

#include "type_info.hpp"
#include "boxed_value.hpp"
#include "boxed_cast_helper.hpp"
#include "bad_boxed_cast.hpp"
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/thread/shared_mutex.hpp>

namespace chaiscript
{
  class bad_boxed_dynamic_cast : public bad_boxed_cast
  {
    public:
      bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
          const std::string &t_what)
        : bad_boxed_cast(t_from, t_to, t_what)
      {
      }

      bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw()
        : bad_boxed_cast(t_from, t_to)
      {
      }

      bad_boxed_dynamic_cast(const std::string &w) throw()
        : bad_boxed_cast(w)
      {
      }
  };

  namespace detail
  {
    class Dynamic_Conversion
    {
      public:
        virtual Boxed_Value convert(const Boxed_Value &derived) = 0;
        const Type_Info &base()
        {
          return m_base;
        }
        const Type_Info &derived()
        {
          return m_derived;
        }

      protected:
        Dynamic_Conversion(const Type_Info &t_base, const Type_Info &t_derived)
          : m_base(t_base), m_derived(t_derived)
        {
        }

      private:
        Type_Info m_base;
        Type_Info m_derived;

    };

    template<typename Base, typename Derived>
    class Dynamic_Conversion_Impl : public Dynamic_Conversion
    {
      public:
        Dynamic_Conversion_Impl()
          : Dynamic_Conversion(user_type<Base>(), user_type<Derived>())
        {
        }

        virtual Boxed_Value convert(const Boxed_Value &derived)
        {
          if (derived.get_type_info().bare_equal(user_type<Derived>()))
          {
            if (derived.is_pointer())
            {
              // Dynamic cast out the contained boxed value, which we know is the type we want
              if (derived.is_const())
              {
                boost::shared_ptr<const Base> data
                  = boost::dynamic_pointer_cast<const Base>(detail::Cast_Helper<boost::shared_ptr<const Derived> >::cast(derived));
                if (!data)
                {
                  throw std::bad_cast();
                }

                return Boxed_Value(data);
              } else {
                boost::shared_ptr<Base> data
                  = boost::dynamic_pointer_cast<Base>(detail::Cast_Helper<boost::shared_ptr<Derived> >::cast(derived));

                if (!data)
                {
                  throw std::bad_cast();
                }

                return Boxed_Value(data);
              }
            } else {
              // Pull the reference out of the contained boxed value, which we know is the type we want
              if (derived.is_const())
              {
                const Derived &d = detail::Cast_Helper<const Derived &>::cast(derived);
                const Base &data = dynamic_cast<const Base &>(d);
                return Boxed_Value(boost::cref(data));
              } else {
                Derived &d = detail::Cast_Helper<Derived &>::cast(derived);
                Base &data = dynamic_cast<Base &>(d);
                return Boxed_Value(boost::ref(data));
              }
            }
          } else {
            throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
          }

        }
    };

    class Dynamic_Conversions
    {
      public:
        static Dynamic_Conversions &get()
        {
          static Dynamic_Conversions obj;
          return obj;
        }

        template<typename Base, typename Derived>
          void add_conversion()
          {
#ifndef CHAISCRIPT_NO_THREADS
            boost::unique_lock<boost::shared_mutex> l(m_mutex);
#endif

            m_conversions.push_back(
                boost::shared_ptr<Dynamic_Conversion>(new Dynamic_Conversion_Impl<Base, Derived>())
              );
          }

        bool has_conversion(const Type_Info &base, const Type_Info &derived)
        {
#ifndef CHAISCRIPT_NO_THREADS
          boost::shared_lock<boost::shared_mutex> l(m_mutex);
#endif

          for (std::vector<boost::shared_ptr<Dynamic_Conversion> >::const_iterator itr = m_conversions.begin();
               itr != m_conversions.end();
               ++itr)
          {
            if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived))
            {
              return true;
            }
          }

          return false;
        }

        boost::shared_ptr<Dynamic_Conversion> get_conversion(const Type_Info &base, const Type_Info &derived)
        {
#ifndef CHAISCRIPT_NO_THREADS
          boost::shared_lock<boost::shared_mutex> l(m_mutex);
#endif

          for (std::vector<boost::shared_ptr<Dynamic_Conversion> >::const_iterator itr = m_conversions.begin();
               itr != m_conversions.end();
               ++itr)
          {
            if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived))
            {
              return *itr;
            }
          }

          throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name());
        }

      private:
        Dynamic_Conversions() {}
#ifndef CHAISCRIPT_NO_THREADS
        boost::shared_mutex m_mutex;
#endif
        std::vector<boost::shared_ptr<Dynamic_Conversion> > m_conversions;
    };
  }

  template<typename Base, typename Derived>
  void register_base_class()
  {
    //Can only be used with related polymorphic types
    //may be expanded some day to support conversions other than child -> parent
    BOOST_STATIC_ASSERT((boost::is_base_of<Base,Derived>::value));
    BOOST_STATIC_ASSERT(boost::is_polymorphic<Base>::value);
    BOOST_STATIC_ASSERT(boost::is_polymorphic<Derived>::value);

    detail::Dynamic_Conversions::get().add_conversion<Base, Derived>();
  }

  template<typename Base, typename Derived>
  bool dynamic_cast_converts()
  {
    return dynamic_cast_converts(user_type<Base>(), user_type<Derived>());
  }

  bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived)
  {
    return detail::Dynamic_Conversions::get().has_conversion(base, derived);
  }

  template<typename Base>
  Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived)
  {
    try {
      return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
    } catch (const std::out_of_range &) {
      throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
    } catch (const std::bad_cast &) {
      throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
    }
  }

}

#endif
<commit_msg>Make sure the same base/derived relationship is never registered more than once<commit_after>#ifndef __chaiscriptdispatchkit_dynamic_cast_conversion_hpp__
#define __chaiscriptdispatchkit_dynamic_cast_conversion_hpp__

#include "type_info.hpp"
#include "boxed_value.hpp"
#include "boxed_cast_helper.hpp"
#include "bad_boxed_cast.hpp"
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_polymorphic.hpp>
#include <boost/thread/shared_mutex.hpp>

namespace chaiscript
{
  class bad_boxed_dynamic_cast : public bad_boxed_cast
  {
    public:
      bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to,
          const std::string &t_what)
        : bad_boxed_cast(t_from, t_to, t_what)
      {
      }

      bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw()
        : bad_boxed_cast(t_from, t_to)
      {
      }

      bad_boxed_dynamic_cast(const std::string &w) throw()
        : bad_boxed_cast(w)
      {
      }
  };

  namespace detail
  {
    class Dynamic_Conversion
    {
      public:
        virtual Boxed_Value convert(const Boxed_Value &derived) = 0;
        const Type_Info &base()
        {
          return m_base;
        }
        const Type_Info &derived()
        {
          return m_derived;
        }

      protected:
        Dynamic_Conversion(const Type_Info &t_base, const Type_Info &t_derived)
          : m_base(t_base), m_derived(t_derived)
        {
        }

      private:
        Type_Info m_base;
        Type_Info m_derived;

    };

    template<typename Base, typename Derived>
    class Dynamic_Conversion_Impl : public Dynamic_Conversion
    {
      public:
        Dynamic_Conversion_Impl()
          : Dynamic_Conversion(user_type<Base>(), user_type<Derived>())
        {
        }

        virtual Boxed_Value convert(const Boxed_Value &derived)
        {
          if (derived.get_type_info().bare_equal(user_type<Derived>()))
          {
            if (derived.is_pointer())
            {
              // Dynamic cast out the contained boxed value, which we know is the type we want
              if (derived.is_const())
              {
                boost::shared_ptr<const Base> data
                  = boost::dynamic_pointer_cast<const Base>(detail::Cast_Helper<boost::shared_ptr<const Derived> >::cast(derived));
                if (!data)
                {
                  throw std::bad_cast();
                }

                return Boxed_Value(data);
              } else {
                boost::shared_ptr<Base> data
                  = boost::dynamic_pointer_cast<Base>(detail::Cast_Helper<boost::shared_ptr<Derived> >::cast(derived));

                if (!data)
                {
                  throw std::bad_cast();
                }

                return Boxed_Value(data);
              }
            } else {
              // Pull the reference out of the contained boxed value, which we know is the type we want
              if (derived.is_const())
              {
                const Derived &d = detail::Cast_Helper<const Derived &>::cast(derived);
                const Base &data = dynamic_cast<const Base &>(d);
                return Boxed_Value(boost::cref(data));
              } else {
                Derived &d = detail::Cast_Helper<Derived &>::cast(derived);
                Base &data = dynamic_cast<Base &>(d);
                return Boxed_Value(boost::ref(data));
              }
            }
          } else {
            throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion");
          }

        }
    };

    class Dynamic_Conversions
    {
      public:
        static Dynamic_Conversions &get()
        {
          static Dynamic_Conversions obj;
          return obj;
        }

        template<typename Base, typename Derived>
          void add_conversion()
          {
#ifndef CHAISCRIPT_NO_THREADS
            boost::unique_lock<boost::shared_mutex> l(m_mutex);
#endif

            if (find(user_type<Base>(), user_type<Derived>()) == m_conversions.end())
            {
              m_conversions.push_back(
                  boost::shared_ptr<Dynamic_Conversion>(new Dynamic_Conversion_Impl<Base, Derived>())
                  );
            }
          }

        bool has_conversion(const Type_Info &base, const Type_Info &derived)
        {
#ifndef CHAISCRIPT_NO_THREADS
          boost::shared_lock<boost::shared_mutex> l(m_mutex);
#endif

          return find(base, derived) != m_conversions.end();
        }

        boost::shared_ptr<Dynamic_Conversion> get_conversion(const Type_Info &base, const Type_Info &derived)
        {
#ifndef CHAISCRIPT_NO_THREADS
          boost::shared_lock<boost::shared_mutex> l(m_mutex);
#endif

          std::vector<boost::shared_ptr<Dynamic_Conversion> >::const_iterator itr =
            find(base, derived);

          if (itr != m_conversions.end())
          {
            return *itr;
          } else {
            throw std::out_of_range("No such conversion exists from " + derived.bare_name() + " to " + base.bare_name());
          }
        }

      private:
        Dynamic_Conversions() {}

        std::vector<boost::shared_ptr<Dynamic_Conversion> >::const_iterator find(
            const Type_Info &base, const Type_Info &derived)
        {
          for (std::vector<boost::shared_ptr<Dynamic_Conversion> >::const_iterator itr = m_conversions.begin();
               itr != m_conversions.end();
               ++itr)
          {
            if ((*itr)->base().bare_equal(base) && (*itr)->derived().bare_equal(derived))
            {
              return itr;
            }
          }

          return m_conversions.end();
        }
#ifndef CHAISCRIPT_NO_THREADS
        boost::shared_mutex m_mutex;
#endif
        std::vector<boost::shared_ptr<Dynamic_Conversion> > m_conversions;
    };
  }

  template<typename Base, typename Derived>
  void register_base_class()
  {
    //Can only be used with related polymorphic types
    //may be expanded some day to support conversions other than child -> parent
    BOOST_STATIC_ASSERT((boost::is_base_of<Base,Derived>::value));
    BOOST_STATIC_ASSERT(boost::is_polymorphic<Base>::value);
    BOOST_STATIC_ASSERT(boost::is_polymorphic<Derived>::value);

    detail::Dynamic_Conversions::get().add_conversion<Base, Derived>();
  }

  template<typename Base, typename Derived>
  bool dynamic_cast_converts()
  {
    return dynamic_cast_converts(user_type<Base>(), user_type<Derived>());
  }

  bool dynamic_cast_converts(const Type_Info &base, const Type_Info &derived)
  {
    return detail::Dynamic_Conversions::get().has_conversion(base, derived);
  }

  template<typename Base>
  Boxed_Value boxed_dynamic_cast(const Boxed_Value &derived)
  {
    try {
      return detail::Dynamic_Conversions::get().get_conversion(user_type<Base>(), derived.get_type_info())->convert(derived);
    } catch (const std::out_of_range &) {
      throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion");
    } catch (const std::bad_cast &) {
      throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation");
    }
  }

}

#endif
<|endoftext|>


<commit_before><commit_msg>Change C-style array to the class array<commit_after><|endoftext|>


<commit_before>#include "Effect.h"
#include <iostream>
#include <fstream>
#include <ios>
#include "Compiler.h"
#include "Ship.h"
#include "Module.h"
#include <cctype>
#include <algorithm>
#include "Item.h"
#include "Attribute.h"
#include "Engine.h"
#include "Character.h"

#include "Modifier.h"
#include "LocationGroupModifier.h"
#include "LocationRequiredSkillModifier.h"

#include "EffectByteCodeInterpreter.h"
#include "EffectLeechInterpreter.h"
#include "EffectEnergyDestabilizationNewInterpreter.h"
#include "EffectEnergyTransferInterpreter.h"
#include "EffectArmorRepairInterpreter.h"
#include "EffectHullRepairInterpreter.h"
#include "EffectShieldBoostingInterpreter.h"
#include "EffectSlotModifierInterpreter.h"
#include "EffectHardPointModifierEffectInterpreter.h"
#include "EffectAdaptiveArmorHardener.h"

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

using namespace eufe;

const TypeID eufe::ONLINE_EFFECT_ID = 16;
const TypeID eufe::LO_POWER_EFFECT_ID = 11;
const TypeID eufe::HI_POWER_EFFECT_ID = 12;
const TypeID eufe::MED_POWER_EFFECT_ID = 13;
const TypeID eufe::RIG_SLOT_EFFECT_ID = 2663;
const TypeID eufe::SUBSYSTEM_EFFECT_ID = 3772;
const TypeID eufe::TURRET_FITTED_EFFECT_ID = 42;
const TypeID eufe::LAUNCHER_FITTED_EFFECT_ID = 40;

const TypeID eufe::MINING_LASER_EFFECT_ID = 61;
const TypeID eufe::POWER_BOOSTER_EFFECT_ID = 48;
const TypeID eufe::PROJECTILE_FIRED_EFFECT_ID = 34;
const TypeID eufe::TARGET_ATTACK_EFFECT_ID = 10;
const TypeID eufe::USE_MISSILES_EFFECT_ID = 101;

const TypeID eufe::LEECH_EFFECT_ID = 3250;
const TypeID eufe::ENERGY_DESTABILIZATION_NEW_EFFECT_ID = 2303;
const TypeID eufe::ENERGY_TRANSFER_EFFECT_ID = 31;

const TypeID eufe::WARP_DISRUPTION_FIELD_EFFECT_ONLINE_EFFECT_ID = 3461;

const TypeID eufe::ARMOR_REPAIR_EFFECT_ID = 27;
const TypeID eufe::TARGET_ARMOR_REPAIR_EFFECT_ID = 592;
const TypeID eufe::SHIELD_BOOSTING_EFFECT_ID = 4;
const TypeID eufe::SHIELD_TRANSFER_EFFECT_ID = 18;
const TypeID eufe::STRUCTURE_REPAIR_EFFECT_ID = 26;
const TypeID eufe::REMOTE_HULL_REPAIR_EFFECT_ID = 3041;
const TypeID eufe::SLOT_MODIFIER_EFFECT_ID = 3774;
const TypeID eufe::HARD_POINT_MODIFIER_EFFECT_EFFECT_ID = 3773;

const TypeID eufe::ONLINE_FOR_STRUCTURES_EFFECT_ID = 901;

const TypeID eufe::ADAPTIVE_ARMOR_HARDENER_EFFECT_ID = 4928;
const TypeID eufe::FUELED_SHIELD_BOOSTING_EFFECT_ID = 4936;

static std::map<TypeID, boost::weak_ptr<eufe::Effect> > reusableEffects;

boost::shared_ptr<eufe::Effect> Effect::getEffect(Engine* engine, int effectID)
{
	Engine::ScopedLock lock(*engine);

	std::map<TypeID, boost::weak_ptr<eufe::Effect> >::iterator i, end = reusableEffects.end();
	i = reusableEffects.find(effectID);
	if (i == end) {
		boost::shared_ptr<Effect> effect(new Effect(engine, effectID));
		reusableEffects[effectID] = boost::weak_ptr<Effect>(effect);
		return effect;
	}
	else {
		return i->second.lock();
	}
}

#if _DEBUG
Effect::Effect(Engine* engine, TypeID effectID, Category category, const void* byteCode, size_t size, bool isAssistance, bool isOffensive, const char* effectName) : engine_(engine), effectID_(effectID), category_(category), effectName_(effectName)
#else
Effect::Effect(Engine* engine, TypeID effectID, Category category, const void* byteCode, size_t size, bool isAssistance, bool isOffensive) : engine_(engine), effectID_(effectID), category_(category)
#endif
{
	if (effectID == LEECH_EFFECT_ID)
		interpreter_ = new EffectLeechInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ENERGY_DESTABILIZATION_NEW_EFFECT_ID)
		interpreter_ = new EffectEnergyDestabilizationNewInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ENERGY_TRANSFER_EFFECT_ID)
		interpreter_ = new EffectEnergyTransferInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ARMOR_REPAIR_EFFECT_ID)
		interpreter_ = new EffectArmorRepairInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == TARGET_ARMOR_REPAIR_EFFECT_ID)
		interpreter_ = new EffectArmorRepairInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == STRUCTURE_REPAIR_EFFECT_ID)
		interpreter_ = new EffectHullRepairInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == REMOTE_HULL_REPAIR_EFFECT_ID)
		interpreter_ = new EffectHullRepairInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == SHIELD_BOOSTING_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == SHIELD_TRANSFER_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == SLOT_MODIFIER_EFFECT_ID)
		interpreter_ = new EffectSlotModifierInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == HARD_POINT_MODIFIER_EFFECT_EFFECT_ID)
		interpreter_ = new EffectHardPointModifierEffectInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ADAPTIVE_ARMOR_HARDENER_EFFECT_ID)
		interpreter_ = new EffectAdaptiveArmorHardener(engine, isAssistance, isOffensive);
	else if (effectID == FUELED_SHIELD_BOOSTING_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
	else
		interpreter_ = new EffectByteCodeInterpreter(engine, byteCode, size, isAssistance, isOffensive);
#if _DEBUG
	std::string::iterator i, end = effectName_.end();
	for (i = effectName_.begin(); i != end; i++)
	{
		char c = *i;
		if (!((c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
			*i = ' ';
	}
#endif
}

Effect::Effect(Engine* engine, TypeID effectID) : engine_(engine), effectID_(effectID)
{
	Engine::ScopedLock lock(*engine_);

	std::stringstream sql;
#if _DEBUG
	sql << "SELECT effectCategory, isOffensive, isAssistance, byteCode, effectName FROM dgmCompiledEffects WHERE effectID = " << effectID;
#else
	sql << "SELECT effectCategory, isOffensive, isAssistance, byteCode FROM dgmCompiledEffects WHERE effectID = " << effectID;
#endif

	boost::shared_ptr<FetchResult> result = engine_->getSqlConnector()->exec(sql.str().c_str());

	if (result->next())
	{
		category_ = static_cast<Effect::Category>(result->getInt(0));
		bool isAssistance = result->getInt(1) != 0;
		bool isOffensive = result->getInt(2) != 0;
		size_t size = result->getInt(3);
		Blob blob = result->getBlob(3);

		if (effectID == LEECH_EFFECT_ID)
			interpreter_ = new EffectLeechInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ENERGY_DESTABILIZATION_NEW_EFFECT_ID)
			interpreter_ = new EffectEnergyDestabilizationNewInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ENERGY_TRANSFER_EFFECT_ID)
			interpreter_ = new EffectEnergyTransferInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ARMOR_REPAIR_EFFECT_ID)
			interpreter_ = new EffectArmorRepairInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == TARGET_ARMOR_REPAIR_EFFECT_ID)
			interpreter_ = new EffectArmorRepairInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == STRUCTURE_REPAIR_EFFECT_ID)
			interpreter_ = new EffectHullRepairInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == REMOTE_HULL_REPAIR_EFFECT_ID)
			interpreter_ = new EffectHullRepairInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == SHIELD_BOOSTING_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == SHIELD_TRANSFER_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == SLOT_MODIFIER_EFFECT_ID)
			interpreter_ = new EffectSlotModifierInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == HARD_POINT_MODIFIER_EFFECT_EFFECT_ID)
			interpreter_ = new EffectHardPointModifierEffectInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ADAPTIVE_ARMOR_HARDENER_EFFECT_ID)
			interpreter_ = new EffectAdaptiveArmorHardener(engine, isAssistance, isOffensive);
		else if (effectID == FUELED_SHIELD_BOOSTING_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
		else
			interpreter_ = new EffectByteCodeInterpreter(engine, reinterpret_cast<const Byte*>(blob.getMemory()), blob.getSize(), isAssistance, isOffensive);

#if _DEBUG
		effectName_ = result->getText(4);
		std::string::iterator i, end = effectName_.end();
		for (i = effectName_.begin(); i != end; i++)
		{
			char c = *i;
			if (!((c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
				*i = ' ';
		}
#endif
	}
}

Effect::Effect(const Effect& from) : interpreter_(from.interpreter_->clone())
{
#if _DEBUG
	effectName_ = from.effectName_;
#endif
}

Effect::~Effect(void)
{
	Engine::ScopedLock lock(*engine_);
	reusableEffects.erase(reusableEffects.find(effectID_));
	if (interpreter_)
		delete interpreter_;
}

bool Effect::addEffect(Environment environment)
{
	return interpreter_->addEffect(environment);
}

bool Effect::removeEffect(Environment environment)
{
	return interpreter_->removeEffect(environment);
}

TypeID Effect::getEffectID() const
{
	return effectID_;
}

Effect::Category Effect::getCategory() const
{
	return category_;
}

#if _DEBUG
const char* Effect::getEffectName() const
{
	return effectName_.c_str();
}

std::ostream& eufe::operator<<(std::ostream& os, eufe::Effect& effect)
{
	os << "{\"effectName\":\"" << effect.effectName_<< "\", \"effectID\":\"" << effect.effectID_ << "\"}";
	return os;
}

#endif
<commit_msg>Cleanup<commit_after>#include "Effect.h"
#include <iostream>
#include <fstream>
#include <ios>
#include "Compiler.h"
#include "Ship.h"
#include "Module.h"
#include <cctype>
#include <algorithm>
#include "Item.h"
#include "Attribute.h"
#include "Engine.h"
#include "Character.h"

#include "Modifier.h"
#include "LocationGroupModifier.h"
#include "LocationRequiredSkillModifier.h"

#include "EffectByteCodeInterpreter.h"
#include "EffectLeechInterpreter.h"
#include "EffectEnergyDestabilizationNewInterpreter.h"
#include "EffectEnergyTransferInterpreter.h"
#include "EffectArmorRepairInterpreter.h"
#include "EffectHullRepairInterpreter.h"
#include "EffectShieldBoostingInterpreter.h"
#include "EffectSlotModifierInterpreter.h"
#include "EffectHardPointModifierEffectInterpreter.h"
#include "EffectAdaptiveArmorHardener.h"

#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>

using namespace eufe;

const TypeID eufe::ONLINE_EFFECT_ID = 16;
const TypeID eufe::LO_POWER_EFFECT_ID = 11;
const TypeID eufe::HI_POWER_EFFECT_ID = 12;
const TypeID eufe::MED_POWER_EFFECT_ID = 13;
const TypeID eufe::RIG_SLOT_EFFECT_ID = 2663;
const TypeID eufe::SUBSYSTEM_EFFECT_ID = 3772;
const TypeID eufe::TURRET_FITTED_EFFECT_ID = 42;
const TypeID eufe::LAUNCHER_FITTED_EFFECT_ID = 40;

const TypeID eufe::MINING_LASER_EFFECT_ID = 61;
const TypeID eufe::POWER_BOOSTER_EFFECT_ID = 48;
const TypeID eufe::PROJECTILE_FIRED_EFFECT_ID = 34;
const TypeID eufe::TARGET_ATTACK_EFFECT_ID = 10;
const TypeID eufe::USE_MISSILES_EFFECT_ID = 101;

const TypeID eufe::LEECH_EFFECT_ID = 3250;
const TypeID eufe::ENERGY_DESTABILIZATION_NEW_EFFECT_ID = 2303;
const TypeID eufe::ENERGY_TRANSFER_EFFECT_ID = 31;

const TypeID eufe::WARP_DISRUPTION_FIELD_EFFECT_ONLINE_EFFECT_ID = 3461;

const TypeID eufe::ARMOR_REPAIR_EFFECT_ID = 27;
const TypeID eufe::TARGET_ARMOR_REPAIR_EFFECT_ID = 592;
const TypeID eufe::SHIELD_BOOSTING_EFFECT_ID = 4;
const TypeID eufe::SHIELD_TRANSFER_EFFECT_ID = 18;
const TypeID eufe::STRUCTURE_REPAIR_EFFECT_ID = 26;
const TypeID eufe::REMOTE_HULL_REPAIR_EFFECT_ID = 3041;
const TypeID eufe::SLOT_MODIFIER_EFFECT_ID = 3774;
const TypeID eufe::HARD_POINT_MODIFIER_EFFECT_EFFECT_ID = 3773;

const TypeID eufe::ONLINE_FOR_STRUCTURES_EFFECT_ID = 901;

const TypeID eufe::ADAPTIVE_ARMOR_HARDENER_EFFECT_ID = 4928;
const TypeID eufe::FUELED_SHIELD_BOOSTING_EFFECT_ID = 4936;

static std::map<TypeID, boost::weak_ptr<eufe::Effect> > reusableEffects;

boost::shared_ptr<eufe::Effect> Effect::getEffect(Engine* engine, int effectID)
{
	Engine::ScopedLock lock(*engine);

	std::map<TypeID, boost::weak_ptr<eufe::Effect> >::iterator i, end = reusableEffects.end();
	i = reusableEffects.find(effectID);
	if (i == end) {
		boost::shared_ptr<Effect> effect(new Effect(engine, effectID));
		reusableEffects[effectID] = boost::weak_ptr<Effect>(effect);
		return effect;
	}
	else {
		return i->second.lock();
	}
}

#if _DEBUG
Effect::Effect(Engine* engine, TypeID effectID, Category category, const void* byteCode, size_t size, bool isAssistance, bool isOffensive, const char* effectName) : engine_(engine), effectID_(effectID), category_(category), effectName_(effectName)
#else
Effect::Effect(Engine* engine, TypeID effectID, Category category, const void* byteCode, size_t size, bool isAssistance, bool isOffensive) : engine_(engine), effectID_(effectID), category_(category)
#endif
{
	if (effectID == LEECH_EFFECT_ID)
		interpreter_ = new EffectLeechInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ENERGY_DESTABILIZATION_NEW_EFFECT_ID)
		interpreter_ = new EffectEnergyDestabilizationNewInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ENERGY_TRANSFER_EFFECT_ID)
		interpreter_ = new EffectEnergyTransferInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ARMOR_REPAIR_EFFECT_ID)
		interpreter_ = new EffectArmorRepairInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == TARGET_ARMOR_REPAIR_EFFECT_ID)
		interpreter_ = new EffectArmorRepairInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == STRUCTURE_REPAIR_EFFECT_ID)
		interpreter_ = new EffectHullRepairInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == REMOTE_HULL_REPAIR_EFFECT_ID)
		interpreter_ = new EffectHullRepairInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == SHIELD_BOOSTING_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
	else if (effectID == SHIELD_TRANSFER_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, true, isAssistance, isOffensive);
	else if (effectID == SLOT_MODIFIER_EFFECT_ID)
		interpreter_ = new EffectSlotModifierInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == HARD_POINT_MODIFIER_EFFECT_EFFECT_ID)
		interpreter_ = new EffectHardPointModifierEffectInterpreter(engine, isAssistance, isOffensive);
	else if (effectID == ADAPTIVE_ARMOR_HARDENER_EFFECT_ID)
		interpreter_ = new EffectAdaptiveArmorHardener(engine, isAssistance, isOffensive);
	else if (effectID == FUELED_SHIELD_BOOSTING_EFFECT_ID)
		interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
	else
		interpreter_ = new EffectByteCodeInterpreter(engine, byteCode, size, isAssistance, isOffensive);
#if _DEBUG
	std::string::iterator i, end = effectName_.end();
	for (i = effectName_.begin(); i != end; i++)
	{
		char c = *i;
		if (!((c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
			*i = ' ';
	}
#endif
}

Effect::Effect(Engine* engine, TypeID effectID) : engine_(engine), effectID_(effectID)
{
	Engine::ScopedLock lock(*engine_);

	std::stringstream sql;
#if _DEBUG
	sql << "SELECT effectCategory, isOffensive, isAssistance, byteCode, effectName FROM dgmCompiledEffects WHERE effectID = " << effectID;
#else
	sql << "SELECT effectCategory, isOffensive, isAssistance, byteCode FROM dgmCompiledEffects WHERE effectID = " << effectID;
#endif

	boost::shared_ptr<FetchResult> result = engine_->getSqlConnector()->exec(sql.str().c_str());

	if (result->next())
	{
		category_ = static_cast<Effect::Category>(result->getInt(0));
		bool isAssistance = result->getInt(1) != 0;
		bool isOffensive = result->getInt(2) != 0;
		Blob blob = result->getBlob(3);

		if (effectID == LEECH_EFFECT_ID)
			interpreter_ = new EffectLeechInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ENERGY_DESTABILIZATION_NEW_EFFECT_ID)
			interpreter_ = new EffectEnergyDestabilizationNewInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ENERGY_TRANSFER_EFFECT_ID)
			interpreter_ = new EffectEnergyTransferInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ARMOR_REPAIR_EFFECT_ID)
			interpreter_ = new EffectArmorRepairInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == TARGET_ARMOR_REPAIR_EFFECT_ID)
			interpreter_ = new EffectArmorRepairInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == STRUCTURE_REPAIR_EFFECT_ID)
			interpreter_ = new EffectHullRepairInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == REMOTE_HULL_REPAIR_EFFECT_ID)
			interpreter_ = new EffectHullRepairInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == SHIELD_BOOSTING_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
		else if (effectID == SHIELD_TRANSFER_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, true, isAssistance, isOffensive);
		else if (effectID == SLOT_MODIFIER_EFFECT_ID)
			interpreter_ = new EffectSlotModifierInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == HARD_POINT_MODIFIER_EFFECT_EFFECT_ID)
			interpreter_ = new EffectHardPointModifierEffectInterpreter(engine, isAssistance, isOffensive);
		else if (effectID == ADAPTIVE_ARMOR_HARDENER_EFFECT_ID)
			interpreter_ = new EffectAdaptiveArmorHardener(engine, isAssistance, isOffensive);
		else if (effectID == FUELED_SHIELD_BOOSTING_EFFECT_ID)
			interpreter_ = new EffectShieldBoostingInterpreter(engine, false, isAssistance, isOffensive);
		else
			interpreter_ = new EffectByteCodeInterpreter(engine, reinterpret_cast<const Byte*>(blob.getMemory()), blob.getSize(), isAssistance, isOffensive);

#if _DEBUG
		effectName_ = result->getText(4);
		std::string::iterator i, end = effectName_.end();
		for (i = effectName_.begin(); i != end; i++)
		{
			char c = *i;
			if (!((c >= 'a' && c <='z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
				*i = ' ';
		}
#endif
	}
}

Effect::Effect(const Effect& from) : interpreter_(from.interpreter_->clone())
{
#if _DEBUG
	effectName_ = from.effectName_;
#endif
}

Effect::~Effect(void)
{
	Engine::ScopedLock lock(*engine_);
	reusableEffects.erase(reusableEffects.find(effectID_));
	if (interpreter_)
		delete interpreter_;
}

bool Effect::addEffect(Environment environment)
{
	return interpreter_->addEffect(environment);
}

bool Effect::removeEffect(Environment environment)
{
	return interpreter_->removeEffect(environment);
}

TypeID Effect::getEffectID() const
{
	return effectID_;
}

Effect::Category Effect::getCategory() const
{
	return category_;
}

#if _DEBUG
const char* Effect::getEffectName() const
{
	return effectName_.c_str();
}

std::ostream& eufe::operator<<(std::ostream& os, eufe::Effect& effect)
{
	os << "{\"effectName\":\"" << effect.effectName_<< "\", \"effectID\":\"" << effect.effectID_ << "\"}";
	return os;
}

#endif
<|endoftext|>


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

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/segmentation/min_cut_segmentation.h>
#include <pcl/segmentation/impl/min_cut_segmentation.hpp>

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

#include <boost/version.hpp>
#if BOOST_VERSION > 103999

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/segmentation/min_cut_segmentation.h>
#include <pcl/segmentation/impl/min_cut_segmentation.hpp>

// Instantiations of specific point types
PCL_INSTANTIATE(MinCutSegmentation, PCL_XYZ_POINT_TYPES)

#endif
<|endoftext|>


<commit_before>/*
 *  RudeSkinnedMesh.cpp
 *
 *  Bork3D Game Engine
 *  Copyright (c) 2009 Bork 3D LLC. All rights reserved.
 *
 */

#include "RudeSkinnedMesh.h"

#include "RudeDebug.h"
#include "RudeGL.h"
#include "RudeFile.h"
#include "RudePerf.h"
#include "RudeTextureManager.h"
#include "RudeTweaker.h"

bool gDebugAnim = false;
RUDE_TWEAK(DebugAnim, kBool, gDebugAnim);

float gDebugAnimFrame = 0;
RUDE_TWEAK(DebugAnimFrame, kFloat, gDebugAnimFrame);

RudeSkinnedMesh::RudeSkinnedMesh(RudeObject *owner)
: RudeMesh(owner)
, m_frame(0.0f)
, m_fps(24.0f)
, m_toFrame(0.0f)
, m_animateTo(false)
{
}

RudeSkinnedMesh::~RudeSkinnedMesh()
{
}

int RudeSkinnedMesh::Load(const char *name)
{
	RUDE_REPORT("RudeSkinnedMesh::Load %s\n", name);

	if(RudeMesh::Load(name))
		return -1;

	for(unsigned int i = 0; i < m_model.nNumMesh; i++)
	{
		SPODMesh *mesh = &m_model.pMesh[i];

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int offset = mesh->sBoneBatches.pnBatchOffset[b];
			int end = mesh->sBoneBatches.pnBatchOffset[b+1];

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces;

			int numfaces = (end - offset);

			RUDE_REPORT("  Mesh %d-%d: %d tris\n", i, b, numfaces);
		}

		RUDE_ASSERT(mesh->sBoneIdx.eType == EPODDataUnsignedByte, "Bone indices must be unsigned byte");
		RUDE_ASSERT(mesh->sBoneWeight.eType == EPODDataFloat, "Bone weight must be float");
		RUDE_ASSERT(mesh->sVertex.eType == EPODDataFloat, "Mesh verts should be float");
	}

	//GLhandleARB g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );

	return 0;

}

void RudeSkinnedMesh::SetFrame(float f)
{
	m_animateTo = false;
	m_frame = f;
}

void RudeSkinnedMesh::AnimateTo(float f)
{
	m_animateTo = true;
	m_toFrame = f;
}

void RudeSkinnedMesh::NextFrame(float delta)
{

	if(m_animateTo)
	{
		if(m_toFrame > m_frame)
		{
			m_frame += delta * m_fps;

			if(m_frame > m_toFrame)
			{
				m_frame = m_toFrame;
				m_animateTo = false;
			}
		}
		else
		{
			m_frame -= delta * m_fps;

			if(m_frame < m_toFrame)
			{
				m_frame = m_toFrame;
				m_animateTo = false;
			}
		}

	}

	m_model.SetFrame(m_frame);

	if(gDebugAnim)
		m_model.SetFrame(gDebugAnimFrame);
}

void RudeSkinnedMesh::Render()
{
	RUDE_PERF_START(kPerfRudeSkinMeshRender);

#ifdef RUDE_PALETTE_MATRIX_SKIN

	glMatrixMode(GL_MODELVIEW);
	PVRTMATRIX viewmat;
	glGetFloatv(GL_MODELVIEW_MATRIX, viewmat.f);

	RGL.Enable(kBackfaceCull, true);

	glCullFace(GL_FRONT);
	glFrontFace(GL_CW);

	RGL.EnableClient(kVertexArray, true);
	RGL.EnableClient(kTextureCoordArray, true);

	if(m_animate)
	{
		glEnable(GL_MATRIX_PALETTE_OES);
		glEnableClientState(GL_MATRIX_INDEX_ARRAY_OES);
		glEnableClientState(GL_WEIGHT_ARRAY_OES);
	}

	for(int i = 0; i < m_model.nNumNode; i++)
	{
		SPODNode *node = &m_model.pNode[i];

		if(!node->pszName)
			continue;
		if(node->pszName[0] != 'M')
			continue;

		SPODMaterial *material = &m_model.pMaterial[node->nIdxMaterial];
		SPODMesh *mesh = &m_model.pMesh[node->nIdx];

		if(m_animate)
		{
			glMatrixIndexPointerOES(mesh->sBoneIdx.n, GL_UNSIGNED_BYTE, mesh->sBoneIdx.nStride, mesh->pInterleaved + (long) mesh->sBoneIdx.pData);
			glWeightPointerOES(mesh->sBoneWeight.n, GL_FLOAT, mesh->sBoneWeight.nStride, mesh->pInterleaved + (long) mesh->sBoneWeight.pData);
		}

		int textureid = material->nIdxTexDiffuse;
		if(textureid >= 0)
			RudeTextureManager::GetInstance()->SetTexture(m_textures[textureid]);

		unsigned short *indices	= (unsigned short*) mesh->sFaces.pData;

		glVertexPointer(3, GL_FLOAT, mesh->sVertex.nStride, mesh->pInterleaved + (long)mesh->sVertex.pData);

		glTexCoordPointer(2, GL_FLOAT, mesh->psUVW->nStride, mesh->pInterleaved + (long)mesh->psUVW->pData);

		if((mesh->sVtxColours.n > 0) && (mesh->sVtxColours.eType == EPODDataRGBA))
		{
			RGL.EnableClient(kColorArray, true);
			glColorPointer(4, GL_UNSIGNED_BYTE, mesh->sVtxColours.nStride, mesh->pInterleaved + (long)mesh->sVtxColours.pData);
		}
		else
			RGL.EnableClient(kColorArray, false);

		int totalbatchcnt = 0;

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int batchcnt = mesh->sBoneBatches.pnBatchBoneCnt[b];

			if(m_animate)
			{
				glMatrixMode(GL_MATRIX_PALETTE_OES);

				for(int j = 0; j < batchcnt; ++j)
				{
					glCurrentPaletteMatrixOES(j);

					// Generates the world matrix for the given bone in this batch.
					PVRTMATRIX	mBoneWorld;
					int i32NodeID = mesh->sBoneBatches.pnBatches[j + totalbatchcnt];
					m_model.GetBoneWorldMatrix(mBoneWorld, *node, m_model.pNode[i32NodeID]);

					// Multiply the bone's world matrix by the view matrix to put it in view space
					PVRTMatrixMultiply(mBoneWorld, mBoneWorld, viewmat);

					// Load the bone matrix into the current palette matrix.
					glLoadMatrixf(mBoneWorld.f);
				}
			}

			totalbatchcnt += batchcnt;

			int offset = mesh->sBoneBatches.pnBatchOffset[b] * 3;
			int end = mesh->sBoneBatches.pnBatchOffset[b+1] * 3;

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces*3;

			int numidx = (end - offset);

			glDrawElements(GL_TRIANGLES, numidx, GL_UNSIGNED_SHORT, &indices[offset]);
		}

	}

	glDisable(GL_MATRIX_PALETTE_OES);
	glDisableClientState(GL_MATRIX_INDEX_ARRAY_OES);
	glDisableClientState(GL_WEIGHT_ARRAY_OES);

#endif // RUDE_PALETTE_MATRIX_SKIN

#ifdef RUDE_SOFTWARE_SKIN

	glMatrixMode(GL_MODELVIEW);
	PVRTMATRIX viewmat;
	glGetFloatv(GL_MODELVIEW_MATRIX, viewmat.f);

	RGL.Enable(kBackfaceCull, true);

	glCullFace(GL_FRONT);
	glFrontFace(GL_CW);

	RGL.EnableClient(kVertexArray, true);
	RGL.EnableClient(kTextureCoordArray, true);

	for(unsigned int i = 0; i < m_model.nNumNode; i++)
	{
		SPODNode *node = &m_model.pNode[i];

		if(!node->pszName)
			continue;
		if(node->pszName[0] != 'M')
			continue;

		SPODMaterial *material = &m_model.pMaterial[node->nIdxMaterial];
		SPODMesh *mesh = &m_model.pMesh[node->nIdx];

		int textureid = material->nIdxTexDiffuse;
		if(textureid >= 0)
			RudeTextureManager::GetInstance()->SetTexture(m_textures[textureid]);

		unsigned short *indices	= (unsigned short*) mesh->sFaces.pData;

		if((mesh->sVtxColours.n > 0) && (mesh->sVtxColours.eType == EPODDataRGBA))
		{
			RGL.EnableClient(kColorArray, true);
			glColorPointer(4, GL_UNSIGNED_BYTE, mesh->sVtxColours.nStride, mesh->pInterleaved + (long)mesh->sVtxColours.pData);
		}
		else
		{
			RGL.EnableClient(kColorArray, false);
			glColor4f(1.0, 1.0, 1.0, 1.0);
		}

		int totalbatchcnt = 0;

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int batchcnt = mesh->sBoneBatches.pnBatchBoneCnt[b];

			btTransform boneworldbt[9];

			if(m_animate)
			{
				for(int j = 0; j < batchcnt; ++j)
				{
					// Get the world matrix for the given bone in this batch.

					PVRTMATRIX	boneworld;
					int i32NodeID = mesh->sBoneBatches.pnBatches[j + totalbatchcnt];
					m_model.GetBoneWorldMatrix(boneworld, *node, m_model.pNode[i32NodeID]);

					boneworldbt[j].setFromOpenGLMatrix(boneworld.f);
				}
			}

			totalbatchcnt += batchcnt;

			int offset = mesh->sBoneBatches.pnBatchOffset[b] * 3;
			int end = mesh->sBoneBatches.pnBatchOffset[b+1] * 3;

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces*3;

			for(int v = offset; v < end; v += 3)
			{
				float verts[3][3] = { 0.0 };
				float uvs[3][2] = { 0.0 };

				for(int a = 0; a < 3; a++)
				{
					float *meshverts = (float*) (mesh->pInterleaved + (long)mesh->sVertex.pData + mesh->sVertex.nStride * indices[v+a]);
					float *meshuvs = (float*) (mesh->pInterleaved + (long)mesh->psUVW->pData + mesh->psUVW->nStride * indices[v+a]);
					float *meshweights = (float *) (mesh->pInterleaved + (long)mesh->sBoneWeight.pData + mesh->sBoneWeight.nStride * indices[v+a]);
					unsigned char *meshbones = (unsigned char *) (mesh->pInterleaved + (long)mesh->sBoneIdx.pData + mesh->sBoneIdx.nStride * indices[v+a]);

					btVector3 temppos(0,0,0);

					uvs[a][0] = meshuvs[0];
					uvs[a][1] = meshuvs[1];

					for(unsigned int w = 0; w < mesh->sBoneWeight.n; w++)
					{
						float weight = meshweights[w];
						unsigned char boneidx = meshbones[w];

						if(weight < 0.00001f)
							continue;

						btVector3 p(meshverts[0], meshverts[1], meshverts[2]);
						p = boneworldbt[boneidx] * p;
						p = p * weight;
						temppos += p;
					}

					verts[a][0] = temppos[0];
					verts[a][1] = temppos[1];
					verts[a][2] = temppos[2];
				}

				glVertexPointer(3, GL_FLOAT, 0, verts);
				glTexCoordPointer(2, GL_FLOAT, 0, uvs);

				glDrawArrays(GL_TRIANGLES, 0, 3);
			}
		}

	}

#endif // RUDE_SOFTWARE_SKIN

	RUDE_PERF_STOP(kPerfRudeSkinMeshRender);
}
<commit_msg>Fix for software skin renderer bug when rendering m_animate=false, need to init bone mat to identity<commit_after>/*
 *  RudeSkinnedMesh.cpp
 *
 *  Bork3D Game Engine
 *  Copyright (c) 2009 Bork 3D LLC. All rights reserved.
 *
 */

#include "RudeSkinnedMesh.h"

#include "RudeDebug.h"
#include "RudeGL.h"
#include "RudeFile.h"
#include "RudePerf.h"
#include "RudeTextureManager.h"
#include "RudeTweaker.h"

bool gDebugAnim = false;
RUDE_TWEAK(DebugAnim, kBool, gDebugAnim);

float gDebugAnimFrame = 0;
RUDE_TWEAK(DebugAnimFrame, kFloat, gDebugAnimFrame);

RudeSkinnedMesh::RudeSkinnedMesh(RudeObject *owner)
: RudeMesh(owner)
, m_frame(0.0f)
, m_fps(24.0f)
, m_toFrame(0.0f)
, m_animateTo(false)
{
}

RudeSkinnedMesh::~RudeSkinnedMesh()
{
}

int RudeSkinnedMesh::Load(const char *name)
{
	RUDE_REPORT("RudeSkinnedMesh::Load %s\n", name);

	if(RudeMesh::Load(name))
		return -1;

	for(unsigned int i = 0; i < m_model.nNumMesh; i++)
	{
		SPODMesh *mesh = &m_model.pMesh[i];

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int offset = mesh->sBoneBatches.pnBatchOffset[b];
			int end = mesh->sBoneBatches.pnBatchOffset[b+1];

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces;

			int numfaces = (end - offset);

			RUDE_REPORT("  Mesh %d-%d: %d tris\n", i, b, numfaces);
		}

		RUDE_ASSERT(mesh->sBoneIdx.eType == EPODDataUnsignedByte, "Bone indices must be unsigned byte");
		RUDE_ASSERT(mesh->sBoneWeight.eType == EPODDataFloat, "Bone weight must be float");
		RUDE_ASSERT(mesh->sVertex.eType == EPODDataFloat, "Mesh verts should be float");
	}

	//GLhandleARB g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );

	return 0;

}

void RudeSkinnedMesh::SetFrame(float f)
{
	m_animateTo = false;
	m_frame = f;
}

void RudeSkinnedMesh::AnimateTo(float f)
{
	m_animateTo = true;
	m_toFrame = f;
}

void RudeSkinnedMesh::NextFrame(float delta)
{

	if(m_animateTo)
	{
		if(m_toFrame > m_frame)
		{
			m_frame += delta * m_fps;

			if(m_frame > m_toFrame)
			{
				m_frame = m_toFrame;
				m_animateTo = false;
			}
		}
		else
		{
			m_frame -= delta * m_fps;

			if(m_frame < m_toFrame)
			{
				m_frame = m_toFrame;
				m_animateTo = false;
			}
		}

	}

	m_model.SetFrame(m_frame);

	if(gDebugAnim)
		m_model.SetFrame(gDebugAnimFrame);
}

void RudeSkinnedMesh::Render()
{
	RUDE_PERF_START(kPerfRudeSkinMeshRender);

#ifdef RUDE_PALETTE_MATRIX_SKIN

	glMatrixMode(GL_MODELVIEW);
	PVRTMATRIX viewmat;
	glGetFloatv(GL_MODELVIEW_MATRIX, viewmat.f);

	RGL.Enable(kBackfaceCull, true);

	glCullFace(GL_FRONT);
	glFrontFace(GL_CW);

	RGL.EnableClient(kVertexArray, true);
	RGL.EnableClient(kTextureCoordArray, true);

	if(m_animate)
	{
		glEnable(GL_MATRIX_PALETTE_OES);
		glEnableClientState(GL_MATRIX_INDEX_ARRAY_OES);
		glEnableClientState(GL_WEIGHT_ARRAY_OES);
	}

	for(int i = 0; i < m_model.nNumNode; i++)
	{
		SPODNode *node = &m_model.pNode[i];

		if(!node->pszName)
			continue;
		if(node->pszName[0] != 'M')
			continue;

		SPODMaterial *material = &m_model.pMaterial[node->nIdxMaterial];
		SPODMesh *mesh = &m_model.pMesh[node->nIdx];

		if(m_animate)
		{
			glMatrixIndexPointerOES(mesh->sBoneIdx.n, GL_UNSIGNED_BYTE, mesh->sBoneIdx.nStride, mesh->pInterleaved + (long) mesh->sBoneIdx.pData);
			glWeightPointerOES(mesh->sBoneWeight.n, GL_FLOAT, mesh->sBoneWeight.nStride, mesh->pInterleaved + (long) mesh->sBoneWeight.pData);
		}

		int textureid = material->nIdxTexDiffuse;
		if(textureid >= 0)
			RudeTextureManager::GetInstance()->SetTexture(m_textures[textureid]);

		unsigned short *indices	= (unsigned short*) mesh->sFaces.pData;

		glVertexPointer(3, GL_FLOAT, mesh->sVertex.nStride, mesh->pInterleaved + (long)mesh->sVertex.pData);

		glTexCoordPointer(2, GL_FLOAT, mesh->psUVW->nStride, mesh->pInterleaved + (long)mesh->psUVW->pData);

		if((mesh->sVtxColours.n > 0) && (mesh->sVtxColours.eType == EPODDataRGBA))
		{
			RGL.EnableClient(kColorArray, true);
			glColorPointer(4, GL_UNSIGNED_BYTE, mesh->sVtxColours.nStride, mesh->pInterleaved + (long)mesh->sVtxColours.pData);
		}
		else
			RGL.EnableClient(kColorArray, false);

		int totalbatchcnt = 0;

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int batchcnt = mesh->sBoneBatches.pnBatchBoneCnt[b];

			if(m_animate)
			{
				glMatrixMode(GL_MATRIX_PALETTE_OES);

				for(int j = 0; j < batchcnt; ++j)
				{
					glCurrentPaletteMatrixOES(j);

					// Generates the world matrix for the given bone in this batch.
					PVRTMATRIX	mBoneWorld;
					int i32NodeID = mesh->sBoneBatches.pnBatches[j + totalbatchcnt];
					m_model.GetBoneWorldMatrix(mBoneWorld, *node, m_model.pNode[i32NodeID]);

					// Multiply the bone's world matrix by the view matrix to put it in view space
					PVRTMatrixMultiply(mBoneWorld, mBoneWorld, viewmat);

					// Load the bone matrix into the current palette matrix.
					glLoadMatrixf(mBoneWorld.f);
				}
			}

			totalbatchcnt += batchcnt;

			int offset = mesh->sBoneBatches.pnBatchOffset[b] * 3;
			int end = mesh->sBoneBatches.pnBatchOffset[b+1] * 3;

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces*3;

			int numidx = (end - offset);

			glDrawElements(GL_TRIANGLES, numidx, GL_UNSIGNED_SHORT, &indices[offset]);
		}

	}

	glDisable(GL_MATRIX_PALETTE_OES);
	glDisableClientState(GL_MATRIX_INDEX_ARRAY_OES);
	glDisableClientState(GL_WEIGHT_ARRAY_OES);

#endif // RUDE_PALETTE_MATRIX_SKIN

#ifdef RUDE_SOFTWARE_SKIN

	glMatrixMode(GL_MODELVIEW);
	PVRTMATRIX viewmat;
	glGetFloatv(GL_MODELVIEW_MATRIX, viewmat.f);

	RGL.Enable(kBackfaceCull, true);

	glCullFace(GL_FRONT);
	glFrontFace(GL_CW);

	RGL.EnableClient(kVertexArray, true);
	RGL.EnableClient(kTextureCoordArray, true);

	for(unsigned int i = 0; i < m_model.nNumNode; i++)
	{
		SPODNode *node = &m_model.pNode[i];

		if(!node->pszName)
			continue;
		if(node->pszName[0] != 'M')
			continue;

		SPODMaterial *material = &m_model.pMaterial[node->nIdxMaterial];
		SPODMesh *mesh = &m_model.pMesh[node->nIdx];

		int textureid = material->nIdxTexDiffuse;
		if(textureid >= 0)
			RudeTextureManager::GetInstance()->SetTexture(m_textures[textureid]);

		unsigned short *indices	= (unsigned short*) mesh->sFaces.pData;

		if((mesh->sVtxColours.n > 0) && (mesh->sVtxColours.eType == EPODDataRGBA))
		{
			RGL.EnableClient(kColorArray, true);
			glColorPointer(4, GL_UNSIGNED_BYTE, mesh->sVtxColours.nStride, mesh->pInterleaved + (long)mesh->sVtxColours.pData);
		}
		else
		{
			RGL.EnableClient(kColorArray, false);
			glColor4f(1.0, 1.0, 1.0, 1.0);
		}

		int totalbatchcnt = 0;

		for(int b = 0; b < mesh->sBoneBatches.nBatchCnt; b++)
		{
			int batchcnt = mesh->sBoneBatches.pnBatchBoneCnt[b];

			btTransform boneworldbt[9];

			if(m_animate)
			{
				for(int j = 0; j < batchcnt; ++j)
				{
					// Get the world matrix for the given bone in this batch.

					PVRTMATRIX	boneworld;
					int i32NodeID = mesh->sBoneBatches.pnBatches[j + totalbatchcnt];
					m_model.GetBoneWorldMatrix(boneworld, *node, m_model.pNode[i32NodeID]);

					boneworldbt[j].setFromOpenGLMatrix(boneworld.f);
				}
			}
            else
            {
                for(int j = 0; j < batchcnt; ++j)
				{
                    boneworldbt[j].setIdentity();
                }
            }

			totalbatchcnt += batchcnt;

			int offset = mesh->sBoneBatches.pnBatchOffset[b] * 3;
			int end = mesh->sBoneBatches.pnBatchOffset[b+1] * 3;

			if(b == (mesh->sBoneBatches.nBatchCnt - 1))
				end = mesh->nNumFaces*3;

			for(int v = offset; v < end; v += 3)
			{
				float verts[3][3] = { 0.0 };
				float uvs[3][2] = { 0.0 };

				for(int a = 0; a < 3; a++)
				{
					float *meshverts = (float*) (mesh->pInterleaved + (long)mesh->sVertex.pData + mesh->sVertex.nStride * indices[v+a]);
					float *meshuvs = (float*) (mesh->pInterleaved + (long)mesh->psUVW->pData + mesh->psUVW->nStride * indices[v+a]);
					float *meshweights = (float *) (mesh->pInterleaved + (long)mesh->sBoneWeight.pData + mesh->sBoneWeight.nStride * indices[v+a]);
					unsigned char *meshbones = (unsigned char *) (mesh->pInterleaved + (long)mesh->sBoneIdx.pData + mesh->sBoneIdx.nStride * indices[v+a]);

					btVector3 temppos(0,0,0);

					uvs[a][0] = meshuvs[0];
					uvs[a][1] = meshuvs[1];

					for(unsigned int w = 0; w < mesh->sBoneWeight.n; w++)
					{
						float weight = meshweights[w];
						unsigned char boneidx = meshbones[w];

						if(weight < 0.00001f)
							continue;

						btVector3 p(meshverts[0], meshverts[1], meshverts[2]);
						p = boneworldbt[boneidx] * p;
						p = p * weight;
						temppos += p;
					}

					verts[a][0] = temppos[0];
					verts[a][1] = temppos[1];
					verts[a][2] = temppos[2];
				}

				glVertexPointer(3, GL_FLOAT, 0, verts);
				glTexCoordPointer(2, GL_FLOAT, 0, uvs);

				glDrawArrays(GL_TRIANGLES, 0, 3);
			}
		}

	}

#endif // RUDE_SOFTWARE_SKIN

	RUDE_PERF_STOP(kPerfRudeSkinMeshRender);
}
<|endoftext|>


<commit_before>#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "GaussianModule.hpp"

using namespace std;
using namespace uipf;

/*

*/
void GaussianModule::run( DataManager& data) const
{
	using namespace cv;

	data.listParams();
	const Matrix::ptr oMatrix = data.getInputData<Matrix>("image");

	int nWindowSize = data.getParam<int>("windowSize",-1);
	double dSigma = data.getParam<double>("sigma",0.0);

	cv::Mat m = oMatrix->getContent();

	GaussianBlur(m,m,Size( nWindowSize, nWindowSize ), dSigma, dSigma );

	data.setOutputData("image",new Matrix(m));

}

MetaData GaussianModule::getMetaData() const
{
	map<string, DataDescription> input = {
		{"image", DataDescription(MATRIX, "the image to apply the filter on.") }
	};
	map<string, DataDescription> output = {
		{"image", DataDescription(MATRIX, "the result image.") }
	};
	map<string, ParamDescription> params = {
		{"windowSize", ParamDescription("window size of the kernel.") },
		{"sigma", ParamDescription("variance of the gaussian kernel.") }
	};

	return MetaData(
		"Applies Gaussian blurring to an image.",
		input,
		output,
		params
	);
}

<commit_msg>added comments to Gaussian module<commit_after>#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "GaussianModule.hpp"

using namespace std;
using namespace uipf;

// runs the module
/*
data	DataManager handles the input and ouput of this module
*/
void GaussianModule::run( DataManager& data) const
{
	using namespace cv;

	// print params for debugging
	data.listParams();

	// read the params (window size and sigma) given for this step
	int nWindowSize = data.getParam<int>("windowSize",-1);
	double dSigma = data.getParam<double>("sigma",0.0);

	// get a pointer to the "image" input data
	const Matrix::ptr oMatrix = data.getInputData<Matrix>("image");
	// get the actual opencv matrix of the input data
	Mat m = oMatrix->getContent();

	// do gaussian blur using opencv
	GaussianBlur(m,m,Size( nWindowSize, nWindowSize ), dSigma, dSigma );

	// set the result (output) on the datamanager
	data.setOutputData("image",new Matrix(m));

}

// returns the meta data of this module
MetaData GaussianModule::getMetaData() const
{
	map<string, DataDescription> input = {
		{"image", DataDescription(MATRIX, "the image to apply the filter on.") }
	};
	map<string, DataDescription> output = {
		{"image", DataDescription(MATRIX, "the result image.") }
	};
	map<string, ParamDescription> params = {
		{"windowSize", ParamDescription("window size of the kernel.") },
		{"sigma", ParamDescription("variance of the gaussian kernel.") }
	};

	return MetaData(
		"Applies Gaussian blurring to an image.",
		input,
		output,
		params
	);
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
    // FIXME: Use arg[0] as program name?
    std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{

    std::string input_file;
    bool opt_dissassemble = false;
    bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;

    for (int i = 1; i < argc; i++)
    {
        std::string option = argv[i];
        if (option == "-b")
            opt_show_bytes = true;
        else if (option == "-c")
            opt_compile = true;
        else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "-g")
			opt_dump_graph = true;
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
        else
        {
            opt_unknown = true;
            break;
        }
    }

    if (opt_unknown ||
        input_file.empty() ||
        (!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
    {
        show_usage();
        exit(1);
    }

    std::ifstream ifs(input_file);
    if (!ifs.is_open())
    {
        std::cerr << "cannot open file " << input_file << std::endl;
        exit(1);
    }

    std::string src((std::istreambuf_iterator<char>(ifs)),
		    (std::istreambuf_iterator<char>()));

    boost::algorithm::trim(src);

	using namespace dev;

    bytes bytecode = fromHex(src);

    if (opt_show_bytes)
    {
        std::cout << memDump(bytecode) << std::endl;
    }

    if (opt_dissassemble)
    {
        std::string assembly = eth::disassemble(bytecode);
        std::cout << assembly << std::endl;
    }

    if (opt_compile)
    {
    	auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});
		llvm::raw_os_ostream out(std::cout);
		module->print(out, nullptr);

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}
    }

	if (opt_interpret)
	{
		auto engine = eth::jit::ExecutionEngine();
		auto module = eth::jit::Compiler().compile({bytecode.data(), bytecode.size()});
		module->dump();
		u256 gas = 10000;
		auto result = engine.run(std::move(module), gas);
		return result;
	}

    return 0;
}
<commit_msg>minor changes in the compiler driver<commit_after>
#include <iostream>
#include <fstream>
#include <ostream>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <llvm/Support/raw_os_ostream.h>

#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libevmface/Instruction.h>
#include <libevmjit/Compiler.h>
#include <libevmjit/ExecutionEngine.h>

void show_usage()
{
    // FIXME: Use arg[0] as program name?
    std::cerr << "usage: evmcc (-b|-c|-d)+ <inputfile.bc>\n";
}

int main(int argc, char** argv)
{

    std::string input_file;
    bool opt_dissassemble = false;
    bool opt_show_bytes = false;
	bool opt_compile = false;
	bool opt_interpret = false;
	bool opt_dump_graph = false;
	bool opt_unknown = false;

    for (int i = 1; i < argc; i++)
    {
        std::string option = argv[i];
        if (option == "-b")
            opt_show_bytes = true;
        else if (option == "-c")
            opt_compile = true;
        else if (option == "-d")
			opt_dissassemble = true;
		else if (option == "-i")
			opt_interpret = true;
		else if (option == "-g")
			opt_dump_graph = true;
		else if (option[0] != '-' && input_file.empty())
			input_file = option;
        else
        {
            opt_unknown = true;
            break;
        }
    }

    if (opt_unknown ||
        input_file.empty() ||
        (!opt_show_bytes && !opt_compile && !opt_dissassemble && !opt_interpret))
    {
        show_usage();
        exit(1);
    }

    std::ifstream ifs(input_file);
    if (!ifs.is_open())
    {
        std::cerr << "cannot open file " << input_file << std::endl;
        exit(1);
    }

    std::string src((std::istreambuf_iterator<char>(ifs)),
		    (std::istreambuf_iterator<char>()));

    boost::algorithm::trim(src);

	using namespace dev;

    bytes bytecode = fromHex(src);

    if (opt_show_bytes)
    {
        std::cout << memDump(bytecode) << std::endl;
    }

    if (opt_dissassemble)
    {
        std::string assembly = eth::disassemble(bytecode);
        std::cout << assembly << std::endl;
    }

    if (opt_compile || opt_interpret)
    {
    	auto compiler = eth::jit::Compiler();
		auto module = compiler.compile({bytecode.data(), bytecode.size()});

		module->dump();

		if (opt_dump_graph)
		{
			std::ofstream ofs("blocks.dot");
			compiler.dumpBasicBlockGraph(ofs);
			ofs.close();
			std::cout << "Basic blocks graph written to block.dot\n";
		}

		if (opt_interpret)
		{
			auto engine = eth::jit::ExecutionEngine();
			u256 gas = 10000;
			auto result = engine.run(std::move(module), gas);
			return result;
		}
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, 2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __BASE_ADDR_RANGE_MAP_HH__
#define __BASE_ADDR_RANGE_MAP_HH__

#include <cstddef>
#include <functional>
#include <list>
#include <map>
#include <utility>

#include "base/addr_range.hh"
#include "base/types.hh"

/**
 * The AddrRangeMap uses an STL map to implement an interval tree for
 * address decoding. The value stored is a template type and can be
 * e.g. a port identifier, or a pointer.
 */
template <typename V, int max_cache_size=0>
class AddrRangeMap
{
  private:
    typedef std::map<AddrRange, V> RangeMap;

  public:
    typedef typename RangeMap::iterator iterator;
    typedef typename RangeMap::const_iterator const_iterator;

    /**
     * Find entry that contains the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address range. Returns end() if none found.
     *
     * @param r An input address range
     * @return An iterator that contains the input address range
     */
    const_iterator
    contains(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }
    iterator
    contains(const AddrRange &r)
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }

    /**
     * Find entry that contains the given address
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address. Returns end() if none found.
     *
     * @param r An input address
     * @return An iterator that contains the input address
     */
    const_iterator
    contains(Addr r) const
    {
        return contains(RangeSize(r, 1));
    }
    iterator
    contains(Addr r)
    {
        return contains(RangeSize(r, 1));
    }

    /**
     * Find entry that intersects with the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the first entry which range intersects with the
     * input address.
     *
     * @param r An input address
     * @return An iterator that intersects with the input address range
     */
    const_iterator
    intersects(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }
    iterator
    intersects(const AddrRange &r)
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }

    iterator
    insert(const AddrRange &r, const V& d)
    {
        if (intersects(r) != end())
            return tree.end();

        return tree.insert(std::make_pair(r, d)).first;
    }

    void
    erase(iterator p)
    {
        cache.remove(p);
        tree.erase(p);
    }

    void
    erase(iterator p, iterator q)
    {
        for (auto it = p; it != q; it++) {
            cache.remove(p);
        }
        tree.erase(p,q);
    }

    void
    clear()
    {
        cache.erase(cache.begin(), cache.end());
        tree.erase(tree.begin(), tree.end());
    }

    const_iterator
    begin() const
    {
        return tree.begin();
    }

    iterator
    begin()
    {
        return tree.begin();
    }

    const_iterator
    end() const
    {
        return tree.end();
    }

    iterator
    end()
    {
        return tree.end();
    }

    std::size_t
    size() const
    {
        return tree.size();
    }

    bool
    empty() const
    {
        return tree.empty();
    }

  private:
    /**
     * Add an address range map entry to the cache.
     *
     * @param it Iterator to the entry in the address range map
     */
    void
    addNewEntryToCache(iterator it) const
    {
        if (max_cache_size != 0) {
            // If there's a cache, add this element to it.
            if (cache.size() >= max_cache_size) {
                // If the cache is full, move the last element to the
                // front and overwrite it with the new value. This
                // avoids creating or destroying elements of the list.
                auto last = cache.end();
                last--;
                *last = it;
                if (max_cache_size > 1)
                    cache.splice(cache.begin(), cache, last);
            } else {
                cache.push_front(it);
            }
        }
    }

    /**
     * Find entry that satisfies a condition on an address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry that satisfies the input conidition on
     * the input address range. Returns end() if none found.
     *
     * @param r An input address range
     * @param f A condition on an address range
     * @return An iterator that contains the input address range
     */
    iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond)
    {
        // Check the cache first
        for (auto c = cache.begin(); c != cache.end(); c++) {
            auto it = *c;
            if (cond(it->first)) {
                // If this entry matches, promote it to the front
                // of the cache and return it.
                cache.splice(cache.begin(), cache, c);
                return it;
            }
        }

        iterator next = tree.upper_bound(r);
        if (next != end() && cond(next->first)) {
            addNewEntryToCache(next);
            return next;
        }
        if (next == begin())
            return end();
        next--;

        iterator i;
        do {
            i = next;
            if (cond(i->first)) {
                addNewEntryToCache(i);
                return i;
            }
            // Keep looking if the next range merges with the current one.
        } while (next != begin() &&
                 (--next)->first.mergesWith(i->first));

        return end();
    }

    const_iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
    {
        return const_cast<AddrRangeMap *>(this)->find(r, cond);
    }

    RangeMap tree;

    /**
     * A list of iterator that correspond to the max_cache_size most
     * recently used entries in the address range map. This mainly
     * used to optimize lookups. The elements in the list should
     * always be valid iterators of the tree.
     */
    mutable std::list<iterator> cache;
};

#endif //__BASE_ADDR_RANGE_MAP_HH__
<commit_msg>base: Tag API methods and variables in addr_range_map.hh<commit_after>/*
 * Copyright (c) 2012, 2018 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __BASE_ADDR_RANGE_MAP_HH__
#define __BASE_ADDR_RANGE_MAP_HH__

#include <cstddef>
#include <functional>
#include <list>
#include <map>
#include <utility>

#include "base/addr_range.hh"
#include "base/types.hh"

/**
 * The AddrRangeMap uses an STL map to implement an interval tree for
 * address decoding. The value stored is a template type and can be
 * e.g. a port identifier, or a pointer.
 */
template <typename V, int max_cache_size=0>
class AddrRangeMap
{
  private:
    typedef std::map<AddrRange, V> RangeMap;

  public:
    /**
     * @ingroup api_addr_range
     * @{
     */
    typedef typename RangeMap::iterator iterator;
    typedef typename RangeMap::const_iterator const_iterator;
    /** @} */ // end of api_addr_range

    /**
     * Find entry that contains the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address range. Returns end() if none found.
     *
     * @param r An input address range
     * @return An iterator that contains the input address range
     *
     * @ingroup api_addr_range
     * @{
     */
    const_iterator
    contains(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }
    iterator
    contains(const AddrRange &r)
    {
        return find(r, [r](const AddrRange r1) { return r.isSubset(r1); });
    }
    /** @} */ // end of api_addr_range

    /**
     * Find entry that contains the given address
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry which range is a superset of the input
     * address. Returns end() if none found.
     *
     * @param r An input address
     * @return An iterator that contains the input address
     *
     * @ingroup api_addr_range
     * @{
     */
    const_iterator
    contains(Addr r) const
    {
        return contains(RangeSize(r, 1));
    }
    iterator
    contains(Addr r)
    {
        return contains(RangeSize(r, 1));
    }
    /** @} */ // end of api_addr_range

    /**
     * Find entry that intersects with the given address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the first entry which range intersects with the
     * input address.
     *
     * @param r An input address
     * @return An iterator that intersects with the input address range
     *
     * @ingroup api_addr_range
     * @{
     */
    const_iterator
    intersects(const AddrRange &r) const
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }
    iterator
    intersects(const AddrRange &r)
    {
        return find(r, [r](const AddrRange r1) { return r.intersects(r1); });
    }
    /** @} */ // end of api_addr_range

    /**
     * @ingroup api_addr_range
     */
    iterator
    insert(const AddrRange &r, const V& d)
    {
        if (intersects(r) != end())
            return tree.end();

        return tree.insert(std::make_pair(r, d)).first;
    }

    /**
     * @ingroup api_addr_range
     */
    void
    erase(iterator p)
    {
        cache.remove(p);
        tree.erase(p);
    }

    /**
     * @ingroup api_addr_range
     */
    void
    erase(iterator p, iterator q)
    {
        for (auto it = p; it != q; it++) {
            cache.remove(p);
        }
        tree.erase(p,q);
    }

    /**
     * @ingroup api_addr_range
     */
    void
    clear()
    {
        cache.erase(cache.begin(), cache.end());
        tree.erase(tree.begin(), tree.end());
    }

    /**
     * @ingroup api_addr_range
     */
    const_iterator
    begin() const
    {
        return tree.begin();
    }

    /**
     * @ingroup api_addr_range
     */
    iterator
    begin()
    {
        return tree.begin();
    }

    /**
     * @ingroup api_addr_range
     */
    const_iterator
    end() const
    {
        return tree.end();
    }

    /**
     * @ingroup api_addr_range
     */
    iterator
    end()
    {
        return tree.end();
    }

    /**
     * @ingroup api_addr_range
     */
    std::size_t
    size() const
    {
        return tree.size();
    }

    /**
     * @ingroup api_addr_range
     */
    bool
    empty() const
    {
        return tree.empty();
    }

  private:
    /**
     * Add an address range map entry to the cache.
     *
     * @param it Iterator to the entry in the address range map
     */
    void
    addNewEntryToCache(iterator it) const
    {
        if (max_cache_size != 0) {
            // If there's a cache, add this element to it.
            if (cache.size() >= max_cache_size) {
                // If the cache is full, move the last element to the
                // front and overwrite it with the new value. This
                // avoids creating or destroying elements of the list.
                auto last = cache.end();
                last--;
                *last = it;
                if (max_cache_size > 1)
                    cache.splice(cache.begin(), cache, last);
            } else {
                cache.push_front(it);
            }
        }
    }

    /**
     * Find entry that satisfies a condition on an address range
     *
     * Searches through the ranges in the address map and returns an
     * iterator to the entry that satisfies the input conidition on
     * the input address range. Returns end() if none found.
     *
     * @param r An input address range
     * @param f A condition on an address range
     * @return An iterator that contains the input address range
     */
    iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond)
    {
        // Check the cache first
        for (auto c = cache.begin(); c != cache.end(); c++) {
            auto it = *c;
            if (cond(it->first)) {
                // If this entry matches, promote it to the front
                // of the cache and return it.
                cache.splice(cache.begin(), cache, c);
                return it;
            }
        }

        iterator next = tree.upper_bound(r);
        if (next != end() && cond(next->first)) {
            addNewEntryToCache(next);
            return next;
        }
        if (next == begin())
            return end();
        next--;

        iterator i;
        do {
            i = next;
            if (cond(i->first)) {
                addNewEntryToCache(i);
                return i;
            }
            // Keep looking if the next range merges with the current one.
        } while (next != begin() &&
                 (--next)->first.mergesWith(i->first));

        return end();
    }

    const_iterator
    find(const AddrRange &r, std::function<bool(const AddrRange)> cond) const
    {
        return const_cast<AddrRangeMap *>(this)->find(r, cond);
    }

    RangeMap tree;

    /**
     * A list of iterator that correspond to the max_cache_size most
     * recently used entries in the address range map. This mainly
     * used to optimize lookups. The elements in the list should
     * always be valid iterators of the tree.
     */
    mutable std::list<iterator> cache;
};

#endif //__BASE_ADDR_RANGE_MAP_HH__
<|endoftext|>