<commit_before>#ifndef SOLAIRE_DYNAMIC_ARRAY_HPP
#define SOLAIRE_DYNAMIC_ARRAY_HPP

//Copyright 2015 Adam Smith
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file ArrayList.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 11th January 2016
	Last Modified	: 11th January 2016
*/

#include <cstdint>
#include "Solaire/Core/Container.hpp"
#include "Solaire/Data/Iterators/ContiguousIterator.hpp"

namespace Solaire{

    enum : int32_t {
        DEFAULT_ARRAY_LIST_SIZE = 32
    };

    template<class TYPE, class INDEX = uint16_t>
	class ArrayList : public List<TYPE> {
	public:
		typedef TYPE Type;
		typedef const TYPE ConstType;
		typedef Type& Reference;
		typedef ConstType& ConstReference;
		typedef Type&& Move;
		typedef Type* Pointer;
		typedef ConstType* ConstPointer;
		typedef INDEX Index;
		typedef ArrayList<TYPE, INDEX> Self;
	private:
        Allocator* mAllocator;
		Index mHead;
		Index mSize;
		Type* mData;
    private:
        bool CopyTo(Type* const aArray) const throw() {
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                new(aArray + i) Type(mData[i]);
            }
            return true;
        }

        bool MoveTo(Type* const aArray) throw() {
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                new(aArray + i) Type(std::move(mData[i]));
                mData[i].~Type();
            }
            return true;
        }

        bool DestructAll() throw() {
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                mData[i].~Type();
            }
            return true;
        }

        bool ShiftUp(const int32_t aIndex) throw() {
            if(mHead + 1 >= mSize) Reallocate(mSize * 2);
            const int32_t head = mHead - 1;
            new(mHead) Type(std::move(mData[mHead - 1]));
            for(int32_t i = mHead; i >= aIndex; --i) {
                Type& high = mHead[i];
                Type& low = mHead[i - 1];
                high = std::move(low);
            }
            ++mHead;
            return true;
        }

        bool ShiftDown(const int32_t aIndex) throw() {
            const int32_t size = mHead - 1;
            for(int32_t i = mHead; i < size; ++i) {
                Type& high = mHead[i + 1];
                Type& low = mHead[i];
                low = std::move(high);
            }
            --mHead;
            mData[mHead].Type();
            return true;
        }

        bool Reallocate(const Index aSize) throw() {
            Type* const ptr = static_cast<Type*>(mAllocator->Allocate(sizeof(Type) * aSize));
            if(! MoveTo(ptr)) {
                mAllocator->Deallocate(ptr);
                return false;
            }
            mAllocator->Deallocate(mData);
            mData = ptr;
            mSize = aSize;
            return true;
        }
    protected:
        // Inherited from StaticContainer

        Pointer SOLAIRE_EXPORT_CALL GetPtr(int32_t aOffset) throw() override {
            return mData + aOffset;
        }

        SharedAllocation<Iterator<TYPE>> SOLAIRE_EXPORT_CALL Begin() throw() override {
            return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, 0);
        }

        SharedAllocation<Iterator<TYPE>> SOLAIRE_EXPORT_CALL End() throw() override {
            return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, mHead);
        }

        SharedAllocation<Iterator<TYPE>> SOLAIRE_EXPORT_CALL Rbegin() throw() override {
            //! \todo Implement reverse iterator
            return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, 0);
        }

        SharedAllocation<Iterator<TYPE>> SOLAIRE_EXPORT_CALL Rend() throw() override {
            //! \todo Implement reverse iterator
            return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, mHead);
        }

    public:
        ArrayList(Allocator& aAllocator) :
            mAllocator(&aAllocator),
            mHead(0),
            mSize(DEFAULT_ARRAY_LIST_SIZE),
            mData(static_cast<Type*>(aAllocator.Allocate(sizeof(Type) * DEFAULT_ARRAY_LIST_SIZE)))
        {}

        ArrayList(Allocator& aAllocator, const Index aSize) :
            mAllocator(&aAllocator),
            mHead(0),
            mSize(aSize),
            mData(static_cast<Type*>(aAllocator.Allocate(sizeof(Type) * aSize)))
        {}

        ArrayList(const Self& aOther) :
            mAllocator(aOther.mAllocator),
            mHead(aOther.mHead),
            mSize(aOther.mSize),
            mData(static_cast<Type*>(aOther.mAllocator->Allocate(sizeof(Type) * aOther.mSize)))
        {
            aOther.CopyTo(mData);
        }

        ArrayList(Self&& aOther) :
            mAllocator(aOther.mAllocator),
            mHead(aOther.mHead),
            mSize(aOther.mSize),
            mData(aOther.mData)
        {
            aOther.mData = nullptr;
        }

        SOLAIRE_EXPORT_CALL ~ArrayList() {
            if(mData != nullptr) {
                Clear();
                mAllocator->Deallocate(mData);
                mData = nullptr;
            }
        }

        Self& operator=(const Self& aOther) {
            if(mSize < aOther.mHead) {
                Reallocate(aOther.mHead);
            }

            DestructAll();
            aOther.CopyTo(mData);
            mHead = aOther.mHead;

            return *this;
        }

        Self& operator=(Self&& aOther) {
            std::swap(mAllocator, aOther.mAllocator);
            std::swap(mHead, aOther.mHead);
            std::swap(mSize, aOther.mSize);
            std::swap(mData, aOther.mData);
            return *this;
        }

        // Inherited from StaticContainer

        bool SOLAIRE_EXPORT_CALL IsContiguous() const throw() override {
            return true;
        }

        int32_t SOLAIRE_EXPORT_CALL Size() const throw() override {
            return static_cast<int32_t>(mHead);
        }

        Allocator& SOLAIRE_EXPORT_CALL GetAllocator() const throw() override {
            return *mAllocator;
        }

        // Inherited from Stack

		Type& SOLAIRE_EXPORT_CALL PushBack(const Type& aValue) throw() override {
		    if(mHead == mSize) {
                Reallocate(mSize * 2);
		    }
            return mData[mHead++] = aValue;
        }

		Type SOLAIRE_EXPORT_CALL PopBack() throw() {
		    --mHead;
		    Type& back = mData[mHead];
		    Type tmp = std::move(back);
		    back.~Type();
		    return tmp;
		}

		void SOLAIRE_EXPORT_CALL Clear() throw() override {
            DestructAll();
            mHead = 0;
        }

        // Inherited from Deque
		Type& SOLAIRE_EXPORT_CALL PushFront(const Type& aValue) throw() override {
            ShiftUp(0);
            new(mData) Type(aValue);
            return *mData;
		}

		Type SOLAIRE_EXPORT_CALL PopFront() throw() override {
		    Type& front = *mData;
            Type tmp = front;
            front.~Type();
            ShiftDown(0);
            return tmp;
		}

		// Inherited from List

		Type& SOLAIRE_EXPORT_CALL InsertBefore(const STLIterator<const Type> aPos, const Type& aValue) throw() override {
            const int32_t pos = aPos - List<Type>::begin();
            ShiftUp(pos);
            Type* const ptr = mData + pos;
            new(ptr) Type(aValue);
            return *ptr;
		}

		Type& SOLAIRE_EXPORT_CALL InsertAfter(const STLIterator<const Type> aPos, const Type& aValue) throw() override {
            return InsertBefore(aPos - 1, aValue);
		}

		bool SOLAIRE_EXPORT_CALL Erase(const STLIterator<const Type> aPos) throw() override {
		    const int32_t pos = aPos - List<Type>::begin();
            mData[pos].~Type();
            return ShiftDown(pos);
		}

	};
}

#endif
<commit_msg>Bugfixes to ArrayList<commit_after>#ifndef SOLAIRE_DYNAMIC_ARRAY_HPP
#define SOLAIRE_DYNAMIC_ARRAY_HPP

//Copyright 2015 Adam Smith
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : solairelibrary@mail.com
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file ArrayList.hpp
	\brief
	\author
	Created			: Adam Smith
	Last modified	: Adam Smith
	\date
	Created			: 11th January 2016
	Last Modified	: 11th January 2016
*/

#include <cstdint>
#include "Solaire/Core/Container.hpp"
#include "Solaire/Data/Iterators/ContiguousIterator.hpp"

namespace Solaire{

    enum : int32_t {
        DEFAULT_ARRAY_LIST_SIZE = 32
    };

    template<class TYPE, class INDEX = uint16_t>
	class ArrayList : public List<TYPE> {
	public:
		typedef TYPE Type;
		typedef const TYPE ConstType;
		typedef Type& Reference;
		typedef ConstType& ConstReference;
		typedef Type&& Move;
		typedef Type* Pointer;
		typedef ConstType* ConstPointer;
		typedef INDEX Index;
		typedef ArrayList<TYPE, INDEX> Self;
	private:
        Allocator* mAllocator;
		Index mHead;
		Index mSize;
		Type* mData;
    private:
        bool CopyTo(Type* const aArray) const throw() {
            //std::cout << "CopyTo" << std::endl;
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                new(aArray + i) Type(mData[i]);
            }
            return true;
        }

