Merge branch 'master' into NDK-ShadowMapping

Former-commit-id: e2be28b65207dfbb81efe58f31ca31548afecee7
This commit is contained in:
Lynix
2016-04-17 19:57:15 +02:00
354 changed files with 24993 additions and 2830 deletions

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
/*!
* \ingroup core
* \class Nz::AbstractLogger
* \brief Logger interface
*/

View File

@@ -23,8 +23,16 @@ namespace Nz
template<typename O, typename F, typename Tuple> auto Apply(O& object, F&& fn, Tuple&& t);
template<typename T> ByteArray ComputeHash(HashType hash, const T& v);
template<typename T> ByteArray ComputeHash(AbstractHash* hash, const T& v);
template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept;
template<typename T> std::size_t CountOf(const T& c);
template<typename T> void HashCombine(std::size_t& seed, const T& v);
template<typename T>
struct PointedType
{
using type = void; //< FIXME: I can't make SFINAE work
};
template<typename T>
struct TypeTag {};
@@ -33,10 +41,10 @@ namespace Nz
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value);
inline bool Unserialize(UnserializationContext& context, bool* value);
inline bool Unserialize(SerializationContext& context, bool* value);
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value);
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value);
}
#include <Nazara/Core/Algorithm.inl>

View File

@@ -30,6 +30,16 @@ namespace Nz
}
}
/*!
* \ingroup core
* \brief Applies the tuple to the function (e.g. calls the function using the tuple content as arguments)
* \return The result of the function
*
* \param fn Function
* \param t Tuple of arguments for the function
*
* \see Apply
*/
template<typename F, typename Tuple>
auto Apply(F&& fn, Tuple&& t)
{
@@ -38,6 +48,17 @@ namespace Nz
return Detail::ApplyImplFunc(std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \ingroup core
* \brief Applies the tuple to the member function on an object (e.g. calls the member function using the tuple content as arguments)
* \return The result of the member function called
*
* \param object Object of a class
* \param fn Member function
* \param t Tuple of arguments for the member function
*
* \see Apply
*/
template<typename O, typename F, typename Tuple>
auto Apply(O& object, F&& fn, Tuple&& t)
{
@@ -46,15 +67,42 @@ namespace Nz
return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \ingroup core
* \brief Computes the hash of a hashable object
* \return A bytearray which represents the hash
*
* \param hash Enumeration of type HashType
* \param v Object to hash
*
* \remark a HashAppend specialization for type T is required
*
* \see ComputeHash
*/
template<typename T>
ByteArray ComputeHash(HashType hash, const T& v)
{
return ComputeHash(AbstractHash::Get(hash).get(), v);
}
/*!
* \ingroup core
* \brief Computes the hash of a hashable object
* \return A bytearray which represents the hash
*
* \param hash Pointer to abstract hash
* \param v Object to hash
*
* \remark Produce a NazaraAssert if pointer to Abstracthash is invalid
* \remark a HashAppend specialization for type T is required
*
* \see ComputeHash
*/
template<typename T>
ByteArray ComputeHash(AbstractHash* hash, const T& v)
{
NazaraAssert(hash != nullptr, "Invalid abstracthash pointer");
hash->Begin();
HashAppend(hash, v);
@@ -62,7 +110,44 @@ namespace Nz
return hash->End();
}
// Algorithme venant de CityHash par Google
/*!
* \ingroup core
* \brief Returns the number of elements in a C-array
* \return The number of elements
*
* \param name C-array
*
* \see CountOf
*/
template<typename T, std::size_t N>
constexpr std::size_t CountOf(T(&name)[N]) noexcept
{
return N;
}
/*!
* \ingroup core
* \brief Returns the number of elements in a container
* \return The number of elements
*
* \param c Container with the member function "size()"
*
* \see CountOf
*/
template<typename T>
std::size_t CountOf(const T& c)
{
return c.size();
}
/*!
* \ingroup core
* \brief Combines two hash in one
*
* \param seed First value that will be modified (expected to be 64bits)
* \param v Second value to hash
*/
// Algorithm from CityHash by Google
// http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co
template<typename T>
void HashCombine(std::size_t& seed, const T& v)
@@ -79,6 +164,21 @@ namespace Nz
seed = static_cast<std::size_t>(b * kMul);
}
template<typename T> struct PointedType<T*> {typedef T type;};
template<typename T> struct PointedType<T* const> {typedef T type;};
template<typename T> struct PointedType<T* volatile> {typedef T type;};
template<typename T> struct PointedType<T* const volatile> {typedef T type;};
/*!
* \ingroup core
* \brief Serializes a boolean
* \return true if serialization succedeed
*
* \param context Context for the serialization
* \param value Boolean to serialize
*
* \see Serialize, Unserialize
*/
inline bool Serialize(SerializationContext& context, bool value)
{
if (context.currentBitPos == 8)
@@ -96,6 +196,16 @@ namespace Nz
return true;
}
/*!
* \ingroup core
* \brief Serializes an arithmetic type
* \return true if serialization succedeed
*
* \param context Context for the serialization
* \param value Arithmetic type to serialize
*
* \see Serialize, Unserialize
*/
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Serialize(SerializationContext& context, T value)
{
@@ -114,10 +224,18 @@ namespace Nz
return context.stream->Write(&value, sizeof(T)) == sizeof(T);
}
inline bool Unserialize(UnserializationContext& context, bool* value)
/*!
* \ingroup core
* \brief Unserializes a boolean
* \return true if unserialization succedeed
*
* \param context Context for the unserialization
* \param value Pointer to boolean to unserialize
*
* \see Serialize, Unserialize
*/
inline bool Unserialize(SerializationContext& context, bool* value)
{
NazaraAssert(value, "Invalid data pointer");
if (context.currentBitPos == 8)
{
if (!Unserialize(context, &context.currentByte))
@@ -134,8 +252,20 @@ namespace Nz
return true;
}
/*!
* \ingroup core
* \brief Unserializes an arithmetic type
* \return true if unserialization succedeed
*
* \param context Context for the unserialization
* \param value Pointer to arithmetic type to serialize
*
* \remark Produce a NazaraAssert if pointer to value is invalid
*
* \see Serialize, Unserialize
*/
template<typename T>
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(UnserializationContext& context, T* value)
std::enable_if_t<std::is_arithmetic<T>::value, bool> Unserialize(SerializationContext& context, T* value)
{
NazaraAssert(value, "Invalid data pointer");

View File

@@ -9,6 +9,7 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/String.hpp>
#include <limits>
#include <memory>
#include <type_traits>
@@ -31,9 +32,9 @@ namespace Nz
Bitset(const Bitset& bitset) = default;
explicit Bitset(const String& bits);
Bitset(Bitset&& bitset) noexcept = default;
~Bitset() = default;
~Bitset() noexcept = default;
void Clear();
void Clear() noexcept;
unsigned int Count() const;
void Flip();
@@ -89,9 +90,9 @@ namespace Nz
Bitset& operator|=(const Bitset& bitset);
Bitset& operator^=(const Bitset& bitset);
static Block fullBitMask;
static unsigned int bitsPerBlock;
static unsigned int npos;
static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
static constexpr unsigned int bitsPerBlock = std::numeric_limits<Block>::digits;
static constexpr unsigned int npos = std::numeric_limits<unsigned int>::max();
private:
unsigned int FindFirstFrom(unsigned int blockIndex) const;

File diff suppressed because it is too large Load Diff

View File

@@ -3,62 +3,146 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <cstdio>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \brief Constructs a ByteArray object with a reserved size
*
* \param n Space reserved
*/
inline ByteArray::ByteArray(size_type n) :
m_array()
{
m_array.reserve(n);
}
/*!
* \brief Constructs a ByteArray object with a raw memory and a size
*
* \param ptr Pointer to raw memory
* \param n Size that can be accessed
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
inline ByteArray::ByteArray(const void* buffer, size_type n) :
m_array(static_cast<const_pointer>(buffer), static_cast<const_pointer>(buffer) + n)
{
}
/*!
* \brief Constructs a ByteArray object with n times the same value
*
* \param n Number of repetitions
* \param value Value to repeat
*/
inline ByteArray::ByteArray(size_type n, const value_type value) :
m_array(n, value)
{
}
/*!
* \brief Constructs a ByteArray object from two iterators
*
* \param first First iterator
* \param last Second iterator
*/
template <class InputIterator>
ByteArray::ByteArray(InputIterator first, InputIterator last) :
m_array(first, last)
{
}
/*!
* \brief Appends the content of raw memory
*
* \param ptr Constant pointer to raw memory
* \param n Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*
* \see Insert
*/
inline ByteArray::iterator ByteArray::Append(const void* buffer, size_type n)
{
return Insert(end(), static_cast<const_pointer>(buffer), static_cast<const_pointer>(buffer) + n);
}
/*!
* \brief Appends another array of bytes
*
* \param other ByteArray to add
*
* \see Insert
*/
inline ByteArray::iterator ByteArray::Append(const ByteArray& other)
{
return Insert(end(), other.begin(), other.end());
}
/*!
* \brief Assigns this with n times the same value
*
* \param n Number of repetitions
* \param value Value to repeat
*/
inline void ByteArray::Assign(size_type n, value_type value)
{
m_array.assign(n, value);
}
/*!
* \brief Assigns this with the content between two iterators
*
* \param first First iterator
* \param last Second iterator
*/
template <class InputIterator>
void ByteArray::Assign(InputIterator first, InputIterator last)
{
m_array.assign(first, last);
}
/*!
* \brief Gets last element
* \return A reference to last element
*
* \remark If ByteArray is empty, behaviour is undefined
*/
inline ByteArray::reference ByteArray::Back()
{
return m_array.back();
}
/*!
* \brief Gets last element
* \return A constant reference to last element
*
* \remark If ByteArray is empty, behaviour is undefined
*/
inline ByteArray::const_reference ByteArray::Back() const
{
return m_array.back();
}
/*!
* \brief Clears the content of the string
*
* \param keepBuffer Should the buffer be kept
*/
inline void ByteArray::Clear(bool keepBuffer)
{
m_array.clear();
@@ -66,142 +150,326 @@ namespace Nz
m_array.shrink_to_fit();
}
/*!
* \brief Erases an element from the byte array
*
* \param pos Iterator to the element
*/
inline ByteArray::iterator ByteArray::Erase(const_iterator pos)
{
return m_array.erase(pos);
}
/*!
* \brief Erases the elements between the two pointers from the byte array
*
* \param first First iterator
* \param last Second iterator
*/
inline ByteArray::iterator ByteArray::Erase(const_iterator first, const_iterator last)
{
return m_array.erase(first, last);
}
/*!
* \brief Gets first element
* \return A reference to first element
*
* \remark If ByteArray is empty, behaviour is undefined
*/
inline ByteArray::reference ByteArray::Front()
{
return m_array.front();
}
/*!
* \brief Gets first element
* \return A constant reference to first element
*
* \remark If ByteArray is empty, behaviour is undefined
*/
inline ByteArray::const_reference ByteArray::Front() const
{
return m_array.front();
}
/*!
* \brief Gets the internal allocator of the byte array
* \return Allocator
*/
inline ByteArray::allocator_type ByteArray::GetAllocator() const
{
return m_array.get_allocator();
}
/*!
* \brief Gets the raw buffer
* \return Raw buffer
*/
inline ByteArray::pointer ByteArray::GetBuffer()
{
return m_array.data();
}
/*!
* \brief Gets the capacity of the byte array
* \return Capacity of the byte array
*/
inline ByteArray::size_type ByteArray::GetCapacity() const noexcept
{
return m_array.capacity();
}
/*!
* \brief Gets the raw buffer
* \return Raw buffer
*/
inline ByteArray::const_pointer ByteArray::GetConstBuffer() const
{
return m_array.data();
}
/*!
* \brief Gets the maximal size supported by the byte array
* \return Biggest size handled
*/
inline ByteArray::size_type ByteArray::GetMaxSize() const noexcept
{
return m_array.max_size();
}
/*!
* \brief Gets the size of the byte array
* \return Size of the byte array
*/
inline ByteArray::size_type ByteArray::GetSize() const noexcept
{
return m_array.size();
}
/*!
* \brief Returns a sub byte array of the byte array
* \return Sub byte array
*
* \param startPos First iterator
* \param endPos Second iterator
*/
inline ByteArray ByteArray::GetSubArray(const_iterator startPos, const_iterator endPos) const
{
return ByteArray(startPos, endPos);
}
/*!
* \brief Inserts the content of raw memory at the iterator position
*
* \param pos Iterator to the position
* \param buffer Constant pointer to raw memory
* \param n Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const void* buffer, size_type n)
{
return m_array.insert(pos, static_cast<const_pointer>(buffer), static_cast<const_pointer>(buffer) + n);
}
/*!
* \brief Inserts the content of another byte array at the iterator position
*
* \param pos Iterator to the position
* \param other Other byte array
*/
inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const ByteArray& other)
{
return m_array.insert(pos, other.begin(), other.end());
}
/*!
* \brief Inserts n times the same value at the iterator position
*
* \param pos Iterator to the position
* \param n Number of repetitions
* \param value Value to repeat
*/
inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte)
{
return m_array.insert(pos, n, byte);
}
/*!
* \brief Inserts the content from two iterators at the iterator position
*
* \param pos Iterator to the position
* \param first First iterator
* \param last Second iterator
*/
template <class InputIterator>
ByteArray::iterator ByteArray::Insert(const_iterator pos, InputIterator first, InputIterator last)
{
return m_array.insert(pos, first, last);
}
/*!
* \brief Checks whether the byte array is empty
* \return true if byte array is empty
*/
inline bool ByteArray::IsEmpty() const noexcept
{
return m_array.empty();
}
/*!
* \brief Erases the last element
*
* \remark If byte array is empty, the behaviour is undefined
*/
inline void ByteArray::PopBack()
{
Erase(end() - 1);
}
/*!
* \brief Erases the first element
*
* \remark If byte array is empty, the behaviour is undefined
*/
inline void ByteArray::PopFront()
{
Erase(begin());
}
/*!
* \brief Prepends the content of raw memory
*
* \param ptr Constant pointer to raw memory
* \param n Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*
* \see Insert
*/
inline ByteArray::iterator ByteArray::Prepend(const void* buffer, size_type n)
{
return Insert(begin(), buffer, n);
}
/*!
* \brief Prepends another array of bytes
*
* \param other ByteArray to add
*
* \see Insert
*/
inline ByteArray::iterator ByteArray::Prepend(const ByteArray& other)
{
return Insert(begin(), other);
}
/*!
* \brief Pushes the byte at the end
*
* \param byte Byte to add
*/
inline void ByteArray::PushBack(const value_type byte)
{
m_array.push_back(byte);
}
/*!
* \brief Pushes the byte at the beginning
*
* \param byte Byte to add
*/
inline void ByteArray::PushFront(const value_type byte)
{
m_array.insert(begin(), 1, byte);
}
/*!
* \brief Reserves enough memory for the buffer size
*
* \param bufferSize Size of the buffer to allocate
*
* \remark If bufferSize is smaller than the old one, nothing is done
*/
inline void ByteArray::Reserve(size_type bufferSize)
{
m_array.reserve(bufferSize);
}
/*!
* \brief Resizes the string
* \return A reference to this
*
* \param newSize Target size
*/
inline void ByteArray::Resize(size_type newSize)
{
m_array.resize(newSize);
}
/*!
* \brief Resizes the string
* \return A reference to this
*
* \param newSize Target size
* \param byte Byte to add if newSize is greather than actual size
*/
inline void ByteArray::Resize(size_type newSize, const value_type byte)
{
m_array.resize(newSize, byte);
}
/*!
* \brief Releases the excedent memory
*/
inline void ByteArray::ShrinkToFit()
{
m_array.shrink_to_fit();
}
/*!
* \brief Swaps the content with the other byte array
*
* \param other Other byte array to swap with
*/
inline void ByteArray::Swap(ByteArray& other)
{
m_array.swap(other.m_array);
}
/*!
* \brief Gives a string representation in base 16
* \return String in base 16
*/
inline String ByteArray::ToHex() const
{
std::size_t length = m_array.size() * 2;
@@ -213,76 +481,153 @@ namespace Nz
return hexOutput;
}
/*!
* \brief Gives a string representation
* \return String where each byte is converted to char
*/
inline String ByteArray::ToString() const
{
return String(reinterpret_cast<const char*>(GetConstBuffer()), GetSize());
}
/*!
* \brief Returns an iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::iterator ByteArray::begin() noexcept
{
return m_array.begin();
}
/*!
* \brief Returns an iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::const_iterator ByteArray::begin() const noexcept
{
return m_array.begin();
}
/*!
* \brief Returns a constant iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::const_iterator ByteArray::cbegin() const noexcept
{
return m_array.cbegin();
}
/*!
* \brief Returns a constant iterator pointing to the end of the string
* \return End of the string
*/
inline ByteArray::const_iterator ByteArray::cend() const noexcept
{
return m_array.cend();
}
/*!
* \brief Returns a constant reversed iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::const_reverse_iterator ByteArray::crbegin() const noexcept
{
return m_array.crbegin();
}
/*!
* \brief Returns a constant reversed iterator pointing to the end of the string
* \return End of the string
*/
inline ByteArray::const_reverse_iterator ByteArray::crend() const noexcept
{
return m_array.crend();
}
/*!
* \brief Checks whether the byte array is empty
* \return true if byte array is empty
*/
inline bool ByteArray::empty() const noexcept
{
return m_array.empty();
}
/*!
* \brief Returns an iterator pointing to the end of the string
* \return End of the string
*/
inline ByteArray::iterator ByteArray::end() noexcept
{
return m_array.end();
}
/*!
* \brief Returns an iterator pointing to the end of the string
* \return End of the string
*/
inline ByteArray::const_iterator ByteArray::end() const noexcept
{
return m_array.end();
}
/*!
* \brief Returns a reversed iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::reverse_iterator ByteArray::rbegin() noexcept
{
return m_array.rbegin();
}
/*!
* \brief Returns a reversed iterator pointing to the beggining of the string
* \return Beggining of the string
*/
inline ByteArray::const_reverse_iterator ByteArray::rbegin() const noexcept
{
return m_array.rbegin();
}
/*!
* \brief Returns a reversed iterator pointing to the end of the string
* \return End of the string
*/
inline ByteArray::reverse_iterator ByteArray::rend() noexcept
{
return m_array.rend();
}
/*!
* \brief Gets the size of the byte array
* \return Size of the byte array
*/
inline ByteArray::size_type ByteArray::size() const noexcept
{
return GetSize();
}
/*!
* \brief Gets the ith byte
* \return A reference to the byte at the ith position
*
* \remark Produces a NazaraAssert if pos is greather than the size
*/
inline ByteArray::reference ByteArray::operator[](size_type pos)
{
NazaraAssert(pos < GetSize(), "Index out of range");
@@ -290,6 +635,13 @@ namespace Nz
return m_array[pos];
}
/*!
* \brief Gets the ith byte
* \return A constant reference to the byte at the ith position
*
* \remark Produces a NazaraAssert if pos is greather than the size
*/
inline ByteArray::const_reference ByteArray::operator[](size_type pos) const
{
NazaraAssert(pos < GetSize(), "Index out of range");
@@ -297,6 +649,13 @@ namespace Nz
return m_array[pos];
}
/*!
* \brief Concatenates the byte array to another
* \return ByteArray which is the result of the concatenation
*
* \param other ByteArray to add
*/
inline ByteArray ByteArray::operator+(const ByteArray& other) const
{
ByteArray tmp(*this);
@@ -305,6 +664,13 @@ namespace Nz
return tmp;
}
/*!
* \brief Concatenates the byte array to this byte array
* \return A reference to this
*
* \param other ByteArray to add
*/
inline ByteArray& ByteArray::operator+=(const ByteArray& other)
{
Append(other);
@@ -312,31 +678,79 @@ namespace Nz
return *this;
}
/*!
* \brief Checks whether the first byte array is equal to the second byte array
* \return true if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator==(const ByteArray& rhs) const
{
return m_array == rhs.m_array;
}
/*!
* \brief Checks whether the first byte array is equal to the second byte array
* \return false if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator!=(const ByteArray& rhs) const
{
return !operator==(rhs);
}
/*!
* \brief Checks whether the first byte array is less than the second byte array
* \return true if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator<(const ByteArray& rhs) const
{
return m_array < rhs.m_array;
}
/*!
* \brief Checks whether the first byte array is less or equal than the second byte array
* \return true if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator<=(const ByteArray& rhs) const
{
return m_array <= rhs.m_array;
}
/*!
* \brief Checks whether the first byte array is greather than the second byte array
* \return true if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator>(const ByteArray& rhs) const
{
return m_array > rhs.m_array;
}
/*!
* \brief Checks whether the first byte array is greather or equal than the second byte array
* \return true if it is the case
*
* \param first ByteArray to compare in left hand side
* \param second ByteArray to compare in right hand side
*/
inline bool ByteArray::operator>=(const ByteArray& rhs) const
{
return m_array >= rhs.m_array;
@@ -351,8 +765,17 @@ namespace Nz
namespace std
{
/*!
* \brief Swaps two byte arrays, specialisation of std
*
* \param lhs First byte array
* \param rhs Second byte array
*/
inline void swap(Nz::ByteArray& lhs, Nz::ByteArray& rhs)
{
lhs.Swap(rhs);
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_BYTESTREAM_HPP
#define NAZARA_BYTESTREAM_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Serialization.hpp>
#include <Nazara/Core/Stream.hpp>
#include <memory>
namespace Nz
{
class NAZARA_CORE_API ByteStream
{
public:
inline ByteStream(Stream* stream = nullptr);
ByteStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
ByteStream(void* ptr, Nz::UInt64 size);
ByteStream(const void* ptr, Nz::UInt64 size);
ByteStream(const ByteStream&) = delete;
inline ByteStream(ByteStream&& stream);
~ByteStream();
inline Endianness GetDataEndianness() const;
inline Nz::UInt64 GetSize() const;
inline Stream* GetStream() const;
inline bool FlushBits();
inline std::size_t Read(void* ptr, std::size_t size);
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream* stream);
void SetStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
void SetStream(void* ptr, Nz::UInt64 size);
void SetStream(const void* ptr, Nz::UInt64 size);
inline void Write(const void* data, std::size_t size);
template<typename T>
ByteStream& operator>>(T& value);
template<typename T>
ByteStream& operator<<(const T& value);
ByteStream& operator=(const ByteStream&) = delete;
inline ByteStream& operator=(ByteStream&&);
private:
virtual void OnEmptyStream();
std::unique_ptr<Stream> m_ownedStream;
SerializationContext m_context;
};
}
#include <Nazara/Core/ByteStream.inl>
#endif // NAZARA_BYTESTREAM_HPP

View File

@@ -0,0 +1,226 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \brief Constructs a ByteStream object with a stream
*/
inline ByteStream::ByteStream(Stream* stream)
{
m_context.stream = stream;
}
/*!
* \brief Constructs a ByteStream object by move semantic
*
* \param stream ByteStream to move into this
*/
inline ByteStream::ByteStream(ByteStream&& stream) :
m_ownedStream(std::move(stream.m_ownedStream)),
m_context(stream.m_context)
{
stream.m_context.stream = nullptr;
}
/*!
* \brief Destructs the object and calls FlushBits
*
* \remark Produces a NazaraWarning if flush did not work
*
* \see FlushBits
*/
inline ByteStream::~ByteStream()
{
if (!FlushBits())
NazaraWarning("Failed to flush bits at serializer destruction");
}
/*!
* \brief Gets the stream endianness
* \return Type of the endianness
*/
inline Endianness ByteStream::GetDataEndianness() const
{
return m_context.endianness;
}
/*!
* \brief Gets the size of the byte stream
* \return Size of the stream
*/
inline Nz::UInt64 ByteStream::GetSize() const
{
if (m_context.stream)
return m_context.stream->GetSize();
else
return 0;
}
/*!
* \brief Gets the internal stream
* \return Internal stream
*/
inline Stream* ByteStream::GetStream() const
{
return m_context.stream;
}
/*!
* \brief Flushes the stream
* \return true if flushing is successful
*/
inline bool ByteStream::FlushBits()
{
if (!m_context.stream)
return true;
if (m_context.currentBitPos != 8)
{
m_context.currentBitPos = 8; //< To prevent Serialize to flush bits itself
if (!Serialize<UInt8>(m_context, m_context.currentByte))
return false;
}
return true;
}
/*!
* \brief Reads data
* \return Number of data read
*
* \param buffer Preallocated buffer to contain information read
* \param size Size of the read and thus of the buffer
*/
inline std::size_t ByteStream::Read(void* ptr, std::size_t size)
{
if (!m_context.stream)
OnEmptyStream();
FlushBits();
return m_context.stream->Read(ptr, size);
}
/*!
* \brief Sets the stream endianness
*
* \param Type of the endianness
*/
inline void ByteStream::SetDataEndianness(Endianness endiannes)
{
m_context.endianness = endiannes;
}
/*!
* \brief Sets this with a stream
*
* \param stream Stream existing
*
* \remark Produces a NazaraAssert if stream is invalid
*/
inline void ByteStream::SetStream(Stream* stream)
{
NazaraAssert(stream, "Invalid stream");
// We don't want to lose some bits..
FlushBits();
m_context.stream = stream;
m_ownedStream.reset();
}
/*!
* \brief Writes data
* \return Number of data written
*
* \param buffer Preallocated buffer containing information to write
* \param size Size of the writting and thus of the buffer
*
* \remark Produces a NazaraAssert if buffer is nullptr
*/
inline void ByteStream::Write(const void* data, std::size_t size)
{
if (!m_context.stream)
OnEmptyStream();
FlushBits();
m_context.stream->Write(data, size);
}
/*!
* \brief Outputs a data from the stream
* \return A reference to this
*
* \param value Value to unserialize
*
* \remark Produces a NazaraError if unserialization failed
*/
template<typename T>
ByteStream& ByteStream::operator>>(T& value)
{
if (!m_context.stream)
OnEmptyStream();
if (!Unserialize(m_context, &value))
NazaraError("Failed to serialize value");
return *this;
}
/*!
* \brief Adds the data to the stream
* \return A reference to this
*
* \param value Value to serialize
*
* \remark Produces a NazaraError if serialization failed
*/
template<typename T>
ByteStream& ByteStream::operator<<(const T& value)
{
if (!m_context.stream)
OnEmptyStream();
if (!Serialize(m_context, value))
NazaraError("Failed to serialize value");
return *this;
}
/*!
* \brief Moves the other byte stream into this
* \return A reference to this
*
* \param stream ByteStream to move in this
*/
inline ByteStream& ByteStream::operator=(ByteStream&& stream)
{
m_context = stream.m_context;
m_ownedStream = std::move(stream.m_ownedStream);
stream.m_context.stream = nullptr;
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -7,17 +7,39 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::CallOnExit
* \brief Core class that represents a function to call at the end of the scope
*/
/*!
* \brief Constructs a CallOnExit object with a function
*
* \param func Function to call on exit
*/
inline CallOnExit::CallOnExit(Func func) :
m_func(func)
{
}
/*!
* \brief Destructs the object and calls the function
*/
inline CallOnExit::~CallOnExit()
{
if (m_func)
m_func();
}
/*!
* \brief Calls the function and sets the new callback
*
* \param func Function to call on exit
*/
inline void CallOnExit::CallAndReset(Func func)
{
if (m_func)
@@ -26,6 +48,12 @@ namespace Nz
Reset(func);
}
/*!
* \brief Resets the function
*
* \param func Function to call on exit
*/
inline void CallOnExit::Reset(Func func)
{
m_func = func;

View File

@@ -13,6 +13,8 @@
namespace Nz
{
struct SerializationContext;
class Color
{
public:
@@ -62,6 +64,9 @@ namespace Nz
private:
static float Hue2RGB(float v1, float v2, float vH);
};
inline bool Serialize(SerializationContext& context, const Color& color);
inline bool Unserialize(SerializationContext& context, Color* color);
}
std::ostream& operator<<(std::ostream& out, const Nz::Color& color);

View File

@@ -2,6 +2,7 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <algorithm>
#include <cmath>
@@ -11,10 +12,29 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Color
* \brief Core class that represents a color
*/
/*!
* \brief Constructs a Color object by default
*/
inline Color::Color()
{
}
/*!
* \brief Constructs a Color object with values
*
* \param red Red value
* \param green Green value
* \param blue Blue value
* \param alpha Alpha value
*/
inline Color::Color(UInt8 red, UInt8 green, UInt8 blue, UInt8 alpha) :
r(red),
g(green),
@@ -23,6 +43,12 @@ namespace Nz
{
}
/*!
* \brief Constructs a Color object with a light level
*
* \param lightness Value for r, g and b
*/
inline Color::Color(UInt8 lightness) :
r(lightness),
g(lightness),
@@ -31,6 +57,13 @@ namespace Nz
{
}
/*!
* \brief Constructs a Color object with values
*
* \param vec[3] vec[0] = red value, vec[1] = green value, vec[2] = blue value
* \param alpha Alpha value
*/
inline Color::Color(UInt8 vec[3], UInt8 alpha) :
r(vec[0]),
g(vec[1]),
@@ -39,6 +72,11 @@ namespace Nz
{
}
/*!
* \brief Converts this to string
* \return String representation of the object "Color(r, g, b[, a])"
*/
inline String Color::ToString() const
{
StringStream ss;
@@ -52,6 +90,13 @@ namespace Nz
return ss;
}
/*!
* \brief Adds two colors together
* \return Color which is the sum
*
* \param color Other color
*/
inline Color Color::operator+(const Color& color) const
{
///TODO: Improve this shit
@@ -64,6 +109,13 @@ namespace Nz
return c;
}
/*!
* \brief Multiplies two colors together
* \return Color which is the product
*
* \param color Other color
*/
inline Color Color::operator*(const Color& color) const
{
///TODO: Improve this shit
@@ -76,48 +128,104 @@ namespace Nz
return c;
}
/*!
* \brief Adds the color to this
* \return Color which is the sum
*
* \param color Other color
*/
inline Color Color::operator+=(const Color& color)
{
return operator=(operator+(color));
}
/*!
* \brief Multiplies the color to this
* \return Color which is the product
*
* \param color Other color
*/
inline Color Color::operator*=(const Color& color)
{
return operator=(operator*(color));
}
/*!
* \brief Checks whether the two colors are equal
* \return true if it is the case
*
* \param color Color to compare
*/
inline bool Color::operator==(const Color& color) const
{
return r == color.r && g == color.g && b == color.b && a == color.a;
}
/*!
* \brief Checks whether the two colors are equal
* \return false if it is the case
*
* \param color Color to compare
*/
inline bool Color::operator!=(const Color& color) const
{
return !operator==(color);
}
// Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH
// Algorithm coming from http://www.easyrgb.com/index.php?X=MATH
/*!
* \brief Converts CMY representation to RGB
* \return Color resulting
*
* \param cyan Cyan component
* \param magenta Magenta component
* \param yellow Yellow component
*/
inline Color Color::FromCMY(float cyan, float magenta, float yellow)
{
return Color(static_cast<UInt8>((1.f-cyan)*255.f), static_cast<UInt8>((1.f-magenta)*255.f), static_cast<UInt8>((1.f-yellow)*255.f));
}
/*!
* \brief Converts CMYK representation to RGB
* \return Color resulting
*
* \param cyan Cyan component
* \param magenta Magenta component
* \param yellow Yellow component
* \param black Black component
*/
inline Color Color::FromCMYK(float cyan, float magenta, float yellow, float black)
{
return FromCMY(cyan * (1.f - black) + black,
magenta * (1.f - black) + black,
yellow * (1.f - black) + black);
magenta * (1.f - black) + black,
yellow * (1.f - black) + black);
}
/*!
* \brief Converts HSL representation to RGB
* \return Color resulting
*
* \param hue Hue component
* \param saturation Saturation component
* \param lightness Lightness component
*/
inline Color Color::FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness)
{
if (saturation == 0)
{
// RGB results from 0 to 255
return Color(lightness * 255,
lightness * 255,
lightness * 255);
lightness * 255,
lightness * 255);
}
else
{
@@ -135,11 +243,20 @@ namespace Nz
float v1 = 2.f * l - v2;
return Color(static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))),
static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h)),
static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h - (1.f/3.f))));
static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h)),
static_cast<UInt8>(255.f * Hue2RGB(v1, v2, h - (1.f/3.f))));
}
}
/*!
* \brief Converts HSV representation to RGB
* \return Color resulting
*
* \param hue Hue component
* \param saturation Saturation component
* \param value Value component
*/
inline Color Color::FromHSV(float hue, float saturation, float value)
{
if (NumberEquals(saturation, 0.f))
@@ -201,11 +318,28 @@ namespace Nz
return Color(static_cast<UInt8>(r*255.f), static_cast<UInt8>(g*255.f), static_cast<UInt8>(b*255.f));
}
}
/*!
* \brief Converts XYZ representation to RGB
* \return Color resulting
*
* \param vec Vector3 representing the space color
*/
inline Color Color::FromXYZ(const Vector3f& vec)
{
return FromXYZ(vec.x, vec.y, vec.z);
}
/*!
* \brief Converts XYZ representation to RGB
* \return Color resulting
*
* \param x X component
* \param y Y component
* \param z Z component
*/
inline Color Color::FromXYZ(float x, float y, float z)
{
x /= 100.f; // X from 0 to 95.047
@@ -234,6 +368,15 @@ namespace Nz
return Color(static_cast<UInt8>(r * 255.f), static_cast<UInt8>(g * 255.f), static_cast<UInt8>(b * 255.f));
}
/*!
* \brief Converts RGB representation to CMYK
*
* \param color Color to transform
* \param cyan Cyan component
* \param magenta Magenta component
* \param yellow Yellow component
*/
inline void Color::ToCMY(const Color& color, float* cyan, float* magenta, float* yellow)
{
*cyan = 1.f - color.r/255.f;
@@ -241,6 +384,15 @@ namespace Nz
*yellow = 1.f - color.b/255.f;
}
/*!
* \brief Converts RGB representation to CMYK
*
* \param color Color to transform
* \param cyan Cyan component
* \param magenta Magenta component
* \param yellow Yellow component
*/
inline void Color::ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black)
{
float c, m, y;
@@ -265,6 +417,15 @@ namespace Nz
*black = k;
}
/*!
* \brief Converts RGB representation to HSL
*
* \param color Color to transform
* \param hue Hue component
* \param saturation Saturation component
* \param lightness Lightness component
*/
inline void Color::ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness)
{
float r = color.r / 255.f;
@@ -315,6 +476,15 @@ namespace Nz
}
}
/*!
* \brief Converts RGB representation to HSV
*
* \param color Color to transform
* \param hue Hue component
* \param saturation Saturation component
* \param value Value component
*/
inline void Color::ToHSV(const Color& color, float* hue, float* saturation, float* value)
{
float r = color.r / 255.f;
@@ -361,11 +531,27 @@ namespace Nz
}
}
/*!
* \brief Converts RGB representation to XYZ
*
* \param color Color to transform
* \param vec Vector3 representing the space color
*/
inline void Color::ToXYZ(const Color& color, Vector3f* vec)
{
return ToXYZ(color, &vec->x, &vec->y, &vec->z);
}
/*!
* \brief Converts RGB representation to XYZ
*
* \param color Color to transform
* \param x X component
* \param y Y component
* \param z Z component
*/
inline void Color::ToXYZ(const Color& color, float* x, float* y, float* z)
{
float r = color.r/255.f; //R from 0 to 255
@@ -397,6 +583,15 @@ namespace Nz
*z = r*0.0193f + g*0.1192f + b*0.9505f;
}
/*!
* \brief Converts HUE representation to RGV
* \return RGB corresponding
*
* \param v1 V1 component
* \param v2 V2 component
* \param vH VH component
*/
inline float Color::Hue2RGB(float v1, float v2, float vH)
{
if (vH < 0.f)
@@ -415,8 +610,64 @@ namespace Nz
return v1 + (v2 - v1)*(2.f/3.f - vH)*6;
return v1;
}
/*!
* \brief Serializes a Color
* \return true if successfully serialized
*
* \param context Serialization context
* \param color Input color
*/
inline bool Serialize(SerializationContext& context, const Color& color)
{
if (!Serialize(context, color.r))
return false;
if (!Serialize(context, color.g))
return false;
if (!Serialize(context, color.b))
return false;
if (!Serialize(context, color.a))
return false;
return true;
}
/*!
* \brief Unserializes a Color
* \return true if successfully unserialized
*
* \param context Serialization context
* \param color Output color
*/
inline bool Unserialize(SerializationContext& context, Color* color)
{
if (!Unserialize(context, &color->r))
return false;
if (!Unserialize(context, &color->g))
return false;
if (!Unserialize(context, &color->b))
return false;
if (!Unserialize(context, &color->a))
return false;
return true;
}
}
}
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param color The color to output
*/
inline std::ostream& operator<<(std::ostream& out, const Nz::Color& color)
{

View File

@@ -19,7 +19,7 @@ namespace Nz
public:
ConditionVariable();
ConditionVariable(const ConditionVariable&) = delete;
ConditionVariable(ConditionVariable&&) = delete; ///TODO
inline ConditionVariable(ConditionVariable&& condition) noexcept;
~ConditionVariable();
void Signal();
@@ -29,11 +29,13 @@ namespace Nz
bool Wait(Mutex* mutex, UInt32 timeout);
ConditionVariable& operator=(const ConditionVariable&) = delete;
ConditionVariable& operator=(ConditionVariable&&) = delete; ///TODO
inline ConditionVariable& operator=(ConditionVariable&& condition) noexcept;
private:
ConditionVariableImpl* m_impl;
};
}
#include <Nazara/Core/ConditionVariable.inl>
#endif // NAZARA_CONDITIONVARIABLE_HPP