        bool MoveTo(Type* const aArray) throw() {
            //std::cout << "MoveTo" << std::endl;
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                new(aArray + i) Type(std::move(mData[i]));
                mData[i].~Type();
            }
            return true;
        }

        bool DestructAll() throw() {
            //std::cout << "DestructAll" << std::endl;
            const int32_t size = mHead;
            for(int32_t i = 0; i < size; ++i) {
                mData[i].~Type();
            }
            return true;
        }

        bool ShiftUp(const int32_t aIndex) throw() {
            //std::cout << "ShiftUp" << std::endl;
            // Create a new object at the end of the list
            PushBack(mData[mHead - 1]);

            // Shift up existing objects
            const int32_t head = mHead - 1;
            for(int32_t i = head; i > aIndex; --i) {
                Type& high = mData[i];
                Type& low = mData[i - 1];
                high = std::move(low);
            }

            return true;
        }

        bool ShiftDown(const int32_t aIndex) throw() {
            //std::cout << "ShiftDown" << std::endl;
            /*const int32_t size = mHead - 1;
            for(int32_t i = mHead; i < size; ++i) {
                Type& high = mHead[i + 1];
                Type& low = mHead[i];
                low = std::move(high);
            }
            --mHead;
            mData[mHead].Type();
            return true;*/
            return false;
        }

        bool Reallocate(const Index aSize) throw() {
            //std::cout << "Reallocate" << std::endl;
            Type* const ptr = static_cast<Type*>(mAllocator->Allocate(sizeof(Type) * aSize));
            if(! MoveTo(ptr)) {
                mAllocator->Deallocate(ptr);
                return false;
            }
            mAllocator->Deallocate(mData);
            mData = ptr;
            mSize = aSize;
            return true;
        }
    protected:
        // Inherited from StaticContainer

        Pointer SOLAIRE_EXPORT_CALL GetPtr(int32_t aOffset) throw() override {
            return mData + aOffset;
        }

        SharedAllocation<Iterator<Type>> SOLAIRE_EXPORT_CALL Begin() throw() override {
            //! \todo Implement iterator
            //return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, 0);
            return SharedAllocation<Iterator<Type>>();
        }

        SharedAllocation<Iterator<Type>> SOLAIRE_EXPORT_CALL End() throw() override {
            //! \todo Implement iterator
            //return mAllocator->SharedAllocate<ContiguousIterator>(*mAllocator, mData, mHead);
            return SharedAllocation<Iterator<Type>>();
        }

        SharedAllocation<Iterator<Type>> SOLAIRE_EXPORT_CALL Rbegin() throw() override {
            //! \todo Implement reverse iterator
            return SharedAllocation<Iterator<Type>>();
        }

        SharedAllocation<Iterator<Type>> SOLAIRE_EXPORT_CALL Rend() throw() override {
            //! \todo Implement reverse iterator
            return SharedAllocation<Iterator<Type>>();
        }

    public:
        ArrayList(Allocator& aAllocator) :
            mAllocator(&aAllocator),
            mHead(0),
            mSize(DEFAULT_ARRAY_LIST_SIZE),
            mData(static_cast<Type*>(aAllocator.Allocate(sizeof(Type) * DEFAULT_ARRAY_LIST_SIZE)))
        {}

        ArrayList(Allocator& aAllocator, const Index aSize) :
            mAllocator(&aAllocator),
            mHead(0),
            mSize(aSize),
            mData(static_cast<Type*>(aAllocator.Allocate(sizeof(Type) * aSize)))
        {}

        ArrayList(const Self& aOther) :
            mAllocator(aOther.mAllocator),
            mHead(aOther.mHead),
            mSize(aOther.mSize),
            mData(static_cast<Type*>(aOther.mAllocator->Allocate(sizeof(Type) * aOther.mSize)))
        {
            aOther.CopyTo(mData);
        }

        ArrayList(Self&& aOther) :
            mAllocator(aOther.mAllocator),
            mHead(aOther.mHead),
            mSize(aOther.mSize),
            mData(aOther.mData)
        {
            aOther.mData = nullptr;
        }

        SOLAIRE_EXPORT_CALL ~ArrayList() {
            if(mData != nullptr) {
                Clear();
                mAllocator->Deallocate(mData);
                mData = nullptr;
            }
        }

        Self& operator=(const Self& aOther) {
            if(mSize < aOther.mHead) {
                Reallocate(aOther.mHead);
            }

            DestructAll();
            aOther.CopyTo(mData);
            mHead = aOther.mHead;

            return *this;
        }

        Self& operator=(Self&& aOther) {
            std::swap(mAllocator, aOther.mAllocator);
            std::swap(mHead, aOther.mHead);
            std::swap(mSize, aOther.mSize);
            std::swap(mData, aOther.mData);
            return *this;
        }

        // Inherited from StaticContainer

        bool SOLAIRE_EXPORT_CALL IsContiguous() const throw() override {
            return true;
        }

        int32_t SOLAIRE_EXPORT_CALL Size() const throw() override {
            return static_cast<int32_t>(mHead);
        }

        Allocator& SOLAIRE_EXPORT_CALL GetAllocator() const throw() override {
            return *mAllocator;
        }

        // Inherited from Stack

		Type& SOLAIRE_EXPORT_CALL PushBack(const Type& aValue) throw() override {
            if(mHead == mSize) {
                Reallocate(mSize * 2);
		    }
		    Type* const ptr = mData + mHead;
		    ++mHead;
		    new(ptr) Type(aValue);
            return *ptr;
        }

		Type SOLAIRE_EXPORT_CALL PopBack() throw() {
		    --mHead;
		    Type& back = mData[mHead];
		    Type tmp = std::move(back);
		    back.~Type();
		    return tmp;
		}

		void SOLAIRE_EXPORT_CALL Clear() throw() override {
            DestructAll();
            mHead = 0;
        }

        // Inherited from Deque
		Type& SOLAIRE_EXPORT_CALL PushFront(const Type& aValue) throw() override {
		    if(mHead == 0) return PushBack(aValue);

            ShiftUp(0);
            new(mData) Type(aValue);
            return *mData;
		}

		Type SOLAIRE_EXPORT_CALL PopFront() throw() override {
		    Type& front = *mData;
            Type tmp = front;
            front.~Type();
            ShiftDown(0);
            return tmp;
		}

		// Inherited from List

		Type& SOLAIRE_EXPORT_CALL InsertBefore(const int32_t aPos, const Type& aValue) throw() override {
            ShiftUp(aPos);
            Type* const ptr = mData + aPos;
            new(ptr) Type(aValue);
            return *ptr;
		}

		Type& SOLAIRE_EXPORT_CALL InsertAfter(const int32_t aPos, const Type& aValue) throw() override {
            return InsertBefore(aPos - 1, aValue);
		}

		bool SOLAIRE_EXPORT_CALL Erase(const int32_t aPos) throw() override {
            mData[aPos].~Type();
            return ShiftDown(aPos);
		}

	};
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#ifndef ROSETTASTONE_ENTITY_HPP
#define ROSETTASTONE_ENTITY_HPP

#include <Rosetta/Cards/Card.hpp>
#include <Rosetta/Enchants/AuraEffects.hpp>
#include <Rosetta/Enums/TaskEnums.hpp>
#include <Rosetta/Zones/IZone.hpp>

#include <array>
#include <map>

namespace RosettaStone
{
class Card;
class Enchantment;
class Game;
class Player;

//!
//! \brief Abstract entity structure that stores card data.
//!
//! This structure is base structure of all data-holding/action-performing/
//! visible or invisible objects in a RosettaStone.
//! An entity is defined as a collection of properties, called GameTags.
//!
class Entity
{
 public:
    //! Default constructor.
    Entity() = default;

    //! Constructs entity with given \p _owner, \p _card and \p tags.
    //! \param _owner The owner of the card.
    //! \param _card The card.
    //! \param tags The game tags.
    Entity(Player& _owner, Card& _card, std::map<GameTag, int> tags);

    //! Destructor.
    virtual ~Entity();

    //! Copy constructor.
    Entity(const Entity& ent);

    //! Move constructor.
    Entity(Entity&& ent) noexcept;

    //! Copy assignment operator.
    Entity& operator=(const Entity& ent);

    //! Move assignment operator.
    Entity& operator=(Entity&& ent) noexcept;

    //! Returns a list of game tag.
    //! \return A list of game tag.
    std::map<GameTag, int> GetGameTags() const;

    //! Returns the value of game tag.
    //! \param tag The game tag of card.
    //! \return The value of game tag.
    int GetGameTag(GameTag tag) const;

    //! Sets game tag to the card.
    //! \param tag The game tag to indicate ability or condition.
    //! \param value The value to set for game tag.
    virtual void SetGameTag(GameTag tag, int value);

    //! Returns the value of zone type.
    //! \return The value of zone type.
    ZoneType GetZoneType() const;

    //! Sets the value of zone type.
    //! \param type The value of zone type.
    void SetZoneType(ZoneType type);

    //! Returns the value of zone position.
    //! \return The value of zone position.
    int GetZonePosition() const;

    //! Sets the value of zone position.
    //! \param value The value of zone position.
    void SetZonePosition(int value);

    //! Returns the value of cost.
    //! \return The value of cost.
    int GetCost() const;

    //! Sets the value of cost.
    //! \param cost The value of cost.
    void SetCost(int cost);

    //! Returns the value of exhausted.
    //! \return The value of exhausted.
    bool IsExhausted() const;

    //! Sets the value of exhausted.
    //! \param exhausted The value of exhausted.
    void SetExhausted(bool exhausted);

    //! Returns whether this entity has combo.
    //! \return Whether this entity has combo.
    bool HasCombo() const;

    //! Returns whether this entity has overload.
    //! \return Whether this entity has overload.
    bool HasOverload() const;

    //! Returns the value of overload.
    //! \return The value of overload.
    int GetOverload() const;

    //! Returns whether this entity has deathrattle power.
    //! \return Whether this entity has deathrattle power.
    bool HasDeathrattle() const;

    //! Returns whether this entity has to choose one.
    //! \return Whether this entity has to choose one.
    bool HasChooseOne() const;

    //! Resets all game tag values that where changed after creation.
    //! Any enchants and trigger is removed.
    virtual void Reset();

    //! Destroys entity.
    virtual void Destroy();

    //! Activates the task.
    //! \param type The type of power.
    //! \param target The target.
    //! \param chooseOne The index of chosen card from two cards.
    void ActivateTask(PowerType type, Entity* target = nullptr, int chooseOne = 0);

    //! Builds a new entity that can be added to a game.
    //! \param player An owner of the entity.
    //! \param card The card from which the entity must be derived.
    //! \param cardTags The tags preset of card for the entity.
    //! \param zone The zone in which the entity must spawn.
    //! \param id An entity ID to assign to the newly created entity.
    //! \return A pointer to entity that is allocated dynamically.
    static Entity* GetFromCard(
        Player& player, Card&& card,
        std::optional<std::map<GameTag, int>> cardTags = std::nullopt,
        IZone* zone = nullptr, int id = -1);

    Player* owner = nullptr;
    Card card;

    IZone* zone = nullptr;

    AuraEffects* auraEffects = nullptr;
    Aura* onGoingEffect = nullptr;
    Trigger* activatedTrigger = nullptr;

    std::array<Entity*, 2> chooseOneCard{};
    std::vector<Enchantment*> appliedEnchantments;

    int id = 0;
    int orderOfPlay = 0;

    bool isDestroyed = false;

 protected:
    std::map<GameTag, int> m_gameTags;

 private:
    //! Releases dynamic allocated resources.
    void FreeMemory();
};
}  // namespace RosettaStone

#endif  // ROSETTASTONE_ENTITY_HPP
<commit_msg>refactor: Change type of variable 'onGoingEffect' to 'IAura*'<commit_after>// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#ifndef ROSETTASTONE_ENTITY_HPP
#define ROSETTASTONE_ENTITY_HPP

#include <Rosetta/Cards/Card.hpp>
#include <Rosetta/Enchants/AuraEffects.hpp>
#include <Rosetta/Enums/TaskEnums.hpp>
#include <Rosetta/Zones/IZone.hpp>

#include <array>
#include <map>

namespace RosettaStone
{
class Card;
class Enchantment;
class Game;
class Player;

//!
//! \brief Abstract entity structure that stores card data.
//!
//! This structure is base structure of all data-holding/action-performing/
//! visible or invisible objects in a RosettaStone.
//! An entity is defined as a collection of properties, called GameTags.
//!
class Entity
{
 public:
    //! Default constructor.
    Entity() = default;

    //! Constructs entity with given \p _owner, \p _card and \p tags.
    //! \param _owner The owner of the card.
    //! \param _card The card.
    //! \param tags The game tags.
    Entity(Player& _owner, Card& _card, std::map<GameTag, int> tags);

    //! Destructor.
    virtual ~Entity();

    //! Copy constructor.
    Entity(const Entity& ent);

    //! Move constructor.
    Entity(Entity&& ent) noexcept;

    //! Copy assignment operator.
    Entity& operator=(const Entity& ent);

    //! Move assignment operator.
    Entity& operator=(Entity&& ent) noexcept;

    //! Returns a list of game tag.
    //! \return A list of game tag.
    std::map<GameTag, int> GetGameTags() const;

    //! Returns the value of game tag.
    //! \param tag The game tag of card.
    //! \return The value of game tag.
    int GetGameTag(GameTag tag) const;

    //! Sets game tag to the card.
    //! \param tag The game tag to indicate ability or condition.
    //! \param value The value to set for game tag.
    virtual void SetGameTag(GameTag tag, int value);

    //! Returns the value of zone type.
    //! \return The value of zone type.
    ZoneType GetZoneType() const;

    //! Sets the value of zone type.
    //! \param type The value of zone type.
    void SetZoneType(ZoneType type);

    //! Returns the value of zone position.
    //! \return The value of zone position.
    int GetZonePosition() const;

    //! Sets the value of zone position.
    //! \param value The value of zone position.
    void SetZonePosition(int value);

    //! Returns the value of cost.
    //! \return The value of cost.
    int GetCost() const;

    //! Sets the value of cost.
    //! \param cost The value of cost.
    void SetCost(int cost);

    //! Returns the value of exhausted.
    //! \return The value of exhausted.
    bool IsExhausted() const;

    //! Sets the value of exhausted.
    //! \param exhausted The value of exhausted.
    void SetExhausted(bool exhausted);

    //! Returns whether this entity has combo.
    //! \return Whether this entity has combo.
    bool HasCombo() const;

    //! Returns whether this entity has overload.
    //! \return Whether this entity has overload.
    bool HasOverload() const;

    //! Returns the value of overload.
    //! \return The value of overload.
    int GetOverload() const;

    //! Returns whether this entity has deathrattle power.
    //! \return Whether this entity has deathrattle power.
    bool HasDeathrattle() const;

    //! Returns whether this entity has to choose one.
    //! \return Whether this entity has to choose one.
    bool HasChooseOne() const;

    //! Resets all game tag values that where changed after creation.
    //! Any enchants and trigger is removed.
    virtual void Reset();

    //! Destroys entity.
    virtual void Destroy();

    //! Activates the task.
    //! \param type The type of power.
    //! \param target The target.
    //! \param chooseOne The index of chosen card from two cards.
    void ActivateTask(PowerType type, Entity* target = nullptr, int chooseOne = 0);

    //! Builds a new entity that can be added to a game.
    //! \param player An owner of the entity.
    //! \param card The card from which the entity must be derived.
    //! \param cardTags The tags preset of card for the entity.
    //! \param zone The zone in which the entity must spawn.
    //! \param id An entity ID to assign to the newly created entity.
    //! \return A pointer to entity that is allocated dynamically.
    static Entity* GetFromCard(
        Player& player, Card&& card,
        std::optional<std::map<GameTag, int>> cardTags = std::nullopt,
        IZone* zone = nullptr, int id = -1);

    Player* owner = nullptr;
    Card card;

    IZone* zone = nullptr;

    AuraEffects* auraEffects = nullptr;
    IAura* onGoingEffect = nullptr;
    Trigger* activatedTrigger = nullptr;

    std::array<Entity*, 2> chooseOneCard{};
    std::vector<Enchantment*> appliedEnchantments;

    int id = 0;
    int orderOfPlay = 0;

    bool isDestroyed = false;

 protected:
    std::map<GameTag, int> m_gameTags;

 private:
    //! Releases dynamic allocated resources.
    void FreeMemory();
};
}  // namespace RosettaStone

#endif  // ROSETTASTONE_ENTITY_HPP
<|endoftext|>


<commit_before>#include "preferencesdialog.h"
#include "ui_preferencesdialog.h"

PreferencesDialog::PreferencesDialog(QWidget *parent) :
	QDialog(),
	ui(new Ui::PreferencesDialog)
{
	ui->setupUi(this);
	_tabBar = dynamic_cast<TabBar *>(parent);

	//Auto Sync
	int check_data_sync = _settings.value("dataAutoSynchronization", 1).toInt();
	ui->syncAutoCheckBox->setChecked(check_data_sync > 0);

	//Default Editor
	int check_default_editor = _settings.value("useDefaultSpreadsheetEditor", 1).toInt();
	bool defaulteditor = check_default_editor > 0;
	ui->useDefaultSpreadsheetEditor->setChecked(defaulteditor);
	setDefaultEditorCheck(defaulteditor);

	//Selected Editor
	QString spreadsheetEditorName = _settings.value("spreadsheetEditorName","").toString();
	if (spreadsheetEditorName != "")
		ui->spreadsheetEditorName->setText(spreadsheetEditorName);

	connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(savePreferences()));
	connect(ui->useDefaultSpreadsheetEditor, SIGNAL(clicked(bool)), this, SLOT(setDefaultEditorCheck(bool)));
	connect(ui->openEditor, SIGNAL(pressed()),this, SLOT(getSpreadsheetEditor()));

}

PreferencesDialog::~PreferencesDialog()
{
	delete ui;
}

void PreferencesDialog::savePreferences()
{

	//Auto Sync Switch
	int checked = (ui->syncAutoCheckBox->checkState()==Qt::Checked) ? 1 : 0;
	int dataAutoSynchronization = _settings.value("dataAutoSynchronization", 1).toInt();
	_settings.setValue("dataAutoSynchronization", checked);
	if (checked != dataAutoSynchronization)
		emit _tabBar->dataAutoSynchronizationChanged(checked);

	//Use Default Editor Switch
	checked = (ui->useDefaultSpreadsheetEditor->checkState()==Qt::Checked) ? 1 : 0;
	_settings.setValue("useDefaultSpreadsheetEditor", checked);

	_settings.setValue("spreadsheetEditorName", ui->spreadsheetEditorName->text());

	_settings.sync();
	this->close();

}

void PreferencesDialog::setDefaultEditorCheck(bool defaulteditor)
{

	if (defaulteditor)
	{
		ui->openEditor->setEnabled(false);
		ui->spreadsheetEditorName->setEnabled(false);
	}
	else
	{
		ui->openEditor->setEnabled(true);
		ui->openEditor->setDefault(true);
		ui->spreadsheetEditorName->setEnabled(true);
	}

}

void PreferencesDialog::getSpreadsheetEditor()
{

	QString filter = "File Description (*.*)";
	QString applicationfolder;

#ifdef __WIN32__
	applicationfolder = "c:\\Program Files";
#elif __APPLE__
	applicationfolder = "/Applications";
#else
	applicationfolder = "/usr/bin";
#endif

	QString filename = QFileDialog::getOpenFileName(this, "Select a file...", applicationfolder, filter);
	if (filename != "")
		ui->spreadsheetEditorName->setText(filename);

}

<commit_msg>Remove ? mark on Preferences dialog<commit_after>#include "preferencesdialog.h"
#include "ui_preferencesdialog.h"

PreferencesDialog::PreferencesDialog(QWidget *parent) :
	QDialog(),
	ui(new Ui::PreferencesDialog)
{
	ui->setupUi(this);
	_tabBar = dynamic_cast<TabBar *>(parent);

	//Auto Sync
	int check_data_sync = _settings.value("dataAutoSynchronization", 1).toInt();
	ui->syncAutoCheckBox->setChecked(check_data_sync > 0);

	//Default Editor
	int check_default_editor = _settings.value("useDefaultSpreadsheetEditor", 1).toInt();
	bool defaulteditor = check_default_editor > 0;
	ui->useDefaultSpreadsheetEditor->setChecked(defaulteditor);
	setDefaultEditorCheck(defaulteditor);

	//Selected Editor
	QString spreadsheetEditorName = _settings.value("spreadsheetEditorName","").toString();
	if (spreadsheetEditorName != "")
		ui->spreadsheetEditorName->setText(spreadsheetEditorName);

	// Remove Question mark Help sign (Only on windows )
	this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);

	connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(savePreferences()));
	connect(ui->useDefaultSpreadsheetEditor, SIGNAL(clicked(bool)), this, SLOT(setDefaultEditorCheck(bool)));
	connect(ui->openEditor, SIGNAL(pressed()),this, SLOT(getSpreadsheetEditor()));

}

PreferencesDialog::~PreferencesDialog()
{
	delete ui;
}

void PreferencesDialog::savePreferences()
{

	//Auto Sync Switch
	int checked = (ui->syncAutoCheckBox->checkState()==Qt::Checked) ? 1 : 0;
	int dataAutoSynchronization = _settings.value("dataAutoSynchronization", 1).toInt();
	_settings.setValue("dataAutoSynchronization", checked);
	if (checked != dataAutoSynchronization)
		emit _tabBar->dataAutoSynchronizationChanged(checked);

	//Use Default Editor Switch
	checked = (ui->useDefaultSpreadsheetEditor->checkState()==Qt::Checked) ? 1 : 0;
	_settings.setValue("useDefaultSpreadsheetEditor", checked);

	_settings.setValue("spreadsheetEditorName", ui->spreadsheetEditorName->text());

	_settings.sync();
	this->close();

}

void PreferencesDialog::setDefaultEditorCheck(bool defaulteditor)
{

	if (defaulteditor)
	{
		ui->openEditor->setEnabled(false);
		ui->spreadsheetEditorName->setEnabled(false);
	}
	else
	{
		ui->openEditor->setEnabled(true);
		ui->openEditor->setDefault(true);
		ui->spreadsheetEditorName->setEnabled(true);
	}

}

void PreferencesDialog::getSpreadsheetEditor()
{

	QString filter = "File Description (*.*)";
	QString applicationfolder;

#ifdef __WIN32__
	applicationfolder = "c:\\Program Files";
#elif __APPLE__
	applicationfolder = "/Applications";
#else
	applicationfolder = "/usr/bin";
#endif

	QString filename = QFileDialog::getOpenFileName(this, "Select a file...", applicationfolder, filter);
	if (filename != "")
		ui->spreadsheetEditorName->setText(filename);

}

<|endoftext|>


<commit_before>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2009 Collabora Ltd. <info@collabora.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "accounts-list-model.h"

#include "account-item.h"

#include <KDebug>
#include <KIcon>

#include <TelepathyQt/Account>

AccountsListModel::AccountsListModel(QObject *parent)
 : QAbstractListModel(parent)
{
}

AccountsListModel::~AccountsListModel()
{
}

int AccountsListModel::rowCount(const QModelIndex & parent) const
{
    // If the index is the root item, then return the row count.
    if (parent == QModelIndex()) {
       return m_accounts.size();
    }

    // Otherwise, return 0 (as this is a list model, so all items
    // are children of the root item).
    return 0;
}

int AccountsListModel::columnCount(const QModelIndex& parent) const
{
    Q_UNUSED(parent);

    // Column count is always 1
    return 1;
}

QVariant AccountsListModel::data(const QModelIndex &index, int role) const
{
    if(!index.isValid()) {
        return QVariant();
    }

    QVariant data;
    Tp::AccountPtr account = m_accounts.at(index.row())->account();

    switch(role)
    {
    case Qt::DisplayRole:
        data = QVariant(account->displayName());
        break;

    case Qt::DecorationRole:
        data = QVariant(m_accounts.at(index.row())->icon());
        break;

    case Qt::CheckStateRole:
        if(account->isEnabled()) {
            data = QVariant(Qt::Checked);
        }
        else {
            data = QVariant(Qt::Unchecked);
        }
        break;

    case AccountsListModel::ConnectionStateRole:
        data = QVariant(m_accounts.at(index.row())->connectionStatus());
        break;

    case AccountsListModel::ConnectionStateDisplayRole:
        data = QVariant(m_accounts.at(index.row())->connectionStateString());
        break;

    case AccountsListModel::ConnectionStateIconRole:
        data = QVariant(m_accounts.at(index.row())->connectionStateIcon());
        break;

    case AccountsListModel::ConnectionErrorMessageDisplayRole:
        data = QVariant(m_accounts.at(index.row())->connectionStatusReason());
        break;

    case AccountsListModel::ConnectionProtocolNameRole:
        data = QVariant(m_accounts.at(index.row())->connectionProtocolName());
        break;

    case AccountsListModel::AccountItemRole:
        data = QVariant::fromValue<AccountItem*>(m_accounts.at(index.row()));
        break;

    default:
        break;
    }

    return data;
}

bool AccountsListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid()) {
        return false;
    }
    if(role == Qt::CheckStateRole) {
        //this is index from QSortFilterProxyModel
        index.data(AccountItemRole).value<AccountItem*>()->account()->setEnabled(value.toInt() == Qt::Checked);
        return true;
    }

    return false;
}

QModelIndex AccountsListModel::index(int row, int column, const QModelIndex& parent) const
{
    if(row < 0 || column < 0 || parent != QModelIndex()) {
        return QModelIndex();
    }

    if(row < rowCount() && column < columnCount()) {
        return createIndex(row, column);
    }

    return QModelIndex();
}

Qt::ItemFlags AccountsListModel::flags(const QModelIndex &index) const
{
    if(!index.isValid()) {
        return QAbstractItemModel::flags(index);
    }
    return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
}