View File

@@ -0,0 +1,25 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \class Nz::ConditionVariable
*/
/*!
* \brief Constructs a ConditionVariable object by moving another one
*/
inline ConditionVariable::ConditionVariable(ConditionVariable&& condition) noexcept :
m_impl(condition.m_impl)
{
condition.m_impl = nullptr;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -27,36 +27,41 @@
#ifndef NAZARA_CONFIG_CORE_HPP
#define NAZARA_CONFIG_CORE_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
/*!
* \defgroup core (NazaraCore) Core module
* Core/System module including classes to handle threading, time, hardware info, memory management, etc...
*/
// Précision des réels lors de la transformation en chaîne de caractère (Max. chiffres après la virgule)
/// Each modification of a parameter needs a recompilation of the module
// Precision of reals when transformed into string (Max. numbers after the coma)
#define NAZARA_CORE_DECIMAL_DIGITS 6
// Duplique la sortie du log sur le flux de sortie standard (cout)
// Duplicate the log output on the standard output flux (cout)
#define NAZARA_CORE_DUPLICATE_LOG_TO_COUT 0
// Teste les assertions
// Checks the assertions
#define NAZARA_CORE_ENABLE_ASSERTS 0
// Appelle exit dès qu'une assertion est invalide
// Call exit when an assertion is invalid
#define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1
// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash)
// Size of buffer when reading entirely a file (ex: Hash)
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
// Incorpore la table Unicode Character Data (Nécessaires pour faire fonctionner le flag String::HandleUTF8)
// Incorporate the Unicode Character Data table (Necessary to make it work with the flag String::HandleUTF8)
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_CORE_MANAGE_MEMORY 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
// Activate the security tests based on the code (Advised for development)
#define NAZARA_CORE_SAFE 1
// Protège les classes des accès concurrentiels
// Protect the classes against data race
#define NAZARA_CORE_THREADSAFE 1
// Les classes à protéger des accès concurrentiels
// Classes to protect against data race
#define NAZARA_THREADSAFETY_CLOCK 0 // Clock
#define NAZARA_THREADSAFETY_DIRECTORY 1 // Directory
#define NAZARA_THREADSAFETY_DYNLIB 1 // DynLib
@@ -64,18 +69,19 @@
#define NAZARA_THREADSAFETY_LOG 1 // Log
#define NAZARA_THREADSAFETY_REFCOUNTED 1 // RefCounted
// Le nombre de spinlocks à utiliser avec les sections critiques de Windows (0 pour désactiver)
// Number of spinlocks to use with the Windows critical sections (0 to disable)
#define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096
// Optimise l'implémentation Windows avec certaines avancées de Windows vista (Casse la compatibilité XP)
// Optimize the Windows implementation with technologies of Windows vista (and greather) (Break the compatibility with XP)
#define NAZARA_CORE_WINDOWS_VISTA 0
/*
// Règle le temps entre le réveil du thread des timers et l'activation d'un timer (En millisecondes)
// Sets the time between waking thread timers and activating a timer (in milliseconds)
#define NAZARA_CORE_TIMER_WAKEUPTIME 10
*/
/// Vérification des valeurs et types de certaines constantes
/// Checking the values and types of certain constants
#include <Nazara/Core/ConfigCheck.hpp>
#if defined(NAZARA_STATIC)

View File

@@ -7,12 +7,12 @@
#ifndef NAZARA_CONFIG_CHECK_CORE_HPP
#define NAZARA_CONFIG_CHECK_CORE_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
/// This file is used to check the constant values defined in Config.hpp
#include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
// We fore the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
#undef NAZARA_CORE_MANAGE_MEMORY
#define NAZARA_CORE_MANAGE_MEMORY 0

View File

@@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
// We assume that Debug.hpp has already been included, same thing for Config.hpp
#if NAZARA_CORE_MANAGE_MEMORY
#undef delete
#undef new

View File

@@ -28,7 +28,7 @@
namespace Nz
{
using DynLibFunc = int (*)(); // Type "générique" de pointeur sur fonction
using DynLibFunc = int (*)(); // "Generic" type of poiter to function
class DynLibImpl;
@@ -56,7 +56,7 @@ namespace Nz
mutable String m_lastError;
DynLibImpl* m_impl;
};
};
}
#endif // NAZARA_DYNLIB_HPP