void AccountsListModel::addAccount(const Tp::AccountPtr &account)
{
    kDebug() << "Creating a new AccountItem from account:" << account.data();

    // Check if the account is already in the model.
    bool found = false;

    if (!found) {
        Q_FOREACH (const AccountItem* ai, m_accounts) {
            if (ai->account() == account) {
                found = true;
                break;
            }
        }
    }

    if (found) {
        kWarning() << "Requested to add account"
                   << account.data()
                   << "to model, but it is already present. Doing nothing.";
    } else {
        kDebug() << "Account not already in model. Create new AccountItem from account:"
                 << account.data();

        AccountItem *item = new AccountItem(account, this);

        beginInsertRows(QModelIndex(), m_accounts.size(), m_accounts.size());
        m_accounts.append(item);
        endInsertRows();

        connect(item, SIGNAL(removed()), SLOT(onAccountItemRemoved()));
        connect(item, SIGNAL(updated()), SLOT(onAccountItemUpdated()));
    }
}

void AccountsListModel::removeAccount(const QModelIndex &index)
{
    if(!index.isValid()) {
        kDebug() << "Can't remove Account: Invalid index";
        return;
    }
    AccountItem *accountItem = m_accounts.at(index.row());

    Q_ASSERT(accountItem);

    accountItem->remove();
}

AccountItem* AccountsListModel::itemForIndex(const QModelIndex &index)
{
    if(!index.isValid()) {
        kWarning() << "Invalid index" << index;
        return 0;
    }

    AccountItem *accountItem = m_accounts.at(index.row());
    return accountItem;
}

void AccountsListModel::onAccountItemRemoved()
{
    AccountItem *item = qobject_cast<AccountItem*>(sender());

    Q_ASSERT(item);
    if (!item) {
        kWarning() << "Not an AccountItem pointer:" << sender();
        return;
    }

    // We can be pretty sure that there is only one reference to a specific AccountItem in the list
    // If we screw up here, the styling delegate will screw up even more
    beginRemoveRows(QModelIndex(), m_accounts.indexOf(item), m_accounts.indexOf(item));
    m_accounts.removeAll(item);
    endRemoveRows();

    // FIXME: Workaround until the KWidgetItemDelegate gets fixed (probably KDE 4.7)
    //reset();
    delete item;
}

void AccountsListModel::onAccountItemUpdated()
{
    AccountItem *item = qobject_cast<AccountItem*>(sender());

    Q_ASSERT(item);
    if (!item) {
        kWarning() << "Not an AccountItem pointer:" << sender();
        return;
    }

    QModelIndex index = createIndex(m_accounts.lastIndexOf(item), 0);
    Q_EMIT dataChanged(index, index);
}

void AccountsListModel::onTitleForCustomPages(QString mandatoryPage, QList<QString> optionalPage)
{
    Q_EMIT setTitleForCustomPages(mandatoryPage, optionalPage);
}

#include "accounts-list-model.moc"
<commit_msg>Fix Martin's issues and some more cleanup<commit_after>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2009 Collabora Ltd. <info@collabora.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "accounts-list-model.h"

#include "account-item.h"

#include <KDebug>
#include <KIcon>

#include <TelepathyQt/Account>

AccountsListModel::AccountsListModel(QObject *parent)
 : QAbstractListModel(parent)
{
}

AccountsListModel::~AccountsListModel()
{
}

int AccountsListModel::rowCount(const QModelIndex & parent) const
{
    // If the index is the root item, then return the row count.
    if (parent == QModelIndex()) {
       return m_accounts.size();
    }

    // Otherwise, return 0 (as this is a list model, so all items
    // are children of the root item).
    return 0;
}

int AccountsListModel::columnCount(const QModelIndex& parent) const
{
    Q_UNUSED(parent);

    // Column count is always 1
    return 1;
}

QVariant AccountsListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return QVariant();
    }

    QVariant data;
    Tp::AccountPtr account = m_accounts.at(index.row())->account();

    switch(role)
    {
    case Qt::DisplayRole:
        data = QVariant(account->displayName());
        break;

    case Qt::DecorationRole:
        data = QVariant(m_accounts.at(index.row())->icon());
        break;

    case Qt::CheckStateRole:
        if (account->isEnabled()) {
            data = QVariant(Qt::Checked);
        }
        else {
            data = QVariant(Qt::Unchecked);
        }
        break;

    case AccountsListModel::ConnectionStateRole:
        data = QVariant(m_accounts.at(index.row())->connectionStatus());
        break;

    case AccountsListModel::ConnectionStateDisplayRole:
        data = QVariant(m_accounts.at(index.row())->connectionStateString());
        break;

    case AccountsListModel::ConnectionStateIconRole:
        data = QVariant(m_accounts.at(index.row())->connectionStateIcon());
        break;

    case AccountsListModel::ConnectionErrorMessageDisplayRole:
        data = QVariant(m_accounts.at(index.row())->connectionStatusReason());
        break;

    case AccountsListModel::ConnectionProtocolNameRole:
        data = QVariant(m_accounts.at(index.row())->connectionProtocolName());
        break;

    case AccountsListModel::AccountItemRole:
        data = QVariant::fromValue<AccountItem*>(m_accounts.at(index.row()));
        break;

    default:
        break;
    }

    return data;
}

bool AccountsListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid()) {
        return false;
    }
    if (role == Qt::CheckStateRole) {
        //this is index from QSortFilterProxyModel
        index.data(AccountItemRole).value<AccountItem*>()->account()->setEnabled(value.toInt() == Qt::Checked);
        return true;
    }

    return false;
}

QModelIndex AccountsListModel::index(int row, int column, const QModelIndex& parent) const
{
    if (row < 0 || column < 0 || parent != QModelIndex()) {
        return QModelIndex();
    }

    if (row < rowCount() && column < columnCount()) {
        return createIndex(row, column);
    }

    return QModelIndex();
}

Qt::ItemFlags AccountsListModel::flags(const QModelIndex &index) const
{
    if (!index.isValid()) {
        return QAbstractItemModel::flags(index);
    }
    return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
}

void AccountsListModel::addAccount(const Tp::AccountPtr &account)
{
    kDebug() << "Creating a new AccountItem from account:" << account.data();

    // Check if the account is already in the model.
    bool found = false;

    if (!found) {
        Q_FOREACH (const AccountItem *ai, m_accounts) {
            if (ai->account() == account) {
                found = true;
                break;
            }
        }
    }

    if (found) {
        kWarning() << "Requested to add account"
                   << account.data()
                   << "to model, but it is already present. Doing nothing.";
    } else {
        kDebug() << "Account not already in model. Create new AccountItem from account:"
                 << account.data();

        AccountItem *item = new AccountItem(account, this);

        beginInsertRows(QModelIndex(), m_accounts.size(), m_accounts.size());
        m_accounts.append(item);
        endInsertRows();

        connect(item, SIGNAL(removed()), SLOT(onAccountItemRemoved()));
        connect(item, SIGNAL(updated()), SLOT(onAccountItemUpdated()));
    }
}

void AccountsListModel::removeAccount(const QModelIndex &index)
{
    if (!index.isValid()) {
        kDebug() << "Can't remove Account: Invalid index";
        return;
    }
    AccountItem *accountItem = m_accounts.at(index.row());

    Q_ASSERT(accountItem);

    accountItem->remove();
}

AccountItem* AccountsListModel::itemForIndex(const QModelIndex &index)
{
    if (!index.isValid()) {
        kWarning() << "Invalid index" << index;
        return 0;
    }

    AccountItem *accountItem = m_accounts.at(index.row());
    return accountItem;
}

void AccountsListModel::onAccountItemRemoved()
{
    AccountItem *item = qobject_cast<AccountItem*>(sender());

    Q_ASSERT(item);
    if (!item) {
        kWarning() << "Not an AccountItem pointer:" << sender();
        return;
    }

    // We can be pretty sure that there is only one reference to a specific AccountItem in the list
    // If we screw up here, the styling delegate will screw up even more
    beginRemoveRows(QModelIndex(), m_accounts.indexOf(item), m_accounts.indexOf(item));
    m_accounts.removeAll(item);
    endRemoveRows();

    // FIXME: Workaround until the KWidgetItemDelegate gets fixed (probably KDE 4.7)
    //reset();
    delete item;
}

void AccountsListModel::onAccountItemUpdated()
{
    AccountItem *item = qobject_cast<AccountItem*>(sender());

    Q_ASSERT(item);
    if (!item) {
        kWarning() << "Not an AccountItem pointer:" << sender();
        return;
    }

    QModelIndex index = createIndex(m_accounts.lastIndexOf(item), 0);
    Q_EMIT dataChanged(index, index);
}

void AccountsListModel::onTitleForCustomPages(QString mandatoryPage, QList<QString> optionalPage)
{
    Q_EMIT setTitleForCustomPages(mandatoryPage, optionalPage);
}

#include "accounts-list-model.moc"
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010-2014 OTClient <https://github.com/edubart/otclient>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "spritemanager.h"
#include "game.h"
#include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h>
#include <framework/graphics/image.h>

SpriteManager g_sprites;

SpriteManager::SpriteManager()
{
    m_spritesCount = 0;
    m_signature = 0;
}

void SpriteManager::terminate()
{
    unload();
}

bool SpriteManager::loadSpr(std::string file)
{
    m_spritesCount = 0;
    m_signature = 0;
    m_loaded = false;
    try {
        file = g_resources.guessFilePath(file, "spr");

        m_spritesFile = g_resources.openFile(file);
        // cache file buffer to avoid lags from hard drive
        m_spritesFile->cache();

        m_signature = m_spritesFile->getU32();
        m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
        m_spritesOffset = m_spritesFile->tell();
        m_loaded = true;
        g_lua.callGlobalField("g_sprites", "onLoadSpr", file);
        return true;
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("Failed to load sprites from '%s': %s", file, e.what()));
        return false;
    }
}

void SpriteManager::saveSpr(std::string fileName)
{
    if(!m_loaded)
        stdext::throw_exception("failed to save, spr is not loaded");

    try {
        FileStreamPtr fin = g_resources.createFile(fileName);
        if(!fin)
            stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));

        fin->cache();

        fin->addU32(m_signature);
        if(g_game.getFeature(Otc::GameSpritesU32))
            fin->addU32(m_spritesCount);
        else
            fin->addU16(m_spritesCount);

        bool useAlpha = g_game.getFeature(Otc::GameSpritesAlphaChannel);
        uint32 offset = fin->tell();
        uint32 spriteAddress = offset + 4 * m_spritesCount;
        for(int i = 1; i <= m_spritesCount; i++)
            fin->addU32(0);

        for(int i = 1; i <= m_spritesCount; i++) {
            m_spritesFile->seek((i - 1) * 4 + m_spritesOffset);
            uint32 fromAdress = m_spritesFile->getU32();
            if(fromAdress != 0) {
                fin->seek(offset + (i - 1) * 4);
                fin->addU32(spriteAddress);
                fin->seek(spriteAddress);

                m_spritesFile->seek(fromAdress);
                fin->addU8(m_spritesFile->getU8());
                fin->addU8(m_spritesFile->getU8());
                fin->addU8(m_spritesFile->getU8());
                if (useAlpha) fin->addU8(m_spritesFile->getU8());

                uint16 dataSize = m_spritesFile->getU16();
                fin->addU16(dataSize);
                char spriteData[SPRITE_DATA_SIZE];
                m_spritesFile->read(spriteData, dataSize);
                fin->write(spriteData, dataSize);

                spriteAddress = fin->tell();
            }
            //TODO: Check for overwritten sprites.
        }

        fin->flush();
        fin->close();
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
    }
}

void SpriteManager::unload()
{
    m_spritesCount = 0;
    m_signature = 0;
    m_spritesFile = nullptr;
}