View File

@@ -11,12 +11,12 @@
#include <Nazara/Core/Enums.hpp>
#if !defined(NAZARA_BIG_ENDIAN) && !defined(NAZARA_LITTLE_ENDIAN)
// Détection automatique selon les macros du compilateur
// Automatic detection following macroes of compiler
#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__)
#define NAZARA_BIG_ENDIAN
#elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64) || defined(_M_I86) || \
defined(_M_IX86) || defined(_M_X64)
defined(_M_IX86) || defined(_M_X64)
#define NAZARA_LITTLE_ENDIAN
#else
#error Failed to identify endianness, you must define either NAZARA_BIG_ENDIAN or NAZARA_LITTLE_ENDIAN

View File

@@ -7,6 +7,12 @@
namespace Nz
{
/*!
* \ingroup core
* \brief Gets the platform endianness
* \return Type of the endianness
*/
inline constexpr Endianness GetPlatformEndianness()
{
#if defined(NAZARA_BIG_ENDIAN)
@@ -16,11 +22,21 @@ namespace Nz
#endif
}
/*!
* \ingroup core
* \brief Swaps the byte for endianness operations
*
* \param buffer Raw memory
* \param size Size to change endianness
*
* \remark If size is greather than the preallocated buffer, the behaviour is undefined
*/
inline void SwapBytes(void* buffer, unsigned int size)
{
UInt8* bytes = reinterpret_cast<UInt8*>(buffer);
UInt8* bytes = static_cast<UInt8*>(buffer);
unsigned int i = 0;
unsigned int j = size-1;
unsigned int j = size - 1;
while (i < j)
std::swap(bytes[i++], bytes[j--]);

View File

@@ -19,9 +19,9 @@ namespace Nz
enum CursorPosition
{
CursorPosition_AtBegin, // Début du fichier
CursorPosition_AtCurrent, // Position du pointeur
CursorPosition_AtEnd, // Fin du fichier
CursorPosition_AtBegin, // beginning of the file
CursorPosition_AtCurrent, // Position of the cursor
CursorPosition_AtEnd, // End of the file
CursorPosition_Max = CursorPosition_AtEnd
};
@@ -45,7 +45,7 @@ namespace Nz
ErrorFlag_ThrowException = 0x4,
ErrorFlag_ThrowExceptionDisabled = 0x8,
ErrorFlag_Max = ErrorFlag_ThrowExceptionDisabled*2-1
ErrorFlag_Max = ErrorFlag_ThrowExceptionDisabled * 2 - 1
};
enum ErrorType
@@ -75,18 +75,18 @@ namespace Nz
enum OpenModeFlags
{
OpenMode_NotOpen = 0x00, // Utilise le mode d'ouverture actuel
OpenMode_NotOpen = 0x00, // Use the current mod of opening
OpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin
OpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert
OpenMode_ReadOnly = 0x04, // Ouvre uniquement en lecture
OpenMode_Text = 0x10, // Ouvre en mode texte
OpenMode_Truncate = 0x20, // Créé le fichier s'il n'existe pas et le vide s'il existe
OpenMode_WriteOnly = 0x40, // Ouvre uniquement en écriture, créé le fichier s'il n'existe pas
OpenMode_Append = 0x01, // Disable writing on existing parts and put the cursor at the end
OpenMode_Lock = 0x02, // Disable modifying the file before it is open
OpenMode_ReadOnly = 0x04, // Open in read only
OpenMode_Text = 0x10, // Open in text mod
OpenMode_Truncate = 0x20, // Create the file if it doesn't exist and empty it if it exists
OpenMode_WriteOnly = 0x40, // Open in write only, create the file if it doesn't exist
OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Ouvre en lecture/écriture
OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Open in read and write
OpenMode_Max = OpenMode_WriteOnly
OpenMode_Max = OpenMode_WriteOnly * 2 - 1
};
enum ParameterType
@@ -177,7 +177,7 @@ namespace Nz
StreamOption_Sequential = 0x1,
StreamOption_Text = 0x2,
StreamOption_Max = StreamOption_Text*2-1
StreamOption_Max = StreamOption_Text * 2 - 1
};
enum Ternary

View File