ImagePtr SpriteManager::getSpriteImage(int id)
{
    try {

        if(id == 0 || !m_spritesFile)
            return nullptr;

        m_spritesFile->seek(((id-1) * 4) + m_spritesOffset);

        uint32 spriteAddress = m_spritesFile->getU32();

        // no sprite? return an empty texture
        if(spriteAddress == 0)
            return nullptr;

        m_spritesFile->seek(spriteAddress);

        // skip color key
        m_spritesFile->getU8();
        m_spritesFile->getU8();
        m_spritesFile->getU8();

        uint16 pixelDataSize = m_spritesFile->getU16();

        ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE)));

        uint8 *pixels = image->getPixelData();
        int writePos = 0;
        int read = 0;
        bool useAlpha = g_game.getFeature(Otc::GameSpritesAlphaChannel);
        uint8 channels = useAlpha ? 4 : 3;

        // decompress pixels
        while(read < pixelDataSize && writePos < SPRITE_DATA_SIZE) {
            uint16 transparentPixels = m_spritesFile->getU16();
            uint16 coloredPixels = m_spritesFile->getU16();

            for(int i = 0; i < transparentPixels && writePos < SPRITE_DATA_SIZE; i++) {
                pixels[writePos + 0] = 0x00;
                pixels[writePos + 1] = 0x00;
                pixels[writePos + 2] = 0x00;
                pixels[writePos + 3] = 0x00;
                writePos += 4;
            }

            for(int i = 0; i < coloredPixels && writePos < SPRITE_DATA_SIZE; i++) {
                pixels[writePos + 0] = m_spritesFile->getU8();
                pixels[writePos + 1] = m_spritesFile->getU8();
                pixels[writePos + 2] = m_spritesFile->getU8();
                pixels[writePos + 3] = useAlpha ? m_spritesFile->getU8() : 0xFF;
                writePos += 4;
            }

            read += 4 + (channels * coloredPixels);
        }

        // fill remaining pixels with alpha
        while(writePos < SPRITE_DATA_SIZE) {
            pixels[writePos + 0] = 0x00;
            pixels[writePos + 1] = 0x00;
            pixels[writePos + 2] = 0x00;
            pixels[writePos + 3] = 0x00;
            writePos += 4;
        }

        return image;
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what()));
        return nullptr;
    }
}

<commit_msg>Fix alpha at color key.<commit_after>/*
 * Copyright (c) 2010-2014 OTClient <https://github.com/edubart/otclient>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "spritemanager.h"
#include "game.h"
#include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h>
#include <framework/graphics/image.h>

SpriteManager g_sprites;

SpriteManager::SpriteManager()
{
    m_spritesCount = 0;
    m_signature = 0;
}

void SpriteManager::terminate()
{
    unload();
}

bool SpriteManager::loadSpr(std::string file)
{
    m_spritesCount = 0;
    m_signature = 0;
    m_loaded = false;
    try {
        file = g_resources.guessFilePath(file, "spr");

        m_spritesFile = g_resources.openFile(file);
        // cache file buffer to avoid lags from hard drive
        m_spritesFile->cache();

        m_signature = m_spritesFile->getU32();
        m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16();
        m_spritesOffset = m_spritesFile->tell();
        m_loaded = true;
        g_lua.callGlobalField("g_sprites", "onLoadSpr", file);
        return true;
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("Failed to load sprites from '%s': %s", file, e.what()));
        return false;
    }
}

void SpriteManager::saveSpr(std::string fileName)
{
    if(!m_loaded)
        stdext::throw_exception("failed to save, spr is not loaded");

    try {
        FileStreamPtr fin = g_resources.createFile(fileName);
        if(!fin)
            stdext::throw_exception(stdext::format("failed to open file '%s' for write", fileName));

        fin->cache();

        fin->addU32(m_signature);
        if(g_game.getFeature(Otc::GameSpritesU32))
            fin->addU32(m_spritesCount);
        else
            fin->addU16(m_spritesCount);

        uint32 offset = fin->tell();
        uint32 spriteAddress = offset + 4 * m_spritesCount;
        for(int i = 1; i <= m_spritesCount; i++)
            fin->addU32(0);

        for(int i = 1; i <= m_spritesCount; i++) {
            m_spritesFile->seek((i - 1) * 4 + m_spritesOffset);
            uint32 fromAdress = m_spritesFile->getU32();
            if(fromAdress != 0) {
                fin->seek(offset + (i - 1) * 4);
                fin->addU32(spriteAddress);
                fin->seek(spriteAddress);

                m_spritesFile->seek(fromAdress);
                fin->addU8(m_spritesFile->getU8());
                fin->addU8(m_spritesFile->getU8());
                fin->addU8(m_spritesFile->getU8());

                uint16 dataSize = m_spritesFile->getU16();
                fin->addU16(dataSize);
                char spriteData[SPRITE_DATA_SIZE];
                m_spritesFile->read(spriteData, dataSize);
                fin->write(spriteData, dataSize);

                spriteAddress = fin->tell();
            }
            //TODO: Check for overwritten sprites.
        }

        fin->flush();
        fin->close();
    } catch(std::exception& e) {
        g_logger.error(stdext::format("Failed to save '%s': %s", fileName, e.what()));
    }
}

void SpriteManager::unload()
{
    m_spritesCount = 0;
    m_signature = 0;
    m_spritesFile = nullptr;
}

ImagePtr SpriteManager::getSpriteImage(int id)
{
    try {

        if(id == 0 || !m_spritesFile)
            return nullptr;

        m_spritesFile->seek(((id-1) * 4) + m_spritesOffset);

        uint32 spriteAddress = m_spritesFile->getU32();

        // no sprite? return an empty texture
        if(spriteAddress == 0)
            return nullptr;

        m_spritesFile->seek(spriteAddress);

        // skip color key
        m_spritesFile->getU8();
        m_spritesFile->getU8();
        m_spritesFile->getU8();

        uint16 pixelDataSize = m_spritesFile->getU16();

        ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE)));

        uint8 *pixels = image->getPixelData();
        int writePos = 0;
        int read = 0;
        bool useAlpha = g_game.getFeature(Otc::GameSpritesAlphaChannel);
        uint8 channels = useAlpha ? 4 : 3;

        // decompress pixels
        while(read < pixelDataSize && writePos < SPRITE_DATA_SIZE) {
            uint16 transparentPixels = m_spritesFile->getU16();
            uint16 coloredPixels = m_spritesFile->getU16();

            for(int i = 0; i < transparentPixels && writePos < SPRITE_DATA_SIZE; i++) {
                pixels[writePos + 0] = 0x00;
                pixels[writePos + 1] = 0x00;
                pixels[writePos + 2] = 0x00;
                pixels[writePos + 3] = 0x00;
                writePos += 4;
            }

            for(int i = 0; i < coloredPixels && writePos < SPRITE_DATA_SIZE; i++) {
                pixels[writePos + 0] = m_spritesFile->getU8();
                pixels[writePos + 1] = m_spritesFile->getU8();
                pixels[writePos + 2] = m_spritesFile->getU8();
                pixels[writePos + 3] = useAlpha ? m_spritesFile->getU8() : 0xFF;
                writePos += 4;
            }

            read += 4 + (channels * coloredPixels);
        }

        // fill remaining pixels with alpha
        while(writePos < SPRITE_DATA_SIZE) {
            pixels[writePos + 0] = 0x00;
            pixels[writePos + 1] = 0x00;
            pixels[writePos + 2] = 0x00;
            pixels[writePos + 3] = 0x00;
            writePos += 4;
        }

        return image;
    } catch(stdext::exception& e) {
        g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what()));
        return nullptr;
    }
}

<|endoftext|>


<commit_before>/*
 * InterColComm.h
 *
 *  Created on: Aug 28, 2008
 *      Author: rasmussn
 */

#ifndef INTERCOLCOMM_H_
#define INTERCOLCOMM_H_

#include "DataStore.hpp"
#include "../include/pv_common.h"

#include <mpi.h>

// maximum number of messages (each layer publishes to all neighbors)
#define MAX_MESSAGES    MAX_NEIGHBORS
#define MAX_PUBLISHERS  MAX_LAYERS
#define MAX_SUBSCRIBERS MAX_LAYERS

// directional indices
#define LOCAL     0
#define NORTHWEST 1
#define NORTH     2
#define NORTHEAST 3
#define WEST      4
#define EAST      5
#define SOUTHWEST 6
#define SOUTH     7
#define SOUTHEAST 8

#include "../layers/PVLayer.h"

namespace PV {

class HyPerCol;
class HyPerLayer;
class HyPerConn;

class Publisher {
public:
   Publisher(int pubId, int numType1, size_t size1, int numType2, size_t size2, int numLevels);
   virtual ~Publisher();

   int publish(HyPerLayer * pub,
               int neighbors[], int numNeighbors,
               int borders[], int numBorders, PVLayerCube * data);
   int subscribe(HyPerConn * conn);
   int deliver(HyPerCol * hc, int numNeighbors, int numBorders);

   static int borderStoreIndex(int i, int numNeighbors)  {return i+numNeighbors;}

   int increaseTimeLevel()   {return store->newLevelIndex();}

   void setCommunicator(MPI_Comm comm)  {this->comm = comm;}

   DataStore * dataStore()   {return store;}

private:

   PVLayerCube * recvBuffer(int neighborId)
         {return (PVLayerCube *) store->buffer(neighborId);}
   PVLayerCube * recvBuffer(int neighborId, int delay)
         {return (PVLayerCube *) store->buffer(neighborId, delay);}

   int pubId;
   int numSubscribers;
   HyPerConn *  connection[MAX_SUBSCRIBERS];
   MPI_Request  request[MAX_MESSAGES];
   MPI_Comm     comm;
   DataStore *  store;
};

class InterColComm {
public:
   InterColComm(int * argc, char *** argv);
   virtual ~InterColComm();

   int commInit(int * argc, char *** argv);
   int commFinalize();

   int addPublisher(HyPerLayer * pub, size_t size1, size_t size2, int numLevels);
   int publish(HyPerLayer * pub, PVLayerCube * cube);
   int subscribe(HyPerConn * conn);
   int deliver(HyPerCol * hc, int pubId);
   int increaseTimeLevel(int pubId)       {return publishers[pubId]->increaseTimeLevel();}

   int commRank()               { return icRank; }
   int commSize()               { return icSize; }
   MPI_Comm communicator()      { return icComm; }

   DataStore* publisherStore(int pubId)   {return publishers[pubId]->dataStore();}

   int numberOfNeighbors(); // includes interior (self) as a neighbor
   int numberOfBorders()                  {return numBorders;}

   bool hasNeighbor(int neighborId);

   int commRow(int commId);
   int commColumn(int commId);
   int numCommRows()      {return numRows;}
   int numCommColumns()   {return numCols;}

   size_t recvOffset(int n, const PVLayerLoc * loc);
   size_t sendOffset(int n, const PVLayerLoc * loc);
   MPI_Datatype * newDatatypes(const PVLayerLoc * loc);

   int send(pvdata_t * data, const MPI_Datatype neighborDatatypes [],
            const PVLayerLoc * loc);

   int recv(pvdata_t * data, const MPI_Datatype neighborDatatypes [],
            const PVLayerLoc * loc);

private:

   int icRank;
   int icSize;
   int worldRank;
   int worldSize;
   int numRows;
   int numCols;
   int numHyPerCols;
   int numNeighbors;
   int numBorders;
   int numPublishers;

   MPI_Comm icComm;
   MPI_Request requests[MAX_NEIGHBORS];

   int borders[MAX_NEIGHBORS];
   int neighbors[MAX_NEIGHBORS + 1];        // [0] is interior (local)
   int remoteNeighbors[MAX_NEIGHBORS + 1];
   Publisher* publishers[MAX_PUBLISHERS];

   // These methods are private for now, move to public as needed

   int neighborInit();

   bool hasNorthwesternNeighbor(int commId);
   bool hasNorthernNeighbor(int commId);
   bool hasNortheasternNeighbor(int commId);
   bool hasWesternNeighbor(int commId);
   bool hasEasternNeighbor(int commId);
   bool hasSouthwesternNeighbor(int commId);
   bool hasSouthernNeighbor(int commId);
   bool hasSoutheasternNeighbor(int commId);

   int northwest(int commId);
   int north(int commId);
   int northeast(int commId);
   int west(int commId);
   int east(int commId);
   int southwest(int commId);
   int south(int commId);
   int southeast(int commId);

   int neighborIndex(int commId, int index);

};

}

#endif /* INTERCOLCOMM_H_ */
<commit_msg>Added a version of commRow and commColumn that doesn't require commId (rank). <commit_after>/*
 * InterColComm.h
 *
 *  Created on: Aug 28, 2008
 *      Author: rasmussn
 */

#ifndef INTERCOLCOMM_H_
#define INTERCOLCOMM_H_

#include "DataStore.hpp"
#include "../include/pv_common.h"

#include <mpi.h>

// maximum number of messages (each layer publishes to all neighbors)
#define MAX_MESSAGES    MAX_NEIGHBORS
#define MAX_PUBLISHERS  MAX_LAYERS
#define MAX_SUBSCRIBERS MAX_LAYERS

// directional indices
#define LOCAL     0
#define NORTHWEST 1
#define NORTH     2
#define NORTHEAST 3
#define WEST      4
#define EAST      5
#define SOUTHWEST 6
#define SOUTH     7
#define SOUTHEAST 8

#include "../layers/PVLayer.h"

namespace PV {

class HyPerCol;
class HyPerLayer;
class HyPerConn;

class Publisher {
public:
   Publisher(int pubId, int numType1, size_t size1, int numType2, size_t size2, int numLevels);
   virtual ~Publisher();

   int publish(HyPerLayer * pub,
               int neighbors[], int numNeighbors,
               int borders[], int numBorders, PVLayerCube * data);
   int subscribe(HyPerConn * conn);
   int deliver(HyPerCol * hc, int numNeighbors, int numBorders);

   static int borderStoreIndex(int i, int numNeighbors)  {return i+numNeighbors;}

   int increaseTimeLevel()   {return store->newLevelIndex();}

   void setCommunicator(MPI_Comm comm)  {this->comm = comm;}

   DataStore * dataStore()   {return store;}

private:

   PVLayerCube * recvBuffer(int neighborId)
         {return (PVLayerCube *) store->buffer(neighborId);}
   PVLayerCube * recvBuffer(int neighborId, int delay)
         {return (PVLayerCube *) store->buffer(neighborId, delay);}

   int pubId;
   int numSubscribers;
   HyPerConn *  connection[MAX_SUBSCRIBERS];
   MPI_Request  request[MAX_MESSAGES];
   MPI_Comm     comm;
   DataStore *  store;
};

class InterColComm {
public:
   InterColComm(int * argc, char *** argv);
   virtual ~InterColComm();

   int commInit(int * argc, char *** argv);
   int commFinalize();

   int addPublisher(HyPerLayer * pub, size_t size1, size_t size2, int numLevels);
   int publish(HyPerLayer * pub, PVLayerCube * cube);
   int subscribe(HyPerConn * conn);
   int deliver(HyPerCol * hc, int pubId);
   int increaseTimeLevel(int pubId)       {return publishers[pubId]->increaseTimeLevel();}

   int commRank()               { return icRank; }
   int commSize()               { return icSize; }
   MPI_Comm communicator()      { return icComm; }

   DataStore* publisherStore(int pubId)   {return publishers[pubId]->dataStore();}

   int numberOfNeighbors(); // includes interior (self) as a neighbor
   int numberOfBorders()                  {return numBorders;}

   bool hasNeighbor(int neighborId);

   int commRow()          {return commRow(icRank);}
   int commColumn()       {return commColumn(icRank);}
   int numCommRows()      {return numRows;}
   int numCommColumns()   {return numCols;}

   size_t recvOffset(int n, const PVLayerLoc * loc);
   size_t sendOffset(int n, const PVLayerLoc * loc);
   MPI_Datatype * newDatatypes(const PVLayerLoc * loc);

   int send(pvdata_t * data, const MPI_Datatype neighborDatatypes [],
            const PVLayerLoc * loc);

   int recv(pvdata_t * data, const MPI_Datatype neighborDatatypes [],
            const PVLayerLoc * loc);

protected:

   int commRow(int commId);
   int commColumn(int commId);

private:

   int icRank;
   int icSize;
   int worldRank;
   int worldSize;
   int numRows;
   int numCols;
   int numHyPerCols;
   int numNeighbors;
   int numBorders;
   int numPublishers;

   MPI_Comm icComm;
   MPI_Request requests[MAX_NEIGHBORS];

   int borders[MAX_NEIGHBORS];
   int neighbors[MAX_NEIGHBORS + 1];        // [0] is interior (local)
   int remoteNeighbors[MAX_NEIGHBORS + 1];
   Publisher* publishers[MAX_PUBLISHERS];

   // These methods are private for now, move to public as needed

   int neighborInit();

   bool hasNorthwesternNeighbor(int commId);
   bool hasNorthernNeighbor(int commId);
   bool hasNortheasternNeighbor(int commId);
   bool hasWesternNeighbor(int commId);
   bool hasEasternNeighbor(int commId);
   bool hasSouthwesternNeighbor(int commId);
   bool hasSouthernNeighbor(int commId);
   bool hasSoutheasternNeighbor(int commId);

   int northwest(int commId);
   int north(int commId);
   int northeast(int commId);
   int west(int commId);
   int east(int commId);
   int southwest(int commId);
   int south(int commId);
   int southeast(int commId);

   int neighborIndex(int commId, int index);

};

}

#endif /* INTERCOLCOMM_H_ */
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Markus Himmel
 * This file is distributed under the terms of the MIT license
 */

#include "WindowBoard.h"

#include "Game.h"
#include "NumberView.cpp"

#include <Alert.h>
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <LayoutBuilder.h>
#include <Messenger.h>
#include <Rect.h>
#include <String.h>
#include <StringView.h>

GameWindow::GameWindow(WindowBoard *master)
	:
	BWindow(BRect(100, 100, 500, 400), "Haiku2048", B_TITLED_WINDOW, 0),
	fMaster(master)
{
	BButton *newGameButton = new BButton("newgame", "New Game",
		new BMessage(H2048_NEW_GAME));

	undoButton = new BButton("undomove", "Undo last move",
		new BMessage(H2048_UNDO_MOVE));
	undoButton->SetEnabled(false);

	fScore = new BStringView("score", "Score: 0");

	fBoard = new BGridLayout();

	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_WINDOW_INSETS)
		.AddGroup(B_HORIZONTAL)
			.Add(newGameButton)
			.Add(undoButton)
			.Add(fScore)
			.End()
		.Add(fBoard);

	uint32 sizeX = fMaster->fTarget->SizeX();
	uint32 sizeY = fMaster->fTarget->SizeY();

	fViews = new NumberView *[sizeX * sizeY];

	for (uint32 x = 0; x < sizeX; x++)
	{
		for (uint32 y = 0; y < sizeY; y++)
		{
			NumberView *num = new NumberView(0);
			fViews[x * sizeY + y] = num;
			fBoard->AddView(num, x, y);
		}
	}
	ResizeToPreferred();
	BRect rect = Bounds();
	prevWidth = rect.Width();
	prevHeight = rect.Height();
	defaultWidth = rect.Width();
	defaultHeight = rect.Height();
}

GameWindow::~GameWindow()
{
	fMaster->fWindow = NULL;
	delete [] fViews;
}

bool
GameWindow::QuitRequested()
{
	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
	return true;
}

void
GameWindow::MessageReceived(BMessage *message)
{
	switch (message->what)
	{
		case H2048_NEW_GAME:
		{
			BMessenger game(NULL, fMaster->fTarget);
			game.SendMessage(message);
			break;
		}
		case H2048_WINDOW_SHOW:
		{
			bool canUndo = false;
			message->FindBool("canUndo", &canUndo);
			showBoard(canUndo);
			break;
		}
		case H2048_UNDO_MOVE:
		{
			if (!fMaster->fSending) {
				// fMaster->fSending is false when:
				// * The game hasn't started (unlikely, and the button is disabled anyway)
				// * Game over
				// In case of game over, we have to make it true, so that
				// subsequent keypressed are acknowledged
				fMaster->fSending = true;
			}

			BMessenger game(NULL, fMaster->fTarget);
			game.SendMessage(message);
			break;
		}
		case B_KEY_DOWN:
		{
			const char *data;
			ssize_t length;
			if (fMaster->fSending && message->FindData("bytes", B_STRING_TYPE,
				(const void **)&data, &length) == B_OK && data[0] >= 28
				&& data[0] <= 31)
			{
				GameMove m;

				switch (data[0])
				{
					case 30: //Up
						m = Up;
						break;
					case 28: // Left
						m = Left;
						break;
					case 31: // Down
						m = Down;
						break;
					case 29: // Right
						m = Right;
						break;
				}
				BMessage move(H2048_MAKE_MOVE);
				move.AddInt32("direction", m);
				BMessenger messenger(NULL, fMaster->fTarget);
				messenger.SendMessage(&move);
			}
			BWindow::MessageReceived(message);
			break;
		}
		default:
			BWindow::MessageReceived(message);
			break;
	}
}

void
GameWindow::showBoard(bool canUndo)
{
	undoButton->SetEnabled(canUndo);

	Game *target = fMaster->fTarget;
	uint32 sizeX = target->SizeX();
	uint32 sizeY = target->SizeY();

	for (uint32 x = 0; x < sizeX; x++)
	{
		for (uint32 y = 0; y < sizeY; y++)
		{
			fViews[x * sizeY + y]->SetNumber(1 << target->BoardAt(x, y));
			fViews[x * sizeY + y]->Invalidate();
		}
	}

	BString score;
	score << "Score: " << fMaster->fTarget->Score();
	fScore->SetText(score.String());
}

void
GameWindow::FrameResized(float width,
			 float height)
{
	// We don't want the user to scale the window so small that
	// there's no space for the buttons.
	if (width < defaultWidth) {
		ResizeTo(defaultWidth, defaultHeight);
		SetScale(1);
	}
	// Maintain the same width:height ratio
	else {
		float ratio = width/prevWidth;
		SetScale(ratio);
		prevWidth = width;
		prevHeight = height;
		ResizeTo(width, height*ratio);
	}
}

WindowBoard::WindowBoard(Game *target)
	:
	GameBoard(target),
	fSending(false)
{
	fWindow = new GameWindow(this);
	fWindow->Show();
}

WindowBoard::~WindowBoard()
{
	delete fWindow;
}

void
WindowBoard::gameStarted()
{
	BMessage redraw(H2048_WINDOW_SHOW);
	redraw.AddBool("canUndo", false);

	BMessenger messenger(NULL, fWindow);
	messenger.SendMessage(&redraw);

	fSending = true;
}

void
WindowBoard::gameEnded()
{
	fSending = false;
	(new BAlert("Title", "Game Ended", "OK"))->Go();
}

void
WindowBoard::boardChanged(bool canUndo)
{
	BMessage redraw(H2048_WINDOW_SHOW);
	redraw.AddBool("canUndo", canUndo);

	BMessenger messenger(NULL, fWindow);
	messenger.SendMessage(&redraw);
}
<commit_msg>Add 'u' shortcut for undoing move in the GUI<commit_after>/*
 * Copyright (c) 2015 Markus Himmel
 * This file is distributed under the terms of the MIT license
 */