@@ -9,19 +9,18 @@
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Directory.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/String.hpp>
#if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG)
#define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, __FILE__, NAZARA_FUNCTION)
#else
#define NazaraAssert(a, err) for (;;) break
#endif
#define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraInternalError(err) Nz::Error::Trigger(Nz::ErrorType_Internal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraWarning(err) Nz::Error::Trigger(Nz::ErrorType_Warning, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION)
#define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, __FILE__, NAZARA_FUNCTION)
#define NazaraInternalError(err) Nz::Error::Trigger(Nz::ErrorType_Internal, err, __LINE__, __FILE__, NAZARA_FUNCTION)
#define NazaraWarning(err) Nz::Error::Trigger(Nz::ErrorType_Warning, err, __LINE__, __FILE__, NAZARA_FUNCTION)
namespace Nz
{

View File

@@ -8,11 +8,27 @@
namespace Nz
{
/*!
* \brief Computes the hash for the file
* \return ByteArray represing the result of the hash of the file
*
* \param hash Hash to execute
* \param filePath Path for the file
*/
inline ByteArray File::ComputeHash(HashType hash, const String& filePath)
{
return ComputeHash(AbstractHash::Get(hash).get(), filePath);
}
/*!
* \brief Computes the hash for the file
* \return ByteArray represing the result of the hash of the file
*
* \param hash Hash to execute
* \param filePath Path for the file
*/
inline ByteArray File::ComputeHash(AbstractHash* hash, const String& filePath)
{
return Nz::ComputeHash(hash, File(filePath));

View File

@@ -9,7 +9,7 @@
#include <Nazara/Core/Algorithm.hpp>
// Inspiré du code de la SFML par Laurent Gomila
// Inspired from the of code of the SFML by Laurent Gomila
namespace Nz
{

View File

@@ -6,18 +6,44 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::FunctorWithoutArgs
* \brief Core class that represents a functor using a function without argument
*/
/*!
* \brief Constructs a FunctorWithoutArgs object with a function
*
* \param func Function to execute
*/
template<typename F>
FunctorWithoutArgs<F>::FunctorWithoutArgs(F func) :
m_func(func)
{
}
/*!
* \brief Runs the function
*/
template<typename F>
void FunctorWithoutArgs<F>::Run()
{
m_func();
}
/*!
* \ingroup core
* \class Nz::FunctorWithArgs
* \brief Core class that represents a functor using a function with arguments
*/
/*!
* \brief Constructs a FunctorWithArgs object with a function and its arguments
*
* \param func Function to execute
* \param args Arguments for the function
*/
template<typename F, typename... Args>
FunctorWithArgs<F, Args...>::FunctorWithArgs(F func, Args&&... args) :
m_func(func),
@@ -25,13 +51,27 @@ namespace Nz
{
}
/*!
* \brief Runs the function
*/
template<typename F, typename... Args>
void FunctorWithArgs<F, Args...>::Run()
{
Apply(m_func, m_args);
}
/*!
* \ingroup core
* \class Nz::MemberWithoutArgs
* \brief Core class that represents a functor using a member function
*/
/*!
* \brief Constructs a MemberWithoutArgs object with a member function and an object
*
* \param func Member function to execute
* \param object Object to execute on
*/
template<typename C>
MemberWithoutArgs<C>::MemberWithoutArgs(void (C::*func)(), C* object) :
m_func(func),
@@ -39,6 +79,9 @@ namespace Nz
{
}
/*!
* \brief Runs the function
*/
template<typename C>
void MemberWithoutArgs<C>::Run()
{

View File

@@ -0,0 +1,47 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#pragma once
#ifndef NAZARA_OBJECTHANDLER_HPP
#define NAZARA_OBJECTHANDLER_HPP
#include <Nazara/Core/Bitset.hpp>
#include <memory>
#include <vector>
namespace Nz
{
template<typename T> class ObjectHandle;
template<typename T>
class HandledObject
{
friend ObjectHandle<T>;
public:
HandledObject() = default;
HandledObject(const HandledObject& object);
HandledObject(HandledObject&& object);
~HandledObject();
ObjectHandle<T> CreateHandle();
HandledObject& operator=(const HandledObject& object);
HandledObject& operator=(HandledObject&& object);
protected:
void UnregisterAllHandles();
private:
void RegisterHandle(ObjectHandle<T>* handle);
void UnregisterHandle(ObjectHandle<T>* handle);
std::vector<ObjectHandle<T>*> m_handles;
};
}
#include <Nazara/Core/HandledObject.inl>
#endif // NAZARA_OBJECTHANDLER_HPP

View File

@@ -0,0 +1,84 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ObjectHandle.hpp>
#include <algorithm>
#include <type_traits>
#include <utility>
namespace Nz
{
template<typename T>
HandledObject<T>::HandledObject(const HandledObject& object)
{
// Don't copy anything, we're a copy of the object, we have no handle right now
}
template<typename T>
HandledObject<T>::HandledObject(HandledObject&& object) :
m_handles(std::move(object.m_handles))
{
for (ObjectHandle<T>* handle : m_handles)
handle->OnObjectMoved(static_cast<T*>(this));
}
template<typename T>
HandledObject<T>::~HandledObject()
{
UnregisterAllHandles();
}
template<typename T>
ObjectHandle<T> HandledObject<T>::CreateHandle()
{
return ObjectHandle<T>(static_cast<T*>(this));
}
template<typename T>
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
{
// Nothing to do
return *this;
}
template<typename T>
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
{
m_handles = std::move(object.m_handles);
for (ObjectHandle<T>* handle : m_handles)
handle->OnObjectMoved(static_cast<T*>(this));
return *this;
}
template<typename T>
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
{
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
m_handles.push_back(handle);
}
template<typename T>
void HandledObject<T>::UnregisterAllHandles()
{
// Tell every handle we got destroyed, to null them
for (ObjectHandle<T>* handle : m_handles)
handle->OnObjectDestroyed();
m_handles.clear();
}
template<typename T>
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle)
{
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
NazaraAssert(it != m_handles.end(), "Handle not registred");
// On échange cet élément avec le dernier, et on diminue la taille du vector de 1
std::swap(*it, m_handles.back());
m_handles.pop_back();
}
}

View File

@@ -23,8 +23,8 @@ namespace Nz
void Begin() override;
ByteArray End() override;
std::size_t GetDigestLength() const;
const char* GetHashName() const;
std::size_t GetDigestLength() const override;
const char* GetHashName() const override;
private:
HashWhirlpool_state* m_state;

View File

@@ -47,7 +47,17 @@ namespace Nz
};
}
/*!
* \ingroup core
* \class Nz::Initializer
* \brief Core class that represents a module initializer
*/
/*!
* \brief Constructs a Initializer object with a boolean
*
* \param initialize Initialize the module
*/
template<typename... Args>
Initializer<Args...>::Initializer(bool initialize) :
m_initialized(false)
@@ -56,12 +66,22 @@ namespace Nz
Initialize();
}
/*!
* \brief Destructs the object and call Uninitialize
*
* \see Uninitialize
*/
template<typename... Args>
Initializer<Args...>::~Initializer()
{
Uninitialize();
}
/*!
* \brief Initialize the module
*
* \see Uninitialize
*/
template<typename... Args>
bool Initializer<Args...>::Initialize()
{
@@ -71,12 +91,21 @@ namespace Nz
return m_initialized;
}
/*!
* \brief Checks whether the module is initialized
* \return true if initialized
*/
template<typename... Args>
bool Initializer<Args...>::IsInitialized() const
{
return m_initialized;
}
/*!
* \brief Uninitialize the module
*
* \see Initialize
*/
template<typename... Args>
void Initializer<Args...>::Uninitialize()
{
@@ -84,6 +113,10 @@ namespace Nz
Detail::Initializer<Args...>::Uninit();
}
/*!
* \brief Converts the initializer to boolean
* \return true if initialized
*/
template<typename... Args>
Initializer<Args...>::operator bool() const
{

View File

@@ -13,15 +13,22 @@ namespace Nz
{
class Mutex;
class NAZARA_CORE_API LockGuard
class LockGuard
{
public:
LockGuard(Mutex& mutex);
~LockGuard();
inline LockGuard(Mutex& mutex, bool lock = true);
inline ~LockGuard();
inline void Lock();
inline bool TryLock();
inline void Unlock();
private:
Mutex& m_mutex;
bool m_locked;
};
}
#include <Nazara/Core/LockGuard.inl>
#endif // NAZARA_LOCKGUARD_HPP

View File

@@ -0,0 +1,83 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::LockGuard
* \brief Core class that represents a mutex wrapper that provides a convenient RAII-style mechanism
*/
/*!
* \brief Constructs a LockGuard object with a mutex
*
* \param mutex Mutex to lock
* \param lock Should the mutex be locked by the constructor
*/
inline LockGuard::LockGuard(Mutex& mutex, bool lock) :
m_mutex(mutex),
m_locked(false)
{
if (lock)
{
m_mutex.Lock();
m_locked = true;
}
}
/*!
* \brief Destructs a LockGuard object and unlocks the mutex if it was previously locked
*/
inline LockGuard::~LockGuard()
{
if (m_locked)
m_mutex.Unlock();
}
/*!
* \brief Locks the underlying mutex
*
* \see Mutex::Lock
*/
inline void LockGuard::Lock()
{
NazaraAssert(!m_locked, "Mutex is already locked");
m_mutex.Lock();
}
/*!
* \brief Tries to lock the underlying mutex
*
* \see Mutex::TryLock
*
* \return true if the lock was acquired successfully
*/
inline bool LockGuard::TryLock()
{
NazaraAssert(!m_locked, "Mutex is already locked");
return m_mutex.TryLock();
}
/*!
* \brief Unlocks the underlying mutex
*
* \see Mutex::Unlock
*/
inline void LockGuard::Unlock()
{
NazaraAssert(m_locked, "Mutex is not locked");
m_mutex.Unlock();
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Je ne suis pas fier des cinq lignes qui suivent mais difficile de faire autrement pour le moment...
// I'm not proud of those five following lines but ti's hard to do with another way now
#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#else
@@ -16,6 +16,17 @@
namespace Nz
{
/*!
* \ingroup core
* \fn Nz::MemoryHelper
* \brief Core functions that helps the handle of memory in the engine
*/
/*!
* \brief Calls the operator delete on the pointer
*
* \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator delete
*/
inline void OperatorDelete(void* ptr)
{
#if NAZARA_CORE_MANAGE_MEMORY
@@ -25,6 +36,11 @@ namespace Nz
#endif
}
/*!
* \brief Calls the operator new on the pointer
*
* \remark Uses MemoryManager with NAZARA_CORE_MANAGE_MEMORY defined else operator new
*/
inline void* OperatorNew(std::size_t size)
{
#if NAZARA_CORE_MANAGE_MEMORY
@@ -34,6 +50,13 @@ namespace Nz
#endif
}
/*!
* \brief Constructs the object inplace
* \return Pointer to the constructed object
*
* \param ptr Pointer to raw memory allocated
* \param args Arguments for the constructor
*/
template<typename T, typename... Args>
T* PlacementNew(void* ptr, Args&&... args)
{
@@ -43,7 +66,7 @@ namespace Nz
#include <Nazara/Core/DebugOff.hpp>
// Si c'est nous qui avons défini la constante, alors il nous faut l'enlever (Pour éviter que le moteur entier n'en souffre)
// If we have defined the constant, then we have to undefine it (to avoid bloating in the engine)
#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED
#undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION
#endif

View File

@@ -37,7 +37,7 @@ namespace Nz
private:
MemoryPool(MemoryPool* pool);
std::unique_ptr<void*[]> m_freeList;
std::unique_ptr<void* []> m_freeList;
std::unique_ptr<UInt8[]> m_pool;
std::unique_ptr<MemoryPool> m_next;
std::atomic_uint m_freeCount;

View File

@@ -4,10 +4,25 @@
#include <Nazara/Core/MemoryHelper.hpp>
#include <utility>
#include <stdexcept>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::MemoryPool
* \brief Core class that represents a memory pool
*/
/*!
* \brief Constructs a MemoryPool object
*
* \param blockSize Size of blocks that will be allocated
* \param size Size of the pool
* \param canGrow Determine if the pool can allocate more memory
*/
inline MemoryPool::MemoryPool(unsigned int blockSize, unsigned int size, bool canGrow) :
m_freeCount(size),
m_previous(nullptr),
@@ -16,27 +31,47 @@ namespace Nz
m_size(size)
{
m_pool.reset(new UInt8[blockSize * size]);
m_freeList.reset(new void*[size]);
m_freeList.reset(new void* [size]);
// Remplissage de la free list
for (unsigned int i = 0; i < size; ++i)
m_freeList[i] = &m_pool[m_blockSize * (size-i-1)];
}
/*!
* \brief Constructs a MemoryPool object by move semantic
*
* \param pool MemoryPool to move into this
*/
inline MemoryPool::MemoryPool(MemoryPool&& pool) noexcept
{
operator=(std::move(pool));
}
/*!
* \brief Constructs a MemoryPool object by chaining memory pool
*
* \param pool Previous MemoryPool
*/
inline MemoryPool::MemoryPool(MemoryPool* pool) :
MemoryPool(pool->m_blockSize, pool->m_size, pool->m_canGrow)
{
m_previous = pool;
}
/*!
* \brief Allocates enough memory for the size and returns a pointer to it
* \return A pointer to memory allocated
*
* \param size Size to allocate
*
* \remark If the size is greather than the blockSize of pool, new operator is called
*/
inline void* MemoryPool::Allocate(unsigned int size)
{
///DOC: Si la taille est supérieure à celle d'un bloc du pool, l'opérateur new est utilisé
if (size <= m_blockSize)
{
if (m_freeCount > 0)
@@ -53,10 +88,17 @@ namespace Nz
return OperatorNew(size);
}
/*!
* \brief Deletes the memory represented by the poiner
*
* Calls the destructor of the object before releasing it
*
* \remark If ptr is null, nothing is done
*/
template<typename T>
inline void MemoryPool::Delete(T* ptr)
{
///DOC: Va appeler le destructeur de l'objet avant de le libérer
if (ptr)
{
ptr->~T();
@@ -64,12 +106,20 @@ namespace Nz
}
}
/*!
* \brief Frees the memory represented by the poiner
*
* If the pool gets empty after the call and we are the child of another pool, we commit suicide. If the pointer does not own to a block of the pool, operator delete is called
*
* \remark Throws a std::runtime_error if pointer does not point to an element of the pool with NAZARA_CORE_SAFE defined
* \remark If ptr is null, nothing is done
*/
inline void MemoryPool::Free(void* ptr)
{
///DOC: Si appelé avec un pointeur ne faisant pas partie du pool, l'opérateur delete est utilisé
if (ptr)
{
// Le pointeur nous appartient-il ?
// Does the pointer belong to us ?
UInt8* freePtr = static_cast<UInt8*>(ptr);
UInt8* poolPtr = m_pool.get();
if (freePtr >= poolPtr && freePtr < poolPtr + m_blockSize*m_size)
@@ -81,7 +131,7 @@ namespace Nz
m_freeList[m_freeCount++] = ptr;
// Si nous sommes vide et l'extension d'un autre pool, nous nous suicidons
// If we are empty and the extension of another pool, we commit suicide
if (m_freeCount == m_size && m_previous && !m_next)
{
m_previous->m_next.release();
@@ -98,31 +148,61 @@ namespace Nz
}
}
/*!
* \brief Gets the block size
* \return Size of the blocks
*/
inline unsigned int MemoryPool::GetBlockSize() const
{
return m_blockSize;
}
/*!
* \brief Gets the number of free blocks
* \return Number of free blocks in the pool
*/
inline unsigned int MemoryPool::GetFreeBlocks() const
{
return m_freeCount;
}
/*!
* \brief Gets the pool size
* \return Size of the pool
*/
inline unsigned int MemoryPool::GetSize() const
{
return m_size;
}
/*!
* \brief Creates a new value of type T with arguments
* \return Pointer to the allocated object
*
* \param args Arguments for the new object
*
* \remark Constructs inplace in the pool
*/
template<typename T, typename... Args>
inline T* MemoryPool::New(Args&&... args)
{
///DOC: Permet de construire un objet directement dans le pook
T* object = static_cast<T*>(Allocate(sizeof(T)));
PlacementNew<T>(object, std::forward<Args>(args)...);
return object;
}
/*!
* \brief Assigns the content of another pool by move semantic
* \return A reference to this
*
* \param pool Other pool to move into this
*/
inline MemoryPool& MemoryPool::operator=(MemoryPool&& pool) noexcept
{
m_blockSize = pool.m_blockSize;
@@ -134,7 +214,7 @@ namespace Nz
m_next = std::move(pool.m_next);
m_size = pool.m_size;
// Si nous avons été créés par un autre pool, nous devons le faire pointer vers nous de nouveau
// If we have been created by another pool, we must make it point to us again
if (m_previous)
{
m_previous->m_next.release();

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_MEMORYSTREAM_HPP
#define NAZARA_MEMORYSTREAM_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Stream.hpp>
namespace Nz
{
class ByteArray;
class NAZARA_CORE_API MemoryStream : public Stream
{
public:
inline MemoryStream();
inline MemoryStream(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
MemoryStream(const MemoryStream&) = default;
MemoryStream(MemoryStream&&) = default;
~MemoryStream() = default;
void Clear();
bool EndOfStream() const override;
inline ByteArray& GetBuffer();
inline const ByteArray& GetBuffer() const;
UInt64 GetCursorPos() const override;
UInt64 GetSize() const override;
void SetBuffer(ByteArray* byteArray, UInt32 openMode = OpenMode_ReadWrite);
bool SetCursorPos(UInt64 offset) override;
MemoryStream& operator=(const MemoryStream&) = default;
MemoryStream& operator=(MemoryStream&&) = default;
private:
void FlushStream() override;
std::size_t ReadBlock(void* buffer, std::size_t size) override;
std::size_t WriteBlock(const void* buffer, std::size_t size) override;
ByteArray* m_buffer;
UInt64 m_pos;
};
}
#include <Nazara/Core/MemoryStream.inl>
#endif // NAZARA_MEMORYSTREAM_HPP

View File

@@ -0,0 +1,60 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::MemoryStream
* \brief Constructs a MemoryStream object by default
*/
inline MemoryStream::MemoryStream() :
Stream(StreamOption_None, OpenMode_ReadWrite),
m_pos(0)
{
}
/*!
* \brief Constructs a MemoryStream object with a byte array
*
* \param byteArray Bytes to stream
* \param openMode Reading/writing mode for the stream
*/
inline MemoryStream::MemoryStream(ByteArray* byteArray, UInt32 openMode) :
MemoryStream()
{
SetBuffer(byteArray, openMode);
}
/*!
* \brief Gets the internal buffer
* \return Buffer of bytes
*
* \remark Produces a NazaraAssert if buffer is invalid
*/
inline ByteArray& MemoryStream::GetBuffer()
{
NazaraAssert(m_buffer, "Invalid buffer");
return *m_buffer;
}
/*!
* \brief Gets the internal buffer
* \return Buffer of bytes
*
* \remark Produces a NazaraAssert if buffer is invalid
*/
inline const ByteArray& MemoryStream::GetBuffer() const
{
NazaraAssert(m_buffer, "Invalid buffer");
return *m_buffer;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -15,6 +15,7 @@ namespace Nz
class NAZARA_CORE_API MemoryView : public Stream
{
public:
MemoryView(void* ptr, UInt64 size);
MemoryView(const void* ptr, UInt64 size);
MemoryView(const MemoryView&) = delete;
MemoryView(MemoryView&&) = delete; ///TODO
@@ -31,11 +32,11 @@ namespace Nz
MemoryView& operator=(MemoryView&&) = delete; ///TODO
private:
void FlushStream() override;
void FlushStream() override;
std::size_t ReadBlock(void* buffer, std::size_t size) override;
std::size_t WriteBlock(const void* buffer, std::size_t size) override;
const UInt8* m_ptr;
UInt8* m_ptr;
UInt64 m_pos;
UInt64 m_size;
};

View File

@@ -20,7 +20,7 @@ namespace Nz
public:
Mutex();
Mutex(const Mutex&) = delete;
Mutex(Mutex&&) = delete; ///TODO
inline Mutex(Mutex&& mutex) noexcept;
~Mutex();
void Lock();
@@ -28,11 +28,13 @@ namespace Nz
void Unlock();
Mutex& operator=(const Mutex&) = delete;
Mutex& operator=(Mutex&&) = delete; ///TODO
Mutex& operator=(Mutex&& mutex) noexcept;
private:
MutexImpl* m_impl;
};
}
#include <Nazara/Core/Mutex.inl>
#endif // NAZARA_MUTEX_HPP

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Mutex
*/
/*!
* \brief Constructs a Mutex object by moving another one
*/
inline Mutex::Mutex(Mutex&& mutex) noexcept :
m_impl(mutex.m_impl)
{
mutex.m_impl = nullptr;
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,93 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_OBJECTHANDLE_HPP
#define NAZARA_OBJECTHANDLE_HPP
#include <Nazara/Core/Algorithm.hpp>
#include <ostream>
namespace Nz
{
template<typename T> class HandledObject;
template<typename T>
class ObjectHandle
{
friend HandledObject<T>;
public:
ObjectHandle();
explicit ObjectHandle(T* object);
ObjectHandle(const ObjectHandle& handle);
~ObjectHandle();
T* GetObject() const;
bool IsValid() const;
void Reset(T* object = nullptr);
void Reset(const ObjectHandle& handle);
ObjectHandle& Swap(ObjectHandle& handle);
Nz::String ToString() const;
operator bool() const;
operator T*() const;
T* operator->() const;
ObjectHandle& operator=(T* object);
ObjectHandle& operator=(const ObjectHandle& handle);
static const ObjectHandle InvalidHandle;
protected:
void OnObjectDestroyed();
void OnObjectMoved(T* newObject);
T* m_object;
};
template<typename T> std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle);
template<typename T> bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator==(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator==(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator!=(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator!=(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator<(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator<(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> bool operator<=(const ObjectHandle<T>, const ObjectHandle<T>& rhs);
template<typename T> bool operator<=(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator<=(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator>(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator>(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator>=(const T& lhs, const ObjectHandle<T>& rhs);
template<typename T> bool operator>=(const ObjectHandle<T>& lhs, const T& rhs);
template<typename T> struct PointedType<ObjectHandle<T>> { typedef T type; };
template<typename T> struct PointedType<const ObjectHandle<T>> { typedef T type; };
}
namespace std
{
template<typename T>
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs);
}
#include <Nazara/Core/ObjectHandle.inl>
#endif // NAZARA_OBJECTHANDLE_HPP

View File

@@ -0,0 +1,280 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/ObjectHandle.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <functional>
#include <limits>
namespace Nz
{
template<typename T>
ObjectHandle<T>::ObjectHandle() :
m_object(nullptr)
{
}
template<typename T>
ObjectHandle<T>::ObjectHandle(T* object) :
ObjectHandle()
{
Reset(object);
}
template<typename T>
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) :
ObjectHandle()
{
Reset(handle);
}
template<typename T>
ObjectHandle<T>::~ObjectHandle()
{
Reset(nullptr);
}
template<typename T>
T* ObjectHandle<T>::GetObject() const
{
return m_object;
}
template<typename T>
bool ObjectHandle<T>::IsValid() const
{
return m_object != nullptr;
}
template<typename T>
void ObjectHandle<T>::Reset(T* object)
{
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle
if (m_object)
m_object->UnregisterHandle(this);
m_object = object;
if (m_object)
// On informe la nouvelle entité que nous pointons sur elle
m_object->RegisterHandle(this);
}
template<typename T>
void ObjectHandle<T>::Reset(const ObjectHandle<T>& handle)
{
Reset(handle.GetObject());
}
template<typename T>
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle)
{
// Comme nous inversons les handles, nous devons prévenir les entités
// La version par défaut de swap (à base de move) aurait fonctionné,
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire).
if (m_object)
{
m_object->UnregisterHandle(this);
m_object->RegisterHandle(&handle);
}
if (handle.m_object)
{
handle.m_object->UnregisterHandle(&handle);
handle.m_object->RegisterHandle(this);
}
// On effectue l'échange
std::swap(m_object, handle.m_object);
return *this;
}
template<typename T>
Nz::String ObjectHandle<T>::ToString() const
{
Nz::StringStream ss;
ss << "ObjectHandle(";
if (IsValid())
ss << m_object->ToString();
else
ss << "Null";
ss << ')';
return ss;
}
template<typename T>
ObjectHandle<T>::operator bool() const
{
return IsValid();
}
template<typename T>
ObjectHandle<T>::operator T*() const
{
return m_object;
}
template<typename T>
T* ObjectHandle<T>::operator->() const
{
return m_object;
}
template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
{
Reset(entity);
return *this;
}
template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle<T>& handle)
{
Reset(handle);
return *this;
}
template<typename T>
void ObjectHandle<T>::OnObjectDestroyed()
{
// Shortcut
m_object = nullptr;
}
template<typename T>
void ObjectHandle<T>::OnObjectMoved(T* newObject)
{
// The object has been moved, update our pointer
m_object = newObject;
}
template<typename T>
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
{
return handle.ToString();
}
template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return lhs.GetObject() == rhs.GetObject();
}
template<typename T>
bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
{
return &lhs == rhs.GetObject();
}
template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
{
return lhs.GetObject() == &rhs;
}
template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs == rhs);
}
template<typename T>
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs == rhs);
}
template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
{
return !(lhs == rhs);
}
template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return lhs.m_object < rhs.m_object;
}
template<typename T>
bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
{
return &lhs < rhs.m_object;
}
template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
{
return lhs.m_object < &rhs;
}
template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs > rhs);
}
template<typename T>
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs > rhs);
}
template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
{
return !(lhs > rhs);
}
template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return rhs < lhs;
}
template<typename T>
bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
{
return rhs < lhs;
}
template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
{
return rhs < lhs;
}
template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs < rhs);
}
template<typename T>
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
{
return !(lhs < rhs);
}
template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
{
return !(lhs < rhs);
}
template<typename T>
const ObjectHandle<T> ObjectHandle<T>::InvalidHandle;
}
namespace std
{
template<typename T>
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
{
lhs.Swap(rhs);
}
}

View File

@@ -7,6 +7,20 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::ObjectRef
* \brief Core class that represents a reference to an object
*/
/*!
* \brief Gets the ObjectRef object by name
* \return Optional reference
*
* \param name Name of the object
*
* \remark Produces a NazaraError if object not found
*/
template<typename Type>
ObjectRef<Type> ObjectLibrary<Type>::Get(const String& name)
{
@@ -17,18 +31,34 @@ namespace Nz
return ref;
}
/*!
* \brief Checks whether the library has the object with that name
* \return true if it the case
*/
template<typename Type>
bool ObjectLibrary<Type>::Has(const String& name)
{
return Type::s_library.find(name) != Type::s_library.end();
}
/*!
* \brief Registers the ObjectRef object with that name
*
* \param name Name of the object
* \param object Object to stock
*/
template<typename Type>
void ObjectLibrary<Type>::Register(const String& name, ObjectRef<Type> object)
{
Type::s_library.emplace(name, object);
}
/*!
* \brief Gets the ObjectRef object by name
* \return Optional reference
*
* \param name Name of the object
*/
template<typename Type>
ObjectRef<Type> ObjectLibrary<Type>::Query(const String& name)
{
@@ -39,6 +69,11 @@ namespace Nz
return nullptr;
}
/*!
* \brief Unregisters the ObjectRef object with that name
*
* \param name Name of the object
*/
template<typename Type>
void ObjectLibrary<Type>::Unregister(const String& name)
{
@@ -48,7 +83,7 @@ namespace Nz
template<typename Type>
bool ObjectLibrary<Type>::Initialize()
{
return true; // Que faire
return true; // Nothing to do
}
template<typename Type>

View File

@@ -8,6 +8,7 @@
#define NAZARA_RESOURCEREF_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/RefCounted.hpp>
#include <type_traits>
@@ -42,6 +43,9 @@ namespace Nz
private:
T* m_object;
};
template<typename T> struct PointedType<ObjectRef<T>> {typedef T type;};
template<typename T> struct PointedType<ObjectRef<T> const> {typedef T type;};
}
#include <Nazara/Core/ObjectRef.inl>

View File

@@ -7,12 +7,26 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::ObjectRef
* \brief Core class that represents a reference to an object
*/
/*!
* \brief Constructs a ObjectRef object by default
*/
template<typename T>
ObjectRef<T>::ObjectRef() :
m_object(nullptr)
{
}
/*!
* \brief Constructs a ObjectRef object with a pointer to an object
*
* \param object Pointer to handle like a reference (can be nullptr)
*/
template<typename T>
ObjectRef<T>::ObjectRef(T* object) :
m_object(object)
@@ -21,6 +35,11 @@ namespace Nz
m_object->AddReference();
}
/*!
* \brief Constructs a ObjectRef object by assignation
*
* \param ref ObjectRef to assign into this
*/
template<typename T>
ObjectRef<T>::ObjectRef(const ObjectRef& ref) :
m_object(ref.m_object)
@@ -29,6 +48,11 @@ namespace Nz
m_object->AddReference();
}
/*!
* \brief Constructs a ObjectRef<U> object from another type of ObjectRef
*
* \param ref ObjectRef of type U to convert to type T
*/
template<typename T>
template<typename U>
ObjectRef<T>::ObjectRef(const ObjectRef<U>& ref) :
@@ -36,13 +60,21 @@ namespace Nz
{
}
/*!
* \brief Constructs a ObjectRef object by move semantic
*
* \param ref ObjectRef to move into this
*/
template<typename T>
ObjectRef<T>::ObjectRef(ObjectRef&& ref) noexcept :
m_object(ref.m_object)
{
ref.m_object = nullptr; // On vole la référence
ref.m_object = nullptr; // We steal the reference
}
/*!
* \brief Destructs the object (remove a reference to the object when shared)
*/
template<typename T>
ObjectRef<T>::~ObjectRef()
{
@@ -50,27 +82,46 @@ namespace Nz
m_object->RemoveReference();
}
/*!
* \brief Gets the underlying pointer
* \return Underlying pointer
*/
template<typename T>
T* ObjectRef<T>::Get() const
{
return m_object;
}
/*!
* \brief Checks whether the reference is valid
* \return true if reference is not nullptr
*/
template<typename T>
bool ObjectRef<T>::IsValid() const
{
return m_object != nullptr;
}
/*!
* \brief Releases the handle of the pointer
* \return Underlying pointer
*/
template<typename T>
T* ObjectRef<T>::Release()
{
if (m_object)
m_object->RemoveReference();
T* object = m_object;
m_object = nullptr;
return object;
}
/*!
* \brief Resets the content of the ObjectRef with another pointer
* \return true if old handle is destroyed
*/
template<typename T>
bool ObjectRef<T>::Reset(T* object)
{
@@ -88,6 +139,12 @@ namespace Nz
return destroyed;
}
/*!
* \brief Swaps the content of the two ObjectRef
* \return A reference to this
*
* \param ref ObjectRef to swap
*/
template<typename T>
ObjectRef<T>& ObjectRef<T>::Swap(ObjectRef& ref)
{
@@ -96,24 +153,44 @@ namespace Nz
return *this;
}
/*!
* \brief Converts the ObjectRef to bool
* \return true if reference is not nullptr
*
* \see IsValid
*/
template<typename T>
ObjectRef<T>::operator bool() const
{
return IsValid();
}
/*!
* \brief Dereferences the ObjectRef
* \return Underlying pointer
*/
template<typename T>
ObjectRef<T>::operator T*() const
{
return m_object;
}
/*!
* \brief Dereferences the ObjectRef
* \return Underlying pointer
*/
template<typename T>
T* ObjectRef<T>::operator->() const
{
return m_object;
}
/*!
* \brief Assigns the object into this
* \return A reference to this
*
* \param object Pointer to handle like a reference (can be nullptr)
*/
template<typename T>
ObjectRef<T>& ObjectRef<T>::operator=(T* object)
{
@@ -122,6 +199,12 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the reference of the ObjectRef with the handle from another
* \return A reference to this
*
* \param ref The other ObjectRef
*/
template<typename T>
ObjectRef<T>& ObjectRef<T>::operator=(const ObjectRef& ref)
{
@@ -130,6 +213,12 @@ namespace Nz
return *this;
}
/*!
* \brief Sets the reference of the ObjectRef from another type of ObjectRef
* \return A reference to this
*
* \param ref ObjectRef of type U to convert
*/
template<typename T>
template<typename U>
ObjectRef<T>& ObjectRef<T>::operator=(const ObjectRef<U>& ref)
@@ -141,6 +230,12 @@ namespace Nz
return *this;
}
/*!
* \brief Moves the ObjectRef into this
* \return A reference to this
*
* \param ref ObjectRef to move in this
*/
template<typename T>
ObjectRef<T>& ObjectRef<T>::operator=(ObjectRef&& ref) noexcept
{
@@ -152,4 +247,24 @@ namespace Nz
}
}
namespace std
{
/*!
* \ingroup core
* \brief Gives a hash representation of the object, specialisation of std
* \return Hash of the ObjectRef
*
* \param object Object to hash
*/
template<typename T>
struct hash<Nz::ObjectRef<T>>
{
size_t operator()(const Nz::ObjectRef<T>& object) const
{
hash<T*> h;
return h(object.Get());
}
};
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -7,7 +7,7 @@
#ifndef NAZARA_OFFSETOF_HPP
#define NAZARA_OFFSETOF_HPP
// Par "Jesse Good" de SO:
// By "Jesse Good" from SO:
// http://stackoverflow.com/questions/12811330/c-compile-time-offsetof-inside-a-template?answertab=votes#tab-top
namespace Nz

View File

@@ -86,10 +86,10 @@ namespace Nz
Value value;
};
using ParameterMap = std::unordered_map<String, Parameter>;
Parameter& CreateValue(const String& name);
void DestroyValue(Parameter& parameter);
using ParameterMap = std::unordered_map<String, Parameter>;
ParameterMap m_parameters;
};
}

View File