#include "WindowBoard.h"

#include "Game.h"
#include "NumberView.cpp"

#include <Alert.h>
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <LayoutBuilder.h>
#include <Messenger.h>
#include <Rect.h>
#include <String.h>
#include <StringView.h>

GameWindow::GameWindow(WindowBoard *master)
	:
	BWindow(BRect(100, 100, 500, 400), "Haiku2048", B_TITLED_WINDOW, 0),
	fMaster(master)
{
	BButton *newGameButton = new BButton("newgame", "New Game",
		new BMessage(H2048_NEW_GAME));

	undoButton = new BButton("undomove", "Undo last move",
		new BMessage(H2048_UNDO_MOVE));
	undoButton->SetEnabled(false);

	fScore = new BStringView("score", "Score: 0");

	fBoard = new BGridLayout();

	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_WINDOW_INSETS)
		.AddGroup(B_HORIZONTAL)
			.Add(newGameButton)
			.Add(undoButton)
			.Add(fScore)
			.End()
		.Add(fBoard);

	uint32 sizeX = fMaster->fTarget->SizeX();
	uint32 sizeY = fMaster->fTarget->SizeY();

	fViews = new NumberView *[sizeX * sizeY];

	for (uint32 x = 0; x < sizeX; x++)
	{
		for (uint32 y = 0; y < sizeY; y++)
		{
			NumberView *num = new NumberView(0);
			fViews[x * sizeY + y] = num;
			fBoard->AddView(num, x, y);
		}
	}
	ResizeToPreferred();
	BRect rect = Bounds();
	prevWidth = rect.Width();
	prevHeight = rect.Height();
	defaultWidth = rect.Width();
	defaultHeight = rect.Height();
}

GameWindow::~GameWindow()
{
	fMaster->fWindow = NULL;
	delete [] fViews;
}

bool
GameWindow::QuitRequested()
{
	be_app_messenger.SendMessage(B_QUIT_REQUESTED);
	return true;
}

void
GameWindow::MessageReceived(BMessage *message)
{
	switch (message->what)
	{
		case H2048_NEW_GAME:
		{
			BMessenger game(NULL, fMaster->fTarget);
			game.SendMessage(message);
			break;
		}
		case H2048_WINDOW_SHOW:
		{
			bool canUndo = false;
			message->FindBool("canUndo", &canUndo);
			showBoard(canUndo);
			break;
		}
		case H2048_UNDO_MOVE:
		{
			if (!fMaster->fSending) {
				// fMaster->fSending is false when:
				// * The game hasn't started (unlikely, and the button is disabled anyway)
				// * Game over
				// In case of game over, we have to make it true, so that
				// subsequent keypressed are acknowledged
				fMaster->fSending = true;
			}

			BMessenger game(NULL, fMaster->fTarget);
			game.SendMessage(message);
			break;
		}
		case B_KEY_DOWN:
		{
			const char *data;
			ssize_t length;
			if (fMaster->fSending
				&& message->FindData("bytes", B_STRING_TYPE, (const void **)&data, &length) == B_OK
				&& (data[0] == 'u' || (data[0] >= 28 && data[0] <= 31)))
			{
				if (data[0] == 'u') {
					PostMessage(H2048_UNDO_MOVE);
					break;
				}

				GameMove m;

				switch (data[0])
				{
					case 30: //Up
						m = Up;
						break;
					case 28: // Left
						m = Left;
						break;
					case 31: // Down
						m = Down;
						break;
					case 29: // Right
						m = Right;
						break;
				}
				BMessage move(H2048_MAKE_MOVE);
				move.AddInt32("direction", m);
				BMessenger messenger(NULL, fMaster->fTarget);
				messenger.SendMessage(&move);
			}
			BWindow::MessageReceived(message);
			break;
		}
		default:
			BWindow::MessageReceived(message);
			break;
	}
}

void
GameWindow::showBoard(bool canUndo)
{
	undoButton->SetEnabled(canUndo);

	Game *target = fMaster->fTarget;
	uint32 sizeX = target->SizeX();
	uint32 sizeY = target->SizeY();

	for (uint32 x = 0; x < sizeX; x++)
	{
		for (uint32 y = 0; y < sizeY; y++)
		{
			fViews[x * sizeY + y]->SetNumber(1 << target->BoardAt(x, y));
			fViews[x * sizeY + y]->Invalidate();
		}
	}

	BString score;
	score << "Score: " << fMaster->fTarget->Score();
	fScore->SetText(score.String());
}

void
GameWindow::FrameResized(float width,
			 float height)
{
	// We don't want the user to scale the window so small that
	// there's no space for the buttons.
	if (width < defaultWidth) {
		ResizeTo(defaultWidth, defaultHeight);
		SetScale(1);
	}
	// Maintain the same width:height ratio
	else {
		float ratio = width/prevWidth;
		SetScale(ratio);
		prevWidth = width;
		prevHeight = height;
		ResizeTo(width, height*ratio);
	}
}

WindowBoard::WindowBoard(Game *target)
	:
	GameBoard(target),
	fSending(false)
{
	fWindow = new GameWindow(this);
	fWindow->Show();
}

WindowBoard::~WindowBoard()
{
	delete fWindow;
}

void
WindowBoard::gameStarted()
{
	BMessage redraw(H2048_WINDOW_SHOW);
	redraw.AddBool("canUndo", false);

	BMessenger messenger(NULL, fWindow);
	messenger.SendMessage(&redraw);

	fSending = true;
}

void
WindowBoard::gameEnded()
{
	fSending = false;
	(new BAlert("Title", "Game Ended", "OK"))->Go();
}

void
WindowBoard::boardChanged(bool canUndo)
{
	BMessage redraw(H2048_WINDOW_SHOW);
	redraw.AddBool("canUndo", canUndo);

	BMessenger messenger(NULL, fWindow);
	messenger.SendMessage(&redraw);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/public/app/content_main.h"

#include "content/nw/src/shell_main_delegate.h"
#include "sandbox/win/src/sandbox_types.h"

#if defined(OS_WIN)
#include "content/public/app/startup_helper_win.h"
#endif

#if defined(OS_MACOSX)
#include "shell_content_main.h"
#endif

#if defined(OS_WIN)

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) {
  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  content::InitializeSandboxInfo(&sandbox_info);
  content::ShellMainDelegate delegate;
  return content::ContentMain(instance, &sandbox_info, &delegate);
}

#else

int main(int argc, const char** argv) {
#if defined(OS_MACOSX)
  // Do the delegate work in shell_content_main to avoid having to export the
  // delegate types.
  return ::ContentMain(argc, argv);
#else
  content::ShellMainDelegate delegate;
  return content::ContentMain(argc, argv, &delegate);
#endif  // OS_MACOSX
}

#endif  // OS_POSIX
<commit_msg>Enable high DPI support<commit_after>// Copyright (c) 2012 Intel Corp
// Copyright (c) 2012 The Chromium Authors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell co
// pies of the Software, and to permit persons to whom the Software is furnished
//  to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in al
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "content/public/app/content_main.h"

#include "base/command_line.h"
#include "content/nw/src/shell_main_delegate.h"
#include "sandbox/win/src/sandbox_types.h"

#if defined(OS_WIN)
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "content/public/app/startup_helper_win.h"
#include "ui/gfx/win/dpi.h"
#endif

#if defined(OS_MACOSX)
#include "shell_content_main.h"
#endif

#if defined(OS_WIN)

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) {
  CommandLine::Init(0, NULL);
  if (base::win::GetVersion() > base::win::VERSION_VISTA)
    gfx::EnableHighDPISupport();

  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  content::InitializeSandboxInfo(&sandbox_info);
  content::ShellMainDelegate delegate;
  return content::ContentMain(instance, &sandbox_info, &delegate);
}

#else

int main(int argc, const char** argv) {
#if defined(OS_MACOSX)
  // Do the delegate work in shell_content_main to avoid having to export the
  // delegate types.
  return ::ContentMain(argc, argv);
#else
  content::ShellMainDelegate delegate;
  return content::ContentMain(argc, argv, &delegate);
#endif  // OS_MACOSX
}

#endif  // OS_POSIX
<|endoftext|>


<commit_before>#include "ghost/config.h"
#ifdef GHOST_HAVE_MPI
#include <mpi.h>
#endif

#include <map>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <numeric>
#include <algorithm>

#include "ghost/types.h"
#include "ghost/util.h"
#include "ghost/sparsemat.h"

using namespace std;
static map<ghost_sparsemat_t *,map<ghost_lidx_t, ghost_gidx_t> > rowlengths;
static vector<ghost_gidx_t>lowerPerc90Dists;
static vector<ghost_gidx_t>upperPerc90Dists;

ghost_error_t ghost_sparsemat_registerrow(ghost_sparsemat_t *mat, ghost_gidx_t row, ghost_gidx_t *cols, ghost_lidx_t rowlen, ghost_lidx_t stride)
{
    ghost_lidx_t c;
    ghost_gidx_t col;
    ghost_gidx_t firstcol = mat->ncols-1, lastcol = 0;
    vector<ghost_gidx_t>lowerDists;
    vector<ghost_gidx_t>upperDists;
    ghost_gidx_t lowerDistsAcc = 0, upperDistsAcc = 0;
    ghost_gidx_t lowerEnts = 0, upperEnts = 0;

    for (c=0; c<rowlen; c++) {
        col = cols[c*stride];
        if (col < row) {
            mat->lowerBandwidth = MAX(mat->lowerBandwidth, row-col);
            lowerDists.push_back(row-col);
            lowerDistsAcc += row-col;
            lowerEnts++;
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1-(row-col)]++;
#endif
        } else if (col > row) {
            mat->upperBandwidth = MAX(mat->upperBandwidth, col-row);
            upperDists.push_back(col-row);
            upperDistsAcc += col-row;
            upperEnts++;
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1+col-row]++;
#endif
        } else {
            lowerDists.push_back(0);
            upperDists.push_back(0);
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1]++;
#endif
        }
        firstcol = MIN(col,firstcol);
        lastcol = MAX(col,lastcol);

    }

    mat->maxRowLen = MAX(mat->maxRowLen,rowlen);
    rowlengths[mat][rowlen]++;
    mat->avgRowBand += lastcol-firstcol+1;

    nth_element(upperDists.begin(),upperDists.begin()+int(upperDists.size()*.9),upperDists.end());
    nth_element(lowerDists.begin(),lowerDists.begin()+int(lowerDists.size()*.9),lowerDists.end());

    if (upperDists.size()) {
        upperPerc90Dists.push_back(*(upperDists.begin()+int(upperDists.size()*.9)));
    }

    if (lowerDists.size()) {
        lowerPerc90Dists.push_back(*(lowerDists.begin()+int(lowerDists.size()*.9)));
    }

    if (lowerEnts) {
        mat->avgAvgRowBand += (double)lowerDistsAcc/lowerEnts;
    }
    if (upperEnts) {
        mat->avgAvgRowBand += (double)upperDistsAcc/upperEnts;
    }
    mat->avgAvgRowBand += 1;

    return GHOST_SUCCESS;
}