@@ -13,7 +13,7 @@
#include <set>
#include <unordered_map>
///TODO: Révision
///TODO: Revision
namespace Nz
{
class DynLib;

View File

@@ -6,6 +6,20 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::PrimitiveList
* \brief Core class that represents a geometric primitive
*/
/*!
* \brief Makes a box centered
*
* \param lengths (Width, Height, Depht)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -15,11 +29,29 @@ namespace Nz
box.subdivision = subdivision;
}
/*!
* \brief Makes a box centered
*
* \param lengths (Width, Height, Depht)
* \param subdivision Number of subdivision for the axis
* \param position Position of the box
* \param rotation Rotation of the box
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakeBox(lengths, subdivision, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Makes a cone, centered in (0, 0, 0) and circle in (0, -length, 0)
*
* \param length Height of the cone
* \param radius Width of the radius
* \param subdivision Number of sides for the circle
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -30,11 +62,29 @@ namespace Nz
cone.subdivision = subdivision;
}
/*!
* \brief Makes a cone, centered in (0, 0, 0) and circle in (0, -length, 0)
*
* \param length Height of the cone
* \param radius Width of the radius
* \param subdivision Number of sides for the circle
* \param position Position of the cone
* \param rotation Rotation of the cone
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakeCone(length, radius, subdivision, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Makes a cubic sphere, centered in (0, 0, 0)
*
* \param size Radius of the cubic sphere
* \param subdivision Number of subdivision for the box
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -45,11 +95,28 @@ namespace Nz
sphere.cubic.subdivision = subdivision;
}
/*!
* \brief Adds a cubic sphere, centered in (0, 0, 0)
*
* \param size Radius of the cubic sphere
* \param subdivision Number of subdivision for the box
* \param position Position of the cubic sphere
* \param rotation Rotation of the cubic sphere
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakeCubicSphere(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Makes a icosphere, centered in (0, 0, 0)
*
* \param size Radius of the icosphere
* \param recursionLevel Number of recursion for the icosphere
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -60,11 +127,28 @@ namespace Nz
sphere.ico.recursionLevel = recursionLevel;
}
/*!
* \brief Makes a icosphere, centered in (0, 0, 0)
*
* \param size Radius of the sphere
* \param recursionLevel Number of recursion for the icosphere
* \param position Position of the icosphere
* \param rotation Rotation of the icosphere
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakeIcoSphere(size, recursionLevel, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Makes a plane, centered in (0, 0, 0)
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -74,16 +158,42 @@ namespace Nz
plane.subdivision = subdivision;
}
/*!
* \brief Makes a plane, centered in (0, 0, 0)
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param planeInfo Information for the plane
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo, const Rectf& uvCoords)
{
MakePlane(size, subdivision, Matrix4f::Transform(planeInfo.distance * planeInfo.normal, Quaternionf::RotationBetween(Vector3f::Up(), planeInfo.normal)), uvCoords);
}
/*!
* \brief Makes a plane, centered in (0, 0, 0)
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param position Position of the plane
* \param rotation Rotation of the plane
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakePlane(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Makes a UV sphere, centered in (0, 0, 0)
*
* \param size Radius of the sphere
* \param sliceCount Number of slices
* \param stackCount Number of stacks
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
matrix = transformMatrix;
@@ -95,11 +205,30 @@ namespace Nz
sphere.uv.stackCount = stackCount;
}
/*!
* \brief Makes a UV sphere, centered in (0, 0, 0)
*
* \param size Radius of the sphere
* \param sliceCount Number of slices
* \param stackCount Number of stacks
* \param position Position of the box
* \param rotation Rotation of the box
* \param uvCoords Coordinates for texture
*/
inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
MakeUVSphere(size, sliceCount, stackCount, Matrix4f::Transform(position, rotation), uvCoords);
}
/*!
* \brief Creates a box centered
* \return Primitive which is a box
*
* \param lengths (Width, Height, Depht)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -108,6 +237,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a box centered
* \return Primitive which is a box
*
* \param lengths (Width, Height, Depht)
* \param subdivision Number of subdivision for the axis
* \param position Position of the box
* \param rotation Rotation of the box
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;
@@ -116,6 +255,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a cone, centered in (0, 0, 0) and circle in (0, -length, 0)
* \return Primitive which is a cone
*
* \param length Height of the cone
* \param radius Width of the radius
* \param subdivision Number of sides for the circle
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -124,6 +273,17 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a cone, centered in (0, 0, 0) and circle in (0, -length, 0)
* \return Primitive which is a cone
*
* \param length Height of the cone
* \param radius Width of the radius
* \param subdivision Number of sides for the circle
* \param position Position of the cone
* \param rotation Rotation of the cone
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;
@@ -132,6 +292,15 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a cubic sphere, centered in (0, 0, 0)
* \return Primitive which is a cubic sphere
*
* \param size Radius of the cubic sphere
* \param subdivision Number of subdivision for the box
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -140,6 +309,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a cubic sphere, centered in (0, 0, 0)
* \return Primitive which is a cubic sphere
*
* \param size Radius of the cubic sphere
* \param subdivision Number of subdivision for the box
* \param position Position of the cubic sphere
* \param rotation Rotation of the cubic sphere
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;
@@ -148,6 +327,15 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a icosphere, centered in (0, 0, 0)
* \return Primitive which is a icosphere
*
* \param size Radius of the icosphere
* \param recursionLevel Number of recursion for the icosphere
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -156,6 +344,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a icosphere, centered in (0, 0, 0)
* \return Primitive which is a icosphere
*
* \param size Radius of the sphere
* \param recursionLevel Number of recursion for the icosphere
* \param position Position of the icosphere
* \param rotation Rotation of the icosphere
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;
@@ -164,6 +362,15 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a plane, centered in (0, 0, 0)
* \return Primitive which is a plane
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -172,6 +379,15 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a plane, centered in (0, 0, 0)
* \return Primitive which is a plane
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param planeInfo Information for the plane
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords)
{
Primitive primitive;
@@ -180,6 +396,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a plane, centered in (0, 0, 0)
* \return Primitive which is a plane
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param position Position of the plane
* \param rotation Rotation of the plane
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;
@@ -188,6 +414,16 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a UV sphere, centered in (0, 0, 0)
* \return Primitive which is a uv sphere
*
* \param size Radius of the sphere
* \param sliceCount Number of slices
* \param stackCount Number of stacks
* \param transformMatrix Matrix to apply
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords)
{
Primitive primitive;
@@ -196,6 +432,17 @@ namespace Nz
return primitive;
}
/*!
* \brief Creates a UV sphere, centered in (0, 0, 0)
* \return Primitive which is a uv sphere
*
* \param size Radius of the sphere
* \param sliceCount Number of slices
* \param stackCount Number of stacks
* \param position Position of the box
* \param rotation Rotation of the box
* \param uvCoords Coordinates for texture
*/
inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords)
{
Primitive primitive;

View File

@@ -9,6 +9,7 @@
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Core/String.hpp>
#include <list>
#include <tuple>
@@ -21,6 +22,8 @@ namespace Nz
template<typename Type, typename Parameters>
class ResourceLoader
{
static_assert(std::is_base_of<ResourceParameters, Parameters>::value, "ResourceParameters must be a base of Parameters");
friend Type;
public:

View File

@@ -11,6 +11,18 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::ResourceLoader
* \brief Core class that represents a loader of resources
*/
/*!
* \brief Checks whether the extension of the file is supported
* \return true if supported
*
* \param extension Extension of the file
*/
template<typename Type, typename Parameters>
bool ResourceLoader<Type, Parameters>::IsExtensionSupported(const String& extension)
{
@@ -25,16 +37,26 @@ namespace Nz
return false;
}
/*!
* \brief Loads a resource from a file
* \return true if successfully loaded
*
* \param resource Resource to load
* \param filePath Path to the resource
* \param parameters Parameters for the load
*
* \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if filePath has no extension
* \remark Produces a NazaraError if file count not be opened
* \remark Produces a NazaraWarning if loader failed
* \remark Produces a NazaraError if all loaders failed or no loader was found
*/
template<typename Type, typename Parameters>
bool ResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters)
{
#if NAZARA_CORE_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
return false;
}
#endif
NazaraAssert(resource, "Invalid resource");
NazaraAssert(parameters.IsValid(), "Invalid parameters");
String path = File::NormalizePath(filePath);
String ext = path.SubStringFrom('.', -1, true).ToLower();
@@ -122,22 +144,28 @@ namespace Nz
return false;
}
/*!
* \brief Loads a resource from a raw memory, a size and parameters
* \return true if successfully loaded
*
* \param resource Resource to load
* \param data Raw memory of the resource
* \param size Size available for the read
* \param parameters Parameters for the load
*
* \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if size is 0 with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraWarning if loader failed
* \remark Produces a NazaraError if all loaders failed or no loader was found
*/
template<typename Type, typename Parameters>
bool ResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
{
#if NAZARA_CORE_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
return false;
}
if (size == 0)
{
NazaraError("No data to load");
return false;
}
#endif
NazaraAssert(resource, "Invalid resource");
NazaraAssert(data, "Invalid data pointer");
NazaraAssert(size, "No data to load");
NazaraAssert(parameters.IsValid(), "Invalid parameters");
MemoryView stream(data, size);
@@ -198,22 +226,26 @@ namespace Nz
return false;
}
/*!
* \brief Loads a resource from a stream and parameters
* \return true if successfully loaded
*
* \param resource Resource to load
* \param stream Stream of the resource
* \param parameters Parameters for the load
*
* \remark Produces a NazaraError if resource is nullptr with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if stream has no data with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraError if parameters are invalid with NAZARA_CORE_SAFE defined
* \remark Produces a NazaraWarning if loader failed
* \remark Produces a NazaraError if all loaders failed or no loader was found
*/
template<typename Type, typename Parameters>
bool ResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters)
{
#if NAZARA_CORE_SAFE
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
return false;
}
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
{
NazaraError("No data to load");
return false;
}
#endif
NazaraAssert(resource, "Invalid resource");
NazaraAssert(stream.GetCursorPos() < stream.GetSize(), "No data to load");
NazaraAssert(parameters.IsValid(), "Invalid parameters");
UInt64 streamPos = stream.GetCursorPos();
bool found = false;
@@ -224,17 +256,17 @@ namespace Nz
stream.SetCursorPos(streamPos);
// Le loader supporte-t-il les données ?
// Does the loader support these data ?
Ternary recognized = checkFunc(stream, parameters);
if (recognized == Ternary_False)
continue;
else if (recognized == Ternary_True)
found = true;
// On repositionne le stream à son ancienne position
// We move the stream to its old position
stream.SetCursorPos(streamPos);
// Chargement de la ressource
// Load of the resource
if (streamLoader(resource, stream, parameters))
return true;
@@ -250,28 +282,33 @@ namespace Nz
return false;
}
/*!
* \brief Registers the loader
*
* \param extensionGetter A function to test whether the extension (as a string) is supported by this loader
* \param checkFunc A function to check the stream with the parser
* \param streamLoader A function to load the data from a stream in the resource
* \param fileLoader Optional function to load the data from a file in the resource
* \param memoryLoader Optional function to load the data from a raw memory in the resource
*/
template<typename Type, typename Parameters>
void ResourceLoader<Type, Parameters>::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader)
{
#if NAZARA_CORE_SAFE
if (streamLoader)
{
if (!checkFunc)
{
NazaraError("StreamLoader present without StreamChecker");
return;
}
}
else if (!fileLoader && !memoryLoader)
{
NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present");
return;
}
#endif
NazaraAssert(checkFunc || !streamLoader, "StreamLoader present without StreamChecker");
NazaraAssert(fileLoader || memoryLoader || streamLoader, "A loader function is mandatory");
Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader));
}
/*!
* \brief Unregisters the loader
*
* \param extensionGetter A function to test whether the extension (as a string) is supported by this loader
* \param checkFunc A function to check the stream with the parser
* \param streamLoader A function to load the data from a stream in the resource
* \param fileLoader Optional function to load the data from a file in the resource
* \param memoryLoader Optional function to load the data from a raw memory in the resource
*/
template<typename Type, typename Parameters>
void ResourceLoader<Type, Parameters>::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader)
{

View File

@@ -8,6 +8,7 @@
#define NAZARA_RESOURCEMANAGER_HPP
#include <Nazara/Core/ObjectRef.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Core/String.hpp>
#include <unordered_map>

View File

@@ -9,12 +9,27 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::ResourceManager
* \brief Core class that represents a resource manager
*/
/*!
* \brief Clears the content of the manager
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::Clear()
{
Type::s_managerMap.clear();
}
/*!
* \brief Gets a reference to the object loaded from file
* \return Reference to the object
*
* \param filePath Path to the asset that will be loaded
*/
template<typename Type, typename Parameters>
ObjectRef<Type> ResourceManager<Type, Parameters>::Get(const String& filePath)
{
@@ -43,12 +58,19 @@ namespace Nz
return it->second;
}
/*!
* \brief Gets the defaults parameters for the load
* \return Default parameters for loading from file
*/
template<typename Type, typename Parameters>
const Parameters& ResourceManager<Type, Parameters>::GetDefaultParameters()
{
return Type::s_managerParameters;
}
/*!
* \brief Purges the resource manager from every asset whose it is the only owner
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::Purge()
{
@@ -56,16 +78,22 @@ namespace Nz
while (it != Type::s_managerMap.end())
{
const ObjectRef<Type>& ref = it->second;
if (ref.GetReferenceCount() == 1) // Sommes-nous les seuls à détenir la ressource ?
if (ref.GetReferenceCount() == 1) // Are we the only ones to own the resource ?
{
NazaraDebug("Purging resource from file " + ref->GetFilePath());
Type::s_managerMap.erase(it++); // Alors on la supprime
Type::s_managerMap.erase(it++); // Then we erase it
}
else
++it;
}
}
/*!
* \brief Registers the resource under the filePath
*
* \param filePath Path for the resource
* \param resource Object to associate with
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::Register(const String& filePath, ObjectRef<Type> resource)
{
@@ -74,12 +102,22 @@ namespace Nz
Type::s_managerMap[absolutePath] = resource;
}
/*!
* \brief Sets the defaults parameters for the load
*
* \param params Default parameters for loading from file
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::SetDefaultParameters(const Parameters& params)
{
Type::s_managerParameters = params;
}
/*!
* \brief Unregisters the resource under the filePath
*
* \param filePath Path for the resource
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::Unregister(const String& filePath)
{
@@ -88,12 +126,19 @@ namespace Nz
Type::s_managerMap.erase(absolutePath);
}
/*!
* \brief Initializes the resource manager
* \return true
*/
template<typename Type, typename Parameters>
bool ResourceManager<Type, Parameters>::Initialize()
{
return true;
}
/*!
* \brief Uninitialize the resource manager
*/
template<typename Type, typename Parameters>
void ResourceManager<Type, Parameters>::Uninitialize()
{

View File

@@ -0,0 +1,20 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RESOURCEPARAMETERS_HPP
#define NAZARA_RESOURCEPARAMETERS_HPP
#include <Nazara/Core/ParameterList.hpp>
namespace Nz
{
struct ResourceParameters
{
ParameterList custom;
};
}
#endif // NAZARA_RESOURCEPARAMETERS_HPP

View File

@@ -0,0 +1,54 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RESOURCESAVER_HPP
#define NAZARA_RESOURCESAVER_HPP
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Core/String.hpp>
#include <list>
#include <tuple>
#include <type_traits>
namespace Nz
{
class Stream;
template<typename Type, typename Parameters>
class ResourceSaver
{
static_assert(std::is_base_of<ResourceParameters, Parameters>::value, "ResourceParameters must be a base of Parameters");
friend Type;
public:
using ExtensionGetter = bool (*)(const String& extension);
using FormatQuerier = bool (*)(const String& format);
using FileSaver = bool (*)(const Type& resource, const String& filePath, const Parameters& parameters);
using StreamSaver = bool (*)(const Type& resource, const String& format, Stream& stream, const Parameters& parameters);
ResourceSaver() = delete;
~ResourceSaver() = delete;
static bool IsFormatSupported(const String& extension);
static bool SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters = Parameters());
static bool SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters = Parameters());
static void RegisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver = nullptr);
static void UnregisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver = nullptr);
private:
using Saver = std::tuple<FormatQuerier, StreamSaver, FileSaver>;
using SaverList = std::list<Saver>;
};
}
#include <Nazara/Core/ResourceSaver.inl>
#endif // NAZARA_RESOURCESAVER_HPP

View File

@@ -0,0 +1,190 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
/*!
* \ingroup core
* \class Nz::ResourceSaver
* \brief Core class that represents a list of saver functions for a specific resource type
*/
/*!
* \brief Checks whether the extension of the file is supported
* \return true if supported
*
* \param extension Extension of the file
*/
template<typename Type, typename Parameters>
bool ResourceSaver<Type, Parameters>::IsFormatSupported(const String& extension)
{
for (Saver& saver : Type::s_savers)
{
ExtensionGetter isExtensionSupported = std::get<0>(saver);
if (isExtensionSupported && isExtensionSupported(extension))
return true;
}
return false;
}
/*!
* \brief Saves a resource to a file
* \return true if successfully saved
*
* \param resource Resource to save
* \param filePath Path to the file where the resource will be written
* \param parameters Parameters for the save
*
* \remark The previous file content will be discarded, to prevent this behavior you should use SaveToStream
* \remark The file extension will be used as format for the saver ("image.png" => "png", to write a specified format to a user-specified extension you should use SaveToStream
*
* \seealso SaveToStream
*/
template<typename Type, typename Parameters>
bool ResourceSaver<Type, Parameters>::SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters)
{
NazaraAssert(parameters.IsValid(), "Invalid parameters");
String path = File::NormalizePath(filePath);
String ext = path.SubStringFrom('.', -1, true).ToLower();
if (ext.IsEmpty())
{
NazaraError("Failed to get file extension from \"" + filePath + '"');
return false;
}
File file(path); // Opened only is required
bool found = false;
for (Saver& saver : Type::s_savers)
{
FormatQuerier formatQuerier = std::get<0>(saver);
if (!formatQuerier || !formatQuerier(ext))
continue;
found = true;
StreamSaver streamSeaver = std::get<1>(saver);
FileSaver fileSaver = std::get<2>(saver);
if (fileSaver)
{
if (fileSaver(resource, filePath, parameters))
return true;
}
else
{
if (!file.Open(OpenMode_WriteOnly))
{
NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode");
return false;
}
if (streamSeaver(resource, ext, file, parameters))
return true;
}
NazaraWarning("Saver failed");
}
if (found)
NazaraError("Failed to save resource: all savers failed");
else
NazaraError("Failed to save resource: no saver found for extension \"" + ext + '"');
return false;
}
/*!
* \brief Saves a resource to a stream
* \return true if successfully saved
*
* \param resource Resource to load
* \param stream Stream with write access where the resource data will be written
* \param format Data format to save the resource to
* \param parameters Parameters for the saving
*
* \seealso SaveToFile
*/
template<typename Type, typename Parameters>
bool ResourceSaver<Type, Parameters>::SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters)
{
NazaraAssert(stream.IsWritable(), "Stream is not writable");
NazaraAssert(parameters.IsValid(), "Invalid parameters");
UInt64 streamPos = stream.GetCursorPos();
bool found = false;
for (Saver& saver : Type::s_savers)
{
FormatQuerier formatQuerier = std::get<0>(saver);
if (!formatQuerier || !formatQuerier(format))
continue;
found = true;
StreamSaver streamSeaver = std::get<1>(saver);
// We move the stream to its old position
stream.SetCursorPos(streamPos);
// Load of the resource
if (streamSeaver(resource, format, stream, parameters))
return true;
NazaraWarning("Saver failed");
}
if (found)
NazaraError("Failed to save resource: all savers failed");
else
NazaraError("Failed to save resource: no saver found for format \"" + format + '"');
return false;
}
/*!
* \brief Registers a saver
*
* \param formatQuerier A function to test whether the format (as a string) is supported by this saver
* \param streamSaver A function which saves the resource to a stream
* \param fileSaver Optional function which saves the resource directly to a file given a file path
*
* \remark The fileSaver argument is only present for compatibility with external savers which cannot be interfaced with streams
* \remark At least one saver is required
*/
template<typename Type, typename Parameters>
void ResourceSaver<Type, Parameters>::RegisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver)
{
NazaraAssert(formatQuerier, "A format querier is mandaroty");
NazaraAssert(streamSaver || fileSaver, "A saver function is mandaroty");
Type::s_savers.push_front(std::make_tuple(formatQuerier, streamSaver, fileSaver));
}
/*!
* \brief Unregisters a saver
*
* \param formatQuerier A function to test whether the format (as a string) is supported by this saver
* \param streamSaver A function which saves the resource to a stream
* \param fileSaver A function function which saves the resource directly to a file given a file path
*
* \remark The saver will only be unregistered if the function pointers are exactly the same
*/
template<typename Type, typename Parameters>
void ResourceSaver<Type, Parameters>::UnregisterSaver(FormatQuerier formatQuerier, StreamSaver streamSaver, FileSaver fileSaver)
{
Type::s_savers.remove(std::make_tuple(formatQuerier, streamSaver, fileSaver));
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -20,17 +20,9 @@ namespace Nz
struct SerializationContext
{
Stream* stream;
Endianness endianness;
UInt8 currentBitPos;
UInt8 currentByte;
};
struct UnserializationContext
{
Stream* stream;
Endianness endianness;
UInt8 currentBitPos;
UInt8 currentByte;
Endianness endianness = Endianness_BigEndian; //< Default to Big Endian encoding
UInt8 currentBitPos = 8; //< 8 means no bit is currently wrote
UInt8 currentByte; //< Undefined value, will be initialized at the first bit write
};
}