ghost_error_t ghost_sparsemat_registerrow_finalize(ghost_sparsemat_t *mat)
{
    ghost_gidx_t gnrows;
    double avgRowlen = mat->nnz*1.0/(double)mat->nrows;

#ifdef GHOST_HAVE_MPI
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->lowerBandwidth,1,ghost_mpi_dt_gidx,MPI_MAX,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->upperBandwidth,1,ghost_mpi_dt_gidx,MPI_MAX,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->avgRowBand,1,MPI_DOUBLE,MPI_SUM,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->avgAvgRowBand,1,MPI_DOUBLE,MPI_SUM,mat->context->mpicomm));
#ifdef GHOST_GATHER_GLOBAL_INFO
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,mat->nzDist,2*mat->context->gnrows-1,ghost_mpi_dt_idx,MPI_SUM,mat->context->mpicomm));
#endif
#endif
    mat->bandwidth = mat->lowerBandwidth+mat->upperBandwidth+1;

    nth_element(upperPerc90Dists.begin(),upperPerc90Dists.begin()+int(upperPerc90Dists.size()*.5),upperPerc90Dists.end());
    nth_element(lowerPerc90Dists.begin(),lowerPerc90Dists.begin()+int(lowerPerc90Dists.size()*.5),lowerPerc90Dists.end());

    mat->smartRowBand = (double) *(upperPerc90Dists.begin()+int(upperPerc90Dists.size()*.5)) + *(lowerPerc90Dists.begin()+int(lowerPerc90Dists.size()*.5)) + 1;

    ghost_sparsemat_nrows(&gnrows,mat);
    mat->avgRowBand /= (double)(gnrows);
    mat->avgAvgRowBand /= (double)(gnrows);

    rowlengths[mat].erase(0); // erase padded rows

    mat->variance = 0.;
    mat->deviation = 0.;
    for (map<ghost_lidx_t,ghost_gidx_t>::const_iterator it = rowlengths[mat].begin(); it != rowlengths[mat].end(); it++) {
        mat->variance += (it->first-avgRowlen)*(it->first-avgRowlen)*it->second;
    }
    mat->variance /= mat->nrows;
    mat->deviation = sqrt(mat->variance);
    mat->cv = mat->deviation*1./(mat->nnz*1.0/(double)mat->nrows);

    mat->nMaxRows = rowlengths[mat][mat->maxRowLen];

    return GHOST_SUCCESS;
}

<commit_msg>prevent segfault for some matrices<commit_after>#include "ghost/config.h"
#ifdef GHOST_HAVE_MPI
#include <mpi.h>
#endif

#include <map>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <numeric>
#include <algorithm>

#include "ghost/types.h"
#include "ghost/util.h"
#include "ghost/sparsemat.h"

using namespace std;
static map<ghost_sparsemat_t *,map<ghost_lidx_t, ghost_gidx_t> > rowlengths;
static vector<ghost_gidx_t>lowerPerc90Dists;
static vector<ghost_gidx_t>upperPerc90Dists;

ghost_error_t ghost_sparsemat_registerrow(ghost_sparsemat_t *mat, ghost_gidx_t row, ghost_gidx_t *cols, ghost_lidx_t rowlen, ghost_lidx_t stride)
{
    ghost_lidx_t c;
    ghost_gidx_t col;
    ghost_gidx_t firstcol = mat->ncols-1, lastcol = 0;
    vector<ghost_gidx_t>lowerDists;
    vector<ghost_gidx_t>upperDists;
    ghost_gidx_t lowerDistsAcc = 0, upperDistsAcc = 0;
    ghost_gidx_t lowerEnts = 0, upperEnts = 0;

    for (c=0; c<rowlen; c++) {
        col = cols[c*stride];
        if (col < row) {
            mat->lowerBandwidth = MAX(mat->lowerBandwidth, row-col);
            lowerDists.push_back(row-col);
            lowerDistsAcc += row-col;
            lowerEnts++;
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1-(row-col)]++;
#endif
        } else if (col > row) {
            mat->upperBandwidth = MAX(mat->upperBandwidth, col-row);
            upperDists.push_back(col-row);
            upperDistsAcc += col-row;
            upperEnts++;
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1+col-row]++;
#endif
        } else {
            lowerDists.push_back(0);
            upperDists.push_back(0);
#ifdef GHOST_GATHER_GLOBAL_INFO
            mat->nzDist[mat->context->gnrows-1]++;
#endif
        }
        firstcol = MIN(col,firstcol);
        lastcol = MAX(col,lastcol);

    }

    mat->maxRowLen = MAX(mat->maxRowLen,rowlen);
    rowlengths[mat][rowlen]++;
    mat->avgRowBand += lastcol-firstcol+1;

    nth_element(upperDists.begin(),upperDists.begin()+int(upperDists.size()*.9),upperDists.end());
    nth_element(lowerDists.begin(),lowerDists.begin()+int(lowerDists.size()*.9),lowerDists.end());

    if (upperDists.size()) {
        upperPerc90Dists.push_back(*(upperDists.begin()+int(upperDists.size()*.9)));
    }

    if (lowerDists.size()) {
        lowerPerc90Dists.push_back(*(lowerDists.begin()+int(lowerDists.size()*.9)));
    }

    if (lowerEnts) {
        mat->avgAvgRowBand += (double)lowerDistsAcc/lowerEnts;
    }
    if (upperEnts) {
        mat->avgAvgRowBand += (double)upperDistsAcc/upperEnts;
    }
    mat->avgAvgRowBand += 1;

    return GHOST_SUCCESS;
}

ghost_error_t ghost_sparsemat_registerrow_finalize(ghost_sparsemat_t *mat)
{
    ghost_gidx_t gnrows;
    double avgRowlen = mat->nnz*1.0/(double)mat->nrows;

#ifdef GHOST_HAVE_MPI
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->lowerBandwidth,1,ghost_mpi_dt_gidx,MPI_MAX,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->upperBandwidth,1,ghost_mpi_dt_gidx,MPI_MAX,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->avgRowBand,1,MPI_DOUBLE,MPI_SUM,mat->context->mpicomm));
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,&mat->avgAvgRowBand,1,MPI_DOUBLE,MPI_SUM,mat->context->mpicomm));
#ifdef GHOST_GATHER_GLOBAL_INFO
    MPI_CALL_RETURN(MPI_Allreduce(MPI_IN_PLACE,mat->nzDist,2*mat->context->gnrows-1,ghost_mpi_dt_idx,MPI_SUM,mat->context->mpicomm));
#endif
#endif
    mat->bandwidth = mat->lowerBandwidth+mat->upperBandwidth+1;

    nth_element(upperPerc90Dists.begin(),upperPerc90Dists.begin()+int(upperPerc90Dists.size()*.5),upperPerc90Dists.end());
    nth_element(lowerPerc90Dists.begin(),lowerPerc90Dists.begin()+int(lowerPerc90Dists.size()*.5),lowerPerc90Dists.end());

    if (upperPerc90Dists.size() && lowerPerc90Dists.size()) {
        mat->smartRowBand = (double) *(upperPerc90Dists.begin()+int(upperPerc90Dists.size()*.5)) + *(lowerPerc90Dists.begin()+int(lowerPerc90Dists.size()*.5)) + 1;
    }

    ghost_sparsemat_nrows(&gnrows,mat);
    mat->avgRowBand /= (double)(gnrows);
    mat->avgAvgRowBand /= (double)(gnrows);

    rowlengths[mat].erase(0); // erase padded rows

    mat->variance = 0.;
    mat->deviation = 0.;
    for (map<ghost_lidx_t,ghost_gidx_t>::const_iterator it = rowlengths[mat].begin(); it != rowlengths[mat].end(); it++) {
        mat->variance += (it->first-avgRowlen)*(it->first-avgRowlen)*it->second;
    }
    mat->variance /= mat->nrows;
    mat->deviation = sqrt(mat->variance);
    mat->cv = mat->deviation*1./(mat->nnz*1.0/(double)mat->nrows);

    mat->nMaxRows = rowlengths[mat][mat->maxRowLen];

    return GHOST_SUCCESS;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Tommi Maekitalo
 *
 * 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.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <cxxtools/stddevice.h>
#include <cxxtools/ioerror.h>
#include "iodeviceimpl.h"

#include <unistd.h>

namespace cxxtools
{

StdinDevice::StdinDevice()
{
    _impl = new IODeviceImpl(*this);
    setEnabled(true);
    setAsync(true);
    setEof(false);
    _impl->open(STDIN_FILENO, true, true);
}

StdinDevice::~StdinDevice()
{
    _impl->detach(*selector());
    setEnabled(false);
    delete _impl;
}

IODeviceImpl& StdinDevice::ioimpl()
{
    return *_impl;
}

SelectableImpl& StdinDevice::simpl()
{
    return *_impl;
}

size_t StdinDevice::onBeginWrite(const char* buffer, size_t n)
{
    throw IOError("cannot write to standard input device");
}

size_t StdinDevice::onWrite(const char* buffer, size_t count)
{
    throw IOError("cannot write to standard input device");
}

ODevice::ODevice()
{
    _impl = new IODeviceImpl(*this);
}

ODevice::~ODevice()
{
    _impl->detach(*selector());
    setEnabled(false);
    delete _impl;
}

IODeviceImpl& ODevice::ioimpl()
{
    return *_impl;
}

SelectableImpl& ODevice::simpl()
{
    return *_impl;
}

size_t ODevice::onBeginRead(char* buffer, size_t n, bool& eof)
{
    throw IOError("cannot read from standard output device");
}

size_t ODevice::onRead(char* buffer, size_t count, bool& eof)
{
    throw IOError("cannot read from standard output device");
}

StdoutDevice::StdoutDevice()
{
    ioimpl().open(STDOUT_FILENO, true, true);
}

StderrDevice::StderrDevice()
{
    ioimpl().open(STDERR_FILENO, true, true);
}

} // namespace cxxtools
<commit_msg>fix initialization of cxxtools::StdoutDevice and cxxtools::StderrDevice<commit_after>/*
 * Copyright (C) 2017 Tommi Maekitalo
 *
 * 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.
 *
 * As a special exception, you may use this file as part of a free
 * software library without restriction. Specifically, if other files
 * instantiate templates or use macros or inline functions from this
 * file, or you compile this file and link it with other files to
 * produce an executable, this file does not by itself cause the
 * resulting executable to be covered by the GNU General Public
 * License. This exception does not however invalidate any other
 * reasons why the executable file might be covered by the GNU Library
 * General Public License.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <cxxtools/stddevice.h>
#include <cxxtools/ioerror.h>
#include "iodeviceimpl.h"

#include <unistd.h>

namespace cxxtools
{

StdinDevice::StdinDevice()
{
    _impl = new IODeviceImpl(*this);
    setEnabled(true);
    setAsync(true);
    setEof(false);
    _impl->open(STDIN_FILENO, true, true);
}

StdinDevice::~StdinDevice()
{
    _impl->detach(*selector());
    setEnabled(false);
    delete _impl;
}

IODeviceImpl& StdinDevice::ioimpl()
{
    return *_impl;
}

SelectableImpl& StdinDevice::simpl()
{
    return *_impl;
}

size_t StdinDevice::onBeginWrite(const char* buffer, size_t n)
{
    throw IOError("cannot write to standard input device");
}

size_t StdinDevice::onWrite(const char* buffer, size_t count)
{
    throw IOError("cannot write to standard input device");
}

ODevice::ODevice()
{
    _impl = new IODeviceImpl(*this);
    setEnabled(true);
    setAsync(true);
    setEof(false);
}

ODevice::~ODevice()
{
    _impl->detach(*selector());
    setEnabled(false);
    delete _impl;
}

IODeviceImpl& ODevice::ioimpl()
{
    return *_impl;
}

SelectableImpl& ODevice::simpl()
{
    return *_impl;
}

size_t ODevice::onBeginRead(char* buffer, size_t n, bool& eof)
{
    throw IOError("cannot read from standard output device");
}

size_t ODevice::onRead(char* buffer, size_t count, bool& eof)
{
    throw IOError("cannot read from standard output device");
}

StdoutDevice::StdoutDevice()
{
    ioimpl().open(STDOUT_FILENO, true, true);
}

StderrDevice::StderrDevice()
{
    ioimpl().open(STDERR_FILENO, true, true);
}

} // namespace cxxtools
<|endoftext|>