View File

@@ -1,46 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SERIALIZER_HPP
#define NAZARA_SERIALIZER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
namespace Nz
{
class Stream;
class Serializer
{
public:
inline Serializer(Stream& stream);
Serializer(const Serializer&) = default;
Serializer(Serializer&&) = default;
~Serializer();
inline Endianness GetDataEndianness() const;
inline Stream& GetStream() const;
inline bool FlushBits();
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream& stream);
template<typename T>
Serializer& operator<<(const T& value);
Serializer& operator=(const Serializer&) = default;
Serializer& operator=(Serializer&&) = default;
private:
SerializationContext m_serializationContext;
};
}
#include <Nazara/Core/Serializer.inl>
#endif // NAZARA_SERIALIZER_HPP

View File

@@ -1,67 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline Serializer::Serializer(Stream& stream)
{
m_serializationContext.currentBitPos = 8;
m_serializationContext.endianness = Endianness_BigEndian;
m_serializationContext.stream = &stream;
}
inline Serializer::~Serializer()
{
if (!FlushBits())
NazaraWarning("Failed to flush bits at serializer destruction");
}
inline Endianness Serializer::GetDataEndianness() const
{
return m_serializationContext.endianness;
}
inline Stream& Serializer::GetStream() const
{
return *m_serializationContext.stream;
}
inline bool Serializer::FlushBits()
{
if (m_serializationContext.currentBitPos != 8)
{
m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself
if (!Serialize<UInt8>(m_serializationContext, m_serializationContext.currentByte))
return false;
}
return true;
}
inline void Serializer::SetDataEndianness(Endianness endiannes)
{
m_serializationContext.endianness = endiannes;
}
inline void Serializer::SetStream(Stream& stream)
{
m_serializationContext.stream = &stream;
}
template<typename T>
Serializer& Serializer::operator<<(const T& value)
{
if (!Serialize(m_serializationContext, value))
NazaraError("Failed to serialize value");
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>
#include "Serializer.hpp"

View File

@@ -8,18 +8,38 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Signal
* \brief Core class that represents a signal, a list of objects waiting for its message
*/
/*!
* \brief Constructs a Signal object by default
*/
template<typename... Args>
Signal<Args...>::Signal() :
m_slotIterator(0)
{
}
/*!
* \brief Constructs a Signal object by move semantic
*
* \param signal Signal to move in this
*/
template<typename... Args>
Signal<Args...>::Signal(Signal&& signal)
{
operator=(std::move(signal));
}
/*!
* \brief Clears the list of actions attached to the signal
*/
template<typename... Args>
void Signal<Args...>::Clear()
{
@@ -27,12 +47,26 @@ namespace Nz
m_slotIterator = 0;
}
/*!
* \brief Connects a function to the signal
* \return Connection attached to the signal
*
* \param func Non-member function
*/
template<typename... Args>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const Callback& func)
{
return Connect(Callback(func));
}
/*!
* \brief Connects a function to the signal
* \return Connection attached to the signal
*
* \param func Non-member function
*/
template<typename... Args>
typename Signal<Args...>::Connection Signal<Args...>::Connect(Callback&& func)
{
@@ -54,6 +88,14 @@ namespace Nz
return Connection(m_slots.back());
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(O& object, void (O::*method) (Args...))
@@ -64,6 +106,14 @@ namespace Nz
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(O* object, void (O::*method)(Args...))
@@ -74,6 +124,14 @@ namespace Nz
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const O& object, void (O::*method) (Args...) const)
@@ -84,6 +142,14 @@ namespace Nz
});
}
/*!
* \brief Connects a member function and its object to the signal
* \return Connection attached to the signal
*
* \param object Object to send the message
* \param method Member function
*/
template<typename... Args>
template<typename O>
typename Signal<Args...>::Connection Signal<Args...>::Connect(const O* object, void (O::*method)(Args...) const)
@@ -94,6 +160,12 @@ namespace Nz
});
}
/*!
* \brief Applies the list of arguments to every callback functions
*
* \param args Arguments to send with the message
*/
template<typename... Args>
void Signal<Args...>::operator()(Args... args) const
{
@@ -101,6 +173,13 @@ namespace Nz
m_slots[m_slotIterator]->callback(args...);
}
/*!
* \brief Moves the signal into this
* \return A reference to this
*
* \param signal Signal to move in this
*/
template<typename... Args>
Signal<Args...>& Signal<Args...>::operator=(Signal&& signal)
{
@@ -114,17 +193,28 @@ namespace Nz
return *this;
}
/*!
* \brief Disconnects a listener from this signal
*
* \param slot Pointer to the ith listener of the signal
*
* \remark Produces a NazaraAssert if slot is invalid (nullptr)
* \remark Produces a NazaraAssert if index of slot is invalid
* \remark Produces a NazaraAssert if slot is not attached to this signal
*/
template<typename... Args>
void Signal<Args...>::Disconnect(const SlotPtr& slot)
{
NazaraAssert(slot, "Invalid slot pointer");
NazaraAssert(slot->index < m_slots.size(), "Invalid slot index");
NazaraAssert(slot->signal == this, "Slot is not attached to this signal");
// "Swap this slot with the last one and pop" idiom
// This will preserve slot indexes
// Can we safely "remove" this slot?
if (m_slotIterator >= m_slots.size()-1 || slot->index > m_slotIterator)
if (m_slotIterator >= (m_slots.size() - 1) || slot->index > m_slotIterator)
{
// Yes we can
SlotPtr& newSlot = m_slots[slot->index];
@@ -150,6 +240,16 @@ namespace Nz
m_slots.pop_back();
}
/*!
* \class Nz::Signal::Connection
* \brief Core class that represents a connection attached to a signal
*/
/*!
* \brief Constructs a Signal::Connection object with a slot
*
* \param slot Slot of the listener
*/
template<typename... Args>
Signal<Args...>::Connection::Connection(const SlotPtr& slot) :
@@ -157,6 +257,13 @@ namespace Nz
{
}
/*!
* \brief Connects to a signal with arguments
*
* \param signal New signal to listen
* \param args Arguments for the signal
*/
template<typename... Args>
template<typename... ConnectArgs>
void Signal<Args...>::Connection::Connect(BaseClass& signal, ConnectArgs&&... args)
@@ -164,6 +271,10 @@ namespace Nz
operator=(signal.Connect(std::forward<ConnectArgs>(args)...));
}
/*!
* \brief Disconnects the connection from the signal
*/
template<typename... Args>
void Signal<Args...>::Connection::Disconnect()
{
@@ -171,12 +282,27 @@ namespace Nz
ptr->signal->Disconnect(ptr);
}
/*!
* \brief Checks whether the connection is still active with the signal
* \return true if signal is still active
*/
template<typename... Args>
bool Signal<Args...>::Connection::IsConnected() const
{
return !m_ptr.expired();
}
/*!
* \class Nz::Signal::ConnectionGuard
* \brief Core class that represents a RAII for a connection attached to a signal
*/
/*!
* \brief Constructs a Signal::ConnectionGuard object with a connection
*
* \param connection Connection for the scope
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::ConnectionGuard(const Connection& connection) :
@@ -184,18 +310,35 @@ namespace Nz
{
}
/*!
* \brief Constructs a Signal::ConnectionGuard object with a connection by move semantic
*
* \param connection Connection for the scope
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::ConnectionGuard(Connection&& connection) :
m_connection(std::move(connection))
{
}
/*!
* \brief Destructs the object and disconnects the connection
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::~ConnectionGuard()
{
m_connection.Disconnect();
}
/*!
* \brief Connects to a signal with arguments
*
* \param signal New signal to listen
* \param args Arguments for the signal
*/
template<typename... Args>
template<typename... ConnectArgs>
void Signal<Args...>::ConnectionGuard::Connect(BaseClass& signal, ConnectArgs&&... args)
@@ -204,24 +347,45 @@ namespace Nz
m_connection.Connect(signal, std::forward<ConnectArgs>(args)...);
}
/*!
* \brief Disconnects the connection from the signal
*/
template<typename... Args>
void Signal<Args...>::ConnectionGuard::Disconnect()
{
m_connection.Disconnect();
}
/*!
* \brief Gets the connection attached to the signal
* \return Connection of the signal
*/
template<typename... Args>
typename Signal<Args...>::Connection& Signal<Args...>::ConnectionGuard::GetConnection()
{
return m_connection;
}
/*!
* \brief Checks whether the connection is still active with the signal
* \return true if signal is still active
*/
template<typename... Args>
bool Signal<Args...>::ConnectionGuard::IsConnected() const
{
return m_connection.IsConnected();
}
/*!
* \brief Assigns the connection into this
* \return A reference to this
*
* \param connection Connection to assign into this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(const Connection& connection)
{
@@ -231,6 +395,13 @@ namespace Nz
return *this;
}
/*!
* \brief Moves the Connection into this
* \return A reference to this
*
* \param connection Connection to move in this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(Connection&& connection)
{
@@ -240,6 +411,13 @@ namespace Nz
return *this;
}
/*!
* \brief Moves the ConnectionGuard into this
* \return A reference to this
*
* \param connection ConnectionGuard to move in this
*/
template<typename... Args>
typename Signal<Args...>::ConnectionGuard& Signal<Args...>::ConnectionGuard::operator=(ConnectionGuard&& connection)
{

View File

@@ -7,7 +7,7 @@
#ifndef NAZARA_SPARSEPTR_HPP
#define NAZARA_SPARSEPTR_HPP
///FIXME: Est-ce que SparsePtr est vraiment le meilleur nom pour cette classe ?
///FIXME: Is SparsePtr a really good name for this class ?
#include <Nazara/Prerequesites.hpp>
#include <cstddef>

View File

@@ -7,24 +7,53 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::SparsePtr
* \brief Core class that represents a pointer and the step between two elements
*/
/*!
* \brief Constructs a SparsePtr object by default
*/
template<typename T>
SparsePtr<T>::SparsePtr()
{
Reset();
}
/*!
* \brief Constructs a SparsePtr object with a pointer
*
* \param ptr Pointer to data
*/
template<typename T>
SparsePtr<T>::SparsePtr(T* ptr)
{
Reset(ptr);
}
/*!
* \brief Constructs a SparsePtr object with a pointer and a step
*
* \param ptr Pointer to data
* \param stride Step between two elements
*/
template<typename T>
SparsePtr<T>::SparsePtr(VoidPtr ptr, int stride)
{
Reset(ptr, stride);
}
/*!
* \brief Constructs a SparsePtr object from another type of SparsePtr
*
* \param ptr Pointer to data of type U to convert to type T
*/
template<typename T>
template<typename U>
SparsePtr<T>::SparsePtr(const SparsePtr<U>& ptr)
@@ -32,18 +61,32 @@ namespace Nz
Reset(ptr);
}
/*!
* \brief Gets the original pointer
* \return Pointer to the first data
*/
template<typename T>
typename SparsePtr<T>::VoidPtr SparsePtr<T>::GetPtr() const
{
return m_ptr;
}
/*!
* \brief Gets the stride
* \return Step between two elements
*/
template<typename T>
int SparsePtr<T>::GetStride() const
{
return m_stride;
}
/*!
* \brief Resets the SparsePtr
*/
template<typename T>
void SparsePtr<T>::Reset()
{
@@ -51,6 +94,14 @@ namespace Nz
SetStride(0);
}
/*!
* \brief Resets the SparsePtr with a pointer
*
* \param ptr Pointer to data
*
* \remark stride is set to sizeof(T)
*/
template<typename T>
void SparsePtr<T>::Reset(T* ptr)
{
@@ -58,6 +109,13 @@ namespace Nz
SetStride(sizeof(T));
}
/*!
* \brief Resets the SparsePtr with a pointer and its stride
*
* \param ptr Pointer to data
* \param stride Step between two elements
*/
template<typename T>
void SparsePtr<T>::Reset(VoidPtr ptr, int stride)
{
@@ -65,6 +123,12 @@ namespace Nz
SetStride(stride);
}
/*!
* \brief Resets the SparsePtr with another SparsePtr
*
* \param ptr Another sparsePtr
*/
template<typename T>
void SparsePtr<T>::Reset(const SparsePtr& ptr)
{
@@ -72,6 +136,12 @@ namespace Nz
SetStride(ptr.GetStride());
}
/*!
* \brief Resets the SparsePtr with another type of SparsePtr
*
* \param ptr Another sparsePtr
*/
template<typename T>
template<typename U>
void SparsePtr<T>::Reset(const SparsePtr<U>& ptr)
@@ -82,94 +152,187 @@ namespace Nz
SetStride(ptr.GetStride());
}
/*!
* \brief Sets the pointer
*
* \param ptr Pointer to data
*/
template<typename T>
void SparsePtr<T>::SetPtr(VoidPtr ptr)
{
m_ptr = reinterpret_cast<BytePtr>(ptr);
m_ptr = static_cast<BytePtr>(ptr);
}
/*!
* \brief Sets the stride
*
* \param stride Step between two elements
*/
template<typename T>
void SparsePtr<T>::SetStride(int stride)
{
m_stride = stride;
}
/*!
* \brief Converts the pointer to bool
* \return true if pointer is not nullptr
*/
template<typename T>
SparsePtr<T>::operator bool() const
{
return m_ptr != nullptr;
}
/*!
* \brief Converts the pointer to a pointer to the value
* \return The value of the pointer
*/
template<typename T>
SparsePtr<T>::operator T*() const
{
return reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Dereferences the pointer
* \return The dereferencing of the pointer
*/
template<typename T>
T& SparsePtr<T>::operator*() const
{
return *reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Dereferences the pointer
* \return The dereferencing of the pointer
*/
template<typename T>
T* SparsePtr<T>::operator->() const
{
return reinterpret_cast<T*>(m_ptr);
}
/*!
* \brief Gets the ith element of the stride pointer
* \return A reference to the ith value
*
* \param index Number of stride to do
*/
template<typename T>
T& SparsePtr<T>::operator[](int index) const
{
return *reinterpret_cast<T*>(m_ptr + index*m_stride);
return *reinterpret_cast<T*>(m_ptr + index * m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator+(int count) const
{
return SparsePtr(m_ptr + count*m_stride, m_stride);
return SparsePtr(m_ptr + count * m_stride, m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator+(unsigned int count) const
{
return SparsePtr(m_ptr + count*m_stride, m_stride);
return SparsePtr(m_ptr + count * m_stride, m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator-(int count) const
{
return SparsePtr(m_ptr - count*m_stride, m_stride);
return SparsePtr(m_ptr - count * m_stride, m_stride);
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A SparsePtr with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator-(unsigned int count) const
{
return SparsePtr(m_ptr - count*m_stride, m_stride);
return SparsePtr(m_ptr - count * m_stride, m_stride);
}
/*!
* \brief Gets the difference between the two SparsePtr
* \return The difference of elements: ptr - this->ptr
*
* \param ptr Other ptr
*/
template<typename T>
std::ptrdiff_t SparsePtr<T>::operator-(const SparsePtr& ptr) const
{
return (m_ptr - ptr.m_ptr)/m_stride;
return (m_ptr - ptr.m_ptr) / m_stride;
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A reference to this pointer with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator+=(int count)
{
m_ptr += count*m_stride;
m_ptr += count * m_stride;
return *this;
}
/*!
* \brief Gets the SparsePtr with an offset
* \return A reference to this pointer with the new stride
*
* \param count Number of stride to do
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator-=(int count)
{
m_ptr -= count*m_stride;
m_ptr -= count * m_stride;
return *this;
}
/*!
* \brief Gets the SparsePtr with the next element
* \return A reference to this pointer updated
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator++()
{
@@ -178,19 +341,29 @@ namespace Nz
return *this;
}
/*!
* \brief Gets the SparsePtr with the next element
* \return A SparsePtr not updated
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator++(int)
{
// On fait une copie de l'objet
// We copy the object
SparsePtr tmp(*this);
// On modifie l'objet
// We modify it
operator++();
// On retourne la copie
// We return the copy
return tmp;
}
/*!
* \brief Gets the SparsePtr with the previous element
* \return A reference to this pointer updated
*/
template<typename T>
SparsePtr<T>& SparsePtr<T>::operator--()
{
@@ -198,49 +371,96 @@ namespace Nz
return *this;
}
/*!
* \brief Gets the SparsePtr with the previous element
* \return A SparsePtr not updated
*/
template<typename T>
SparsePtr<T> SparsePtr<T>::operator--(int)
{
// On fait une copie de l'objet
// We copy the object
SparsePtr tmp(*this);
// On modifie l'objet
// We modify it
operator--();
// On retourne la copie
// We return the copy
return tmp;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the two SparsePtr are pointing to the same memory
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator==(const SparsePtr& ptr) const
{
return m_ptr == ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return false if the two SparsePtr are pointing to the same memory
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator!=(const SparsePtr& ptr) const
{
return m_ptr != ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory inferior to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator<(const SparsePtr& ptr) const
{
return m_ptr < ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory superior to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator>(const SparsePtr& ptr) const
{
return m_ptr > ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory inferior or equal to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator<=(const SparsePtr& ptr) const
{
return m_ptr <= ptr.m_ptr;
}
/*!
* \brief Compares the SparsePtr to another one
* \return true if the first SparsePtr is pointing to memory superior or equal to the second one
*
* \param ptr Other SparsePtr to compare with
*/
template<typename T>
bool SparsePtr<T>::operator>=(const SparsePtr& ptr) const
{

View File

@@ -7,12 +7,26 @@
namespace Nz
{
/*!
* \ingroup core
* \brief Constructs a Stream object with options
*
* \param streamOptions Options for the stream
* \param openMode Reading/writing mode for the stream
*/
inline Stream::Stream(UInt32 streamOptions, UInt32 openMode) :
m_openMode(openMode),
m_streamOptions(streamOptions)
{
}
/*!
* \brief Enables the text mode
*
* \param textMode Enables the mode or disables
*/
inline void Stream::EnableTextMode(bool textMode)
{
if (textMode)
@@ -21,6 +35,12 @@ namespace Nz
m_streamOptions &= ~StreamOption_Text;
}
/*!
* \brief Flushes the stream
*
* \remark Produces a NazaraAssert if file is not writable
*/
inline void Stream::Flush()
{
NazaraAssert(IsWritable(), "Stream is not writable");
@@ -28,36 +48,77 @@ namespace Nz
FlushStream();
}
/*!
* \brief Gets the open mode of the stream
* \return Reading/writing mode for the stream
*/
inline UInt32 Stream::GetOpenMode() const
{
return m_openMode;
}
/*!
* \brief Gets the options of the stream
* \return Options of the stream
*/
inline UInt32 Stream::GetStreamOptions() const
{
return m_streamOptions;
}
/*!
* \brief Checks whether the stream is readable
* \return true if it is the case
*/
inline bool Stream::IsReadable() const
{
return (m_openMode & OpenMode_ReadOnly) != 0;
}
/*!
* \brief Checks whether the stream is sequential
* \return true if it is the case
*/
inline bool Stream::IsSequential() const
{
return (m_streamOptions & StreamOption_Sequential) != 0;
}
/*!
* \brief Checks whether the stream has text mode enabled
* \return true if it is the case
*/
inline bool Stream::IsTextModeEnabled() const
{
return (m_streamOptions & StreamOption_Text) != 0;
}
/*!
* \brief Checks whether the stream can be written
* \return true if it is the case
*/
inline bool Stream::IsWritable() const
{
return (m_openMode & OpenMode_WriteOnly) != 0;
}
/*!
* \brief Reads the stream and puts the result in a buffer
* \return Size of the read
*
* \param buffer Buffer to stock data
* \param size Size meant to be read
*
* \remark Produces a NazaraAssert if stream is not readable
* \remark If preallocated space of buffer is less than the size, the behaviour is undefined
*/
inline std::size_t Stream::Read(void* buffer, std::size_t size)
{
NazaraAssert(IsReadable(), "Stream is not readable");
@@ -65,6 +126,17 @@ namespace Nz
return ReadBlock(buffer, size);
}
/*!
* \brief Writes in the stream the content of a buffer
* \return Size of the writing
*
* \param buffer Buffer to get data from
* \param size Size meant to be written
*
* \remark Produces a NazaraAssert if stream is not writable
* \remark If preallocated space of buffer is less than the size, the behaviour is undefined
*/
inline std::size_t Stream::Write(const void* buffer, std::size_t size)
{
NazaraAssert(IsWritable(), "Stream is not writable");

View File

@@ -23,11 +23,11 @@ namespace Nz
public:
enum Flags
{
None = 0x00, // Mode par défaut
CaseInsensitive = 0x01, // Insensible à la casse
HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8
TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
None = 0x00, // Default mode
CaseInsensitive = 0x01, // Case insensitive
HandleUtf8 = 0x02, // Considers bytes as a list of UTF-8 characters
TrimOnlyLeft = 0x04, // Trim(med), only cut the left part of the string
TrimOnlyRight = 0x08 // Trim(med), only cut the right part of the string
};
String();
@@ -71,7 +71,7 @@ namespace Nz
std::size_t FindAny(const char* string, std::intmax_t start = 0, UInt32 flags = None) const;
std::size_t FindAny(const String& string, std::intmax_t start = 0, UInt32 flags = None) const;
std::size_t FindLast(char character, std::intmax_t start = -1, UInt32 flags = None) const;
std::size_t FindLast(const char *string, std::intmax_t start = -1, UInt32 flags = None) const;
std::size_t FindLast(const char* string, std::intmax_t start = -1, UInt32 flags = None) const;
std::size_t FindLast(const String& string, std::intmax_t start = -1, UInt32 flags = None) const;
std::size_t FindLastAny(const char* string, std::intmax_t start = -1, UInt32 flags = None) const;
std::size_t FindLastAny(const String& string, std::intmax_t start = -1, UInt32 flags = None) const;
@@ -119,8 +119,8 @@ namespace Nz
void Reserve(std::size_t bufferSize);
String& Resize(std::intmax_t size, char character = ' ');
String Resized(std::intmax_t size, char character = ' ') const;
String& Resize(std::intmax_t size, UInt32 flags = None);
String Resized(std::intmax_t size, UInt32 flags = None) const;
String& Reverse();
String Reversed() const;
@@ -326,7 +326,7 @@ namespace Nz
inline bool HashAppend(AbstractHash* hash, const String& string);
NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string);
NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string);
NAZARA_CORE_API bool Unserialize(SerializationContext& context, String* string);
}
namespace std

View File

@@ -7,22 +7,43 @@
namespace Nz
{
/*!
* \ingroup core
* \brief Constructs a String object with a shared string by move semantic
*
* \param sharedString Shared string to move into this
*/
inline String::String(std::shared_ptr<SharedString>&& sharedString) :
m_sharedString(std::move(sharedString))
{
}
/*!
* \brief Releases the content to the string
*/
inline void String::ReleaseString()
{
m_sharedString = std::move(GetEmptyString());
}
/*!
* \brief Constructs a SharedString object by default
*/
inline String::SharedString::SharedString() : // Special case: empty string
capacity(0),
size(0)
{
}
/*!
* \brief Constructs a SharedString object with a size
*
* \param strSize Number of characters in the string
*/
inline String::SharedString::SharedString(std::size_t strSize) :
capacity(strSize),
size(strSize),
@@ -31,6 +52,13 @@ namespace Nz
string[strSize] = '\0';
}
/*!
* \brief Constructs a SharedString object with a size and a capacity
*
* \param strSize Number of characters in the string
* \param strCapacity Capacity in characters in the string
*/
inline String::SharedString::SharedString(std::size_t strSize, std::size_t strCapacity) :
capacity(strCapacity),
size(strSize),
@@ -39,6 +67,14 @@ namespace Nz
string[strSize] = '\0';
}
/*!
* \brief Appends the string to the hash
* \return true if hash is successful
*
* \param hash Hash to append data of the file
* \param string String to hash
*/
inline bool HashAppend(AbstractHash* hash, const String& string)
{
hash->Append(reinterpret_cast<const UInt8*>(string.GetConstBuffer()), string.GetSize());
@@ -48,6 +84,13 @@ namespace Nz
namespace std
{
/*!
* \brief Specialisation of std to hash
* \return Result of the hash
*
* \param str String to hash
*/
template<>
struct hash<Nz::String>
{

View File

@@ -6,18 +6,44 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::TaskScheduler
* \brief Core class that represents a thread pool
*/
/*!
* \brief Adds a task to the pending list
*
* \param function Task that the pool will execute
*/
template<typename F>
void TaskScheduler::AddTask(F function)
{
AddTaskFunctor(new FunctorWithoutArgs<F>(function));
}
/*!
* \brief Adds a task to the pending list
*
* \param function Task that the pool will execute
* \param args Arguments of the function
*/
template<typename F, typename... Args>
void TaskScheduler::AddTask(F function, Args&&... args)
{
AddTaskFunctor(new FunctorWithArgs<F, Args...>(function, std::forward<Args>(args)...));
}
/*!
* \brief Adds a task to the pending list
*
* \param function Task that the pool will execute
* \param object Object on which the method will be called
*/
template<typename C>
void TaskScheduler::AddTask(void (C::*function)(), C* object)
{

View File

@@ -7,18 +7,44 @@
namespace Nz
{
/*!
* \ingroup core
* \class Nz::Thread
* \brief Core class that represents a thread
*/
/*!
* \brief Constructs a Thread object with a function
*
* \param function Task the thread will execute in parallel
*/
template<typename F>
Thread::Thread(F function)
{
CreateImpl(new FunctorWithoutArgs<F>(function));
}
/*!
* \brief Constructs a Thread object with a function and its parameters
*
* \param function Task the thread will execute in parallel
* \param args Arguments of the function
*/
template<typename F, typename... Args>
Thread::Thread(F function, Args&&... args)
{
CreateImpl(new FunctorWithArgs<F, Args...>(function, std::forward<Args>(args)...));
}
/*!
* \brief Constructs a Thread object with a member function and its object
*
* \param function Task the thread will execute in parallel
* \param object Object on which the method will be called
*/
template<typename C>
Thread::Thread(void (C::*function)(), C* object)
{

View File

@@ -2,12 +2,12 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Pas de header guard
// No header guard
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation
// These macroes can change for any file which uses it in the same unit of compilation
#undef NazaraLock
#undef NazaraMutex
#undef NazaraMutexAttrib

View File

@@ -2,9 +2,9 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Pas de header guard
// No header guard
// Ces macros peuvent changer pour n'importe quel fichier qui l'utilise dans une même unité de compilation
// These macroes can change for any file which uses it in the same unit of compilation
#undef NazaraLock
#undef NazaraMutex
#undef NazaraMutexAttrib

View File

@@ -18,16 +18,16 @@ namespace Nz
Unicode() = delete;
~Unicode() = delete;
/*
Catégorie Unicode:
-Les valeurs de 0x01 à 0x80 indiquent la catégorie.
-Les valeurs de 0x100 à 0x10000 indiquent la sous-catégorie.
Unicode category:
-Values between 0x01 and 0x80 specify the category
-Values between 0x100 and 0x10000 specify the subcategory
*/
enum Category : UInt16
{
// Catégorie non-reconnue par Nazara
// Category not handled by Nazara
Category_NoCategory = 0,
// Lettres
// Letters
Category_Letter = 0x01, // L
Category_Letter_Lowercase = Category_Letter | 0x0100, // Ll
Category_Letter_Modifier = Category_Letter | 0x0200, // Lm
@@ -35,19 +35,19 @@ namespace Nz
Category_Letter_Titlecase = Category_Letter | 0x0800, // Lt
Category_Letter_Uppercase = Category_Letter | 0x1000, // Lu
// Marques
// Marks
Category_Mark = 0x02, // M
Category_Mark_Enclosing = Category_Mark | 0x100, // Me
Category_Mark_NonSpacing = Category_Mark | 0x200, // Mn
Category_Mark_SpacingCombining = Category_Mark | 0x400, // Mc
// Nombres
// Numbers
Category_Number = 0x04, // N
Category_Number_DecimalDigit = Category_Number | 0x100, // Nd
Category_Number_Letter = Category_Number | 0x200, // Nl
Category_Number_Other = Category_Number | 0x400, // No
// Autres
// Others
Category_Other = 0x08, // C
Category_Other_Control = Category_Other | 0x0100, // Cc
Category_Other_Format = Category_Other | 0x0200, // Cf
@@ -65,13 +65,13 @@ namespace Nz
Category_Punctuation_Open = Category_Punctuation | 0x2000, // Ps
Category_Punctuation_Other = Category_Punctuation | 0x4000, // Po
// Espacements
// Spaces
Category_Separator = 0x20, // Z
Category_Separator_Line = Category_Separator | 0x0100, // Zl
Category_Separator_Paragraph = Category_Separator | 0x0200, // Zp
Category_Separator_Space = Category_Separator | 0x0400, // Zs
// Symboles
// Symbols
Category_Symbol = 0x40, // S
Category_Symbol_Currency = Category_Symbol | 0x0100, // Sc
Category_Symbol_Math = Category_Symbol | 0x0200, // Sm

View File

@@ -1,44 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_UNSERIALIZER_HPP
#define NAZARA_UNSERIALIZER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Serialization.hpp>
namespace Nz
{
class Stream;
class Unserializer
{
public:
inline Unserializer(Stream& stream);
Unserializer(const Unserializer&) = default;
Unserializer(Unserializer&&) = default;
~Unserializer() = default;
inline Endianness GetDataEndianness() const;
inline Stream& GetStream() const;
inline void SetDataEndianness(Endianness endiannes);
inline void SetStream(Stream& stream);
template<typename T>
Unserializer& operator>>(T& value);
Unserializer& operator=(const Unserializer&) = default;
Unserializer& operator=(Unserializer&&) = default;
private:
UnserializationContext m_unserializationContext;
};
}
#include <Nazara/Core/Unserializer.inl>
#endif // NAZARA_UNSERIALIZER_HPP

View File

@@ -1,46 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
inline Unserializer::Unserializer(Stream& stream)
{
m_unserializationContext.currentBitPos = 8;
m_unserializationContext.endianness = Endianness_BigEndian;
m_unserializationContext.stream = &stream;
}
inline Endianness Unserializer::GetDataEndianness() const
{
return m_unserializationContext.endianness;
}
inline Stream& Unserializer::GetStream() const
{
return *m_unserializationContext.stream;
}
inline void Unserializer::SetDataEndianness(Endianness endiannes)
{
m_unserializationContext.endianness = endiannes;
}
inline void Unserializer::SetStream(Stream& stream)
{
m_unserializationContext.stream = &stream;
}
template<typename T>
Unserializer& Unserializer::operator>>(T& value)
{
if (!Unserialize(m_unserializationContext, &value))
NazaraError("Failed to serialize value");
return *this;
}
}
#include <Nazara/Core/DebugOff.hpp>