Merge pull request #55 from Gawaboumga/Documentation-Update-Merge

Documentation update - Core

Former-commit-id: f48bb5f988379093fde2c494fb93b1fefdf3d283
This commit is contained in:
Lynix 2016-02-24 13:38:27 +01:00
commit 1430547e6e
90 changed files with 7875 additions and 349 deletions

View File

@ -27,11 +27,11 @@ namespace Nz
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 PointedType
{
using type = void; //< FIXME: I can't make SFINAE work
};
template<typename T>
struct TypeTag {};

View File

@ -30,6 +30,16 @@ namespace Nz
}
}
/*!
* \brief Applies the tuple to the function
* \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>());
}
/*!
* \brief Applies the tuple to the member function on an object
* \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,39 @@ namespace Nz
return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
}
/*!
* \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, must be convertible to "Nz::String"
*
* \see ComputeHash
*/
template<typename T>
ByteArray ComputeHash(HashType hash, const T& v)
{
return ComputeHash(AbstractHash::Get(hash).get(), v);
}
/*!
* \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, must be convertible to "Nz::String"
*
* \remark Produce a NazaraAssert if pointer to Abstracthash is invalid
*
* \see ComputeHash
*/
template<typename T>
ByteArray ComputeHash(AbstractHash* hash, const T& v)
{
NazaraAssert(hash != nullptr, "Invalid abstracthash pointer");
hash->Begin();
HashAppend(hash, v);
@ -62,19 +107,44 @@ namespace Nz
return hash->End();
}
/*!
* \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;
}
/*!
* \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();
}
// Algorithme venant de CityHash par Google
/*!
* \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)
@ -91,10 +161,20 @@ 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;};
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;};
/*!
* \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)
{
@ -113,6 +193,16 @@ namespace Nz
return true;
}
/*!
* \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)
{
@ -131,6 +221,16 @@ namespace Nz
return context.stream->Write(&value, sizeof(T)) == sizeof(T);
}
/*!
* \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)
{
if (context.currentBitPos == 8)
@ -149,6 +249,18 @@ namespace Nz
return true;
}
/*!
* \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(SerializationContext& context, T* value)
{

File diff suppressed because it is too large Load Diff

View File

@ -6,59 +6,141 @@
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 +148,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 +479,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 +633,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 +647,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 +662,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 +676,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,6 +763,13 @@ 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);

View File

@ -7,11 +7,25 @@
namespace Nz
{
/*!
* \brief Constructs a ByteStream object with a stream
*
* \remark Produces a NazaraAssert if stream is invalid
*/
inline ByteStream::ByteStream(Stream* stream)
{
NazaraAssert(stream, "Invalid 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)
@ -19,17 +33,35 @@ namespace Nz
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)
@ -38,11 +70,21 @@ namespace Nz
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)
@ -59,6 +101,14 @@ namespace Nz
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)
@ -68,13 +118,29 @@ namespace Nz
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();
@ -82,6 +148,16 @@ namespace Nz
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)
@ -91,6 +167,15 @@ namespace Nz
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)
{
@ -103,6 +188,15 @@ namespace Nz
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)
{
@ -115,6 +209,13 @@ namespace Nz
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;

View File

@ -7,17 +7,38 @@
namespace Nz
{
/*!
* \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 +47,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

@ -11,10 +11,28 @@
namespace Nz
{
/*!
* \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 +41,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 +55,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 +70,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 +88,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 +107,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 +126,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 +241,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 +316,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 +366,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 +382,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 +415,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 +474,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 +529,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 +581,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 +608,16 @@ namespace Nz
return v1 + (v2 - v1)*(2.f/3.f - vH)*6;
return v1;
}
}
}
/*!
* \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

@ -27,36 +27,36 @@
#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
/// Each modification of a parameter needs a recompilation of the module
// Précision des réels lors de la transformation en chaîne de caractère (Max. chiffres après la virgule)
// 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 +64,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,11 @@
namespace Nz
{
/*!
* \brief Gets the platform endianness
* \return Type of the endianness
*/
inline constexpr Endianness GetPlatformEndianness()
{
#if defined(NAZARA_BIG_ENDIAN)
@ -16,11 +21,20 @@ namespace Nz
#endif
}
/*!
* \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);
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*2 - 1
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

@ -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,40 @@
namespace Nz
{
/*!
* \class Nz::StdLogger
* \brief Core class that represents a functor
*/
/*!
* \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();
}
/*!
* \brief Constructs a FunctorWithoutArgs 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,12 +47,22 @@ namespace Nz
{
}
/*!
* \brief Runs the function
*/
template<typename F, typename... Args>
void FunctorWithArgs<F, Args...>::Run()
{
Apply(m_func, m_args);
}
/*!
* \brief Constructs a FunctorWithoutArgs 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) :
@ -39,6 +71,10 @@ namespace Nz
{
}
/*!
* \brief Runs the function
*/
template<typename C>
void MemberWithoutArgs<C>::Run()
{

View File

@ -47,6 +47,16 @@ namespace Nz
};
}
/*!
* \class Nz::Initializer<Args...>
* \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) :
@ -56,12 +66,24 @@ 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 +93,23 @@ 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 +117,11 @@ 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

@ -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
{
/*!
* \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,12 @@ 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 +51,14 @@ 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 +68,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

@ -8,6 +8,19 @@
namespace Nz
{
/*!
* \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 +29,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 +86,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 +104,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 +129,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 +146,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 +212,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

@ -7,18 +7,36 @@
namespace Nz
{
/*!
* \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");
@ -26,6 +44,13 @@ namespace Nz
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");

View File

@ -7,6 +7,20 @@
namespace Nz
{
/*!
* \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,37 @@ 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 +72,12 @@ 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)
{

View File

@ -7,12 +7,27 @@
namespace Nz
{
/*!
* \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 +36,12 @@ 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 +50,12 @@ 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 +63,23 @@ 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 +87,50 @@ 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 +148,13 @@ 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 +163,48 @@ 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 +213,13 @@ 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 +228,13 @@ 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 +246,13 @@ 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
{
@ -154,6 +266,13 @@ namespace Nz
namespace std
{
/*!
* \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>>
{

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

@ -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
{
/*!
* \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,31 @@ 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 +64,31 @@ 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 +99,30 @@ 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 +133,30 @@ 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 +166,45 @@ 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 +216,32 @@ 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 +250,17 @@ 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 +269,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 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 +288,18 @@ 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 +308,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 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 +326,17 @@ 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 +345,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 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 +363,17 @@ 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 +382,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 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 +400,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 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 +418,17 @@ 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 +437,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 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 +456,18 @@ 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

@ -11,6 +11,18 @@
namespace Nz
{
/*!
* \class Nz::ResourceLoader<Type, Parameters>
* \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,10 +37,32 @@ namespace Nz
return false;
}
/*!
* \brief Loads a resource from a filepath and parameters
* \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 (!resource)
{
NazaraError("Pointer invalid");
return false;
}
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
@ -122,13 +156,29 @@ 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())
if (!resource)
{
NazaraError("Invalid parameters");
NazaraError("Pointer invalid");
return false;
}
@ -137,6 +187,12 @@ namespace Nz
NazaraError("No data to load");
return false;
}
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
return false;
}
#endif
MemoryView stream(data, size);
@ -198,13 +254,28 @@ 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())
if (!resource)
{
NazaraError("Invalid parameters");
NazaraError("Pointer invalid");
return false;
}
@ -213,6 +284,12 @@ namespace Nz
NazaraError("No data to load");
return false;
}
if (!parameters.IsValid())
{
NazaraError("Invalid parameters");
return false;
}
#endif
UInt64 streamPos = stream.GetCursorPos();
@ -224,17 +301,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,6 +327,16 @@ 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)
{
@ -272,6 +359,16 @@ namespace Nz
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

@ -9,12 +9,28 @@
namespace Nz
{
/*!
* \class Nz::ResourceManager<Type, Parameters>
* \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 +59,21 @@ 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 +81,23 @@ 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 +106,24 @@ 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 +132,21 @@ 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

@ -8,18 +8,37 @@
namespace Nz
{
/*!
* \class Nz::Signal<Args...>
* \brief Core class that represents a signal, a list of objects waiting for its message
*/
/*!
* \brief Constructs a Signal<Args...> object by default
*/
template<typename... Args>
Signal<Args...>::Signal() :
m_slotIterator(0)
{
}
/*!
* \brief Constructs a Signal<Args...> 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 +46,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 +87,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 +105,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 +123,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 +141,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 +159,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 +172,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 +192,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 +239,16 @@ namespace Nz
m_slots.pop_back();
}
/*!
* \class Nz::Signal<Args...>::Connection
* \brief Core class that represents a connection attached to a signal
*/
/*!
* \brief Constructs a Signal<Args...>::Connection object with a slot
*
* \param slot Slot of the listener
*/
template<typename... Args>
Signal<Args...>::Connection::Connection(const SlotPtr& slot) :
@ -157,6 +256,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 +270,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 +281,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<Args...>::ConnectionGuard
* \brief Core class that represents a RAII for a connection attached to a signal
*/
/*!
* \brief Constructs a Signal<Args...>::ConnectionGuard object with a connection
*
* \param connection Connection for the scope
*/
template<typename... Args>
Signal<Args...>::ConnectionGuard::ConnectionGuard(const Connection& connection) :
@ -184,18 +309,35 @@ namespace Nz
{
}
/*!
* \brief Constructs a Signal<Args...>::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 +346,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 +394,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 +410,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,52 @@
namespace Nz
{
/*!
* \class Nz::SparsePtr<T>
* \brief Core class that represents a pointer and the step between two elements
*/
/*!
* \brief Constructs a SparsePtr<T> object by default
*/
template<typename T>
SparsePtr<T>::SparsePtr()
{
Reset();
}
/*!
* \brief Constructs a SparsePtr<T> object with a pointer
*
* \param ptr Pointer to data
*/
template<typename T>
SparsePtr<T>::SparsePtr(T* ptr)
{
Reset(ptr);
}
/*!
* \brief Constructs a SparsePtr<T> 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<T> 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 +60,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 +93,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 +108,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 +122,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 +135,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 +151,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);
}
/*!
* \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 +340,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 +370,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,25 @@
namespace Nz
{
/*!
* \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 +34,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 +47,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 +125,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;

View File

@ -7,22 +7,42 @@
namespace Nz
{
/*!
* \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 +51,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 +66,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 +83,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,43 @@
namespace Nz
{
/*!
* \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,43 @@
namespace Nz
{
/*!
* \class Nz::Thread
* \brief Core class that represents a thread
*/
/*!
* \brief Constructs a Thread<T> 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<T> 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<T> 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

@ -45,4 +45,4 @@ Links
- **RafBill** and **Raakz:** Finding bugs and/or testing
- **Fissal "DrFisher" Hannoun**: Helping a lot in architecture design
- **Alexandre "Danman" Janniaux**: Helping making the POSIX implementation
- **Gawaboumga**: Improving the engine code by merging on GitHub
- **Youri "Gawaboumga" Hubaut**: Improving the engine code by merging on GitHub

View File

@ -45,4 +45,4 @@ Liens
- **RafBill** et **Raakz:** Recherche de bugs et/ou tests
- **Fissal "DrFisher" Hannoun**: Aide et conseils lors de la conception de l'architecture du moteur
- **Alexandre "Danman" Janniaux**: Aide sur l'implémentation POSIX
- **Gawaboumga**: Amélioration du code via le merging sur GitHub
- **Youri "Gawaboumga" Hubaut**: Amélioration du code via le merging sur GitHub

View File

@ -17,8 +17,24 @@
namespace Nz
{
/*!
* \class Nz::AbstractHash<T>
* \brief Core class that represents the behaviour of the hash classes
*
* \remark This class is abstract
*/
AbstractHash::~AbstractHash() = default;
/*!
* \brief Factory of Hash classes in function of HashType
* \return A new instance of the Hash class according to the HashType
*
* \param type Enumeration of type HashType
*
* \remark If enumeration is not defined in HashType, a NazaraInternalError is thrown and nullptr is returned
*/
std::unique_ptr<AbstractHash> AbstractHash::Get(HashType type)
{
NazaraAssert(type <= HashType_Max, "Hash type value out of enum");
@ -26,34 +42,34 @@ namespace Nz
switch (type)
{
case HashType_Fletcher16:
return std::unique_ptr<AbstractHash>(new HashFletcher16);
return std::make_unique<HashFletcher16>();
case HashType_CRC32:
return std::unique_ptr<AbstractHash>(new HashCRC32);
return std::make_unique<HashCRC32>();
case HashType_MD5:
return std::unique_ptr<AbstractHash>(new HashMD5);
return std::make_unique<HashMD5>();
case HashType_SHA1:
return std::unique_ptr<AbstractHash>(new HashSHA1);
return std::make_unique<HashSHA1>();
case HashType_SHA224:
return std::unique_ptr<AbstractHash>(new HashSHA224);
return std::make_unique<HashSHA224>();
case HashType_SHA256:
return std::unique_ptr<AbstractHash>(new HashSHA256);
return std::make_unique<HashSHA256>();
case HashType_SHA384:
return std::unique_ptr<AbstractHash>(new HashSHA384);
return std::make_unique<HashSHA384>();
case HashType_SHA512:
return std::unique_ptr<AbstractHash>(new HashSHA512);
return std::make_unique<HashSHA512>();
case HashType_Whirlpool:
return std::unique_ptr<AbstractHash>(new HashWhirlpool);
return std::make_unique<HashWhirlpool>();
}
NazaraInternalError("Hash type not handled (0x" + String::Number(type, 16) + ')');
return std::unique_ptr<AbstractHash>();
return nullptr;
}
}

View File

@ -11,17 +11,34 @@ namespace Nz
namespace
{
const char* errorType[] = {
"Assert failed: ", // ErrorType_AssertFailed
"Internal error: ", // ErrorType_Internal
"Error: ", // ErrorType_Normal
"Warning: " // ErrorType_Warning
"Assert failed: ", // ErrorType_AssertFailed
"Internal error: ", // ErrorType_Internal
"Error: ", // ErrorType_Normal
"Warning: " // ErrorType_Warning
};
static_assert(sizeof(errorType) / sizeof(const char*) == ErrorType_Max + 1, "Error type array is incomplete");
}
/*!
* \class Nz::AbstractLogger<T>
* \brief Core class that represents the behaviour of the log classes
*
* \remark This class is abstract
*/
AbstractLogger::~AbstractLogger() = default;
/*!
* \brief Writes the error in StringStream
*
* \param type Enumeration of type ErrorType
* \param error String describing the error
* \param line Line number in the file
* \param file Filename
* \param function Name of the function throwing the error
*/
void AbstractLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
{
StringStream stream;

View File

@ -9,6 +9,19 @@
namespace Nz
{
/*!
* \class Nz::ByteArray
* \brief Core class that represents an array of bytes
*/
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param byteArray The ByteArray to output
*/
std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray)
{
out << byteArray.ToHex();

View File

@ -11,24 +11,61 @@
namespace Nz
{
/*!
* \class Nz::ByteStream
* \brief Core class that represents a stream of bytes
*/
/*!
* \brief Constructs a ByteStream object with a byte array
*
* \param byteArray Bytes to stream
* \param openMode Reading/writing mode for the stream
*/
ByteStream::ByteStream(ByteArray* byteArray, UInt32 openMode) :
ByteStream()
{
SetStream(byteArray, openMode);
}
/*!
* \brief Constructs a ByteStream object with a raw memory and a size
*
* \param ptr Pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
ByteStream::ByteStream(void* ptr, Nz::UInt64 size) :
ByteStream()
{
SetStream(ptr, size);
}
/*!
* \brief Constructs a ByteStream object with a raw memory and a size
*
* \param ptr Constant pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
ByteStream::ByteStream(const void* ptr, Nz::UInt64 size) :
ByteStream()
{
SetStream(ptr, size);
}
/*!
* \brief Sets this with a byte array
*
* \param byteArray Bytes to stream
* \param openMode Reading/writing mode for the stream
*/
void ByteStream::SetStream(ByteArray* byteArray, UInt32 openMode)
{
std::unique_ptr<Stream> stream(new MemoryStream(byteArray, openMode));
@ -38,6 +75,15 @@ namespace Nz
m_ownedStream = std::move(stream);
}
/*!
* \brief Sets this with a raw memory and a size
*
* \param ptr Pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
void ByteStream::SetStream(void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
@ -47,6 +93,15 @@ namespace Nz
m_ownedStream = std::move(stream);
}
/*!
* \brief Sets this with a raw memory and a size
*
* \param ptr Constant pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
void ByteStream::SetStream(const void* ptr, Nz::UInt64 size)
{
std::unique_ptr<Stream> stream(new MemoryView(ptr, size));
@ -56,6 +111,12 @@ namespace Nz
m_ownedStream = std::move(stream);
}
/*!
* \brief Signal function (meant to be virtual)
*
* \remark Produces a NazaraError
*/
void ByteStream::OnEmptyStream()
{
NazaraError("No stream");

View File

@ -18,32 +18,84 @@
namespace Nz
{
/*!
* \class Nz::ConditionVariable
* \brief Core class that represents a condition variable
*
* The ConditionVariable class is a synchronization primitive that can be used to block a thread, or multiple threads at the same time, until another thread both modifies a shared variable (the condition), and notifies the ConditionVariable
*/
/*!
* \brief Constructs a ConditionVariable object by default
*/
ConditionVariable::ConditionVariable()
{
m_impl = new ConditionVariableImpl;
}
/*!
* \brief Destructs the object
*/
ConditionVariable::~ConditionVariable()
{
delete m_impl;
}
/*!
* \brief Sends a signal to one thread waiting on the condition
*
* If any threads are waiting on *this, calling Signal unblocks one of the waiting threads
*
* \see SignalAll
*/
void ConditionVariable::Signal()
{
m_impl->Signal();
}
/*!
* \brief Sends a signal to every threads waiting on the condition
*
* Unblocks all threads currently waiting for *this
*
* \see Signal
*/
void ConditionVariable::SignalAll()
{
m_impl->SignalAll();
}
/*!
* \brief Makes the thread wait on the condition
*
* Wait causes the current thread to block until the condition variable is notified or a spurious wakeup occurs
*
* \param mutex Mutex for the condition
*
* \remark Produces a NazaraAssert if mutex is invalid
*/
void ConditionVariable::Wait(Mutex* mutex)
{
NazaraAssert(mutex != nullptr, "Mutex must be valid");
m_impl->Wait(mutex->m_impl);
}
/*!
* \brief Makes the thread wait on the condition for a certain amount of time
*
* Wait causes the current thread to block until the condition variable is notified, a specific time is reached, or a spurious wakeup occurs
*
* \param mutex Mutex for the condition
* \param timeout Time before expiration of the waiting
*
* \remark Produces a NazaraAssert if mutex is invalid
*/
bool ConditionVariable::Wait(Mutex* mutex, UInt32 timeout)
{
NazaraAssert(mutex != nullptr, "Mutex must be valid");

View File

@ -13,12 +13,24 @@
namespace Nz
{
/*!
* \class Nz::CoreCore
* \brief Core class that represents the module initializer of Core
*/
/*!
* \brief Initializes the Core module
* \return true if initialization is successful
*
* \remark Produces a NazaraNotice
*/
bool Core::Initialize()
{
if (s_moduleReferenceCounter > 0)
{
s_moduleReferenceCounter++;
return true; // Déjà initialisé
return true; // Already initialized
}
s_moduleReferenceCounter++;
@ -29,23 +41,34 @@ namespace Nz
return true;
}
/*!
* \brief Checks whether the module is initialized
* \return true if module is initialized
*/
bool Core::IsInitialized()
{
return s_moduleReferenceCounter != 0;
}
/*!
* \brief Uninitializes the Core module
*
* \remark Produces a NazaraNotice
*/
void Core::Uninitialize()
{
if (s_moduleReferenceCounter != 1)
{
// Le module est soit encore utilisé, soit pas initialisé
// The module is still in use, or can not be uninitialized
if (s_moduleReferenceCounter > 1)
s_moduleReferenceCounter--;
return;
}
// Libération du module
// Free of module
s_moduleReferenceCounter = 0;
HardwareInfo::Uninitialize();

View File

@ -30,16 +30,31 @@ namespace Nz
{
namespace
{
//FIXME: MinGW seems to dislike thread_local shared_ptr.. (using a std::string is a working hackfix)
//FIXME: MinGW seems to dislike thread_local shared_ptr.. (using a std::string is a working hackfix)
thread_local std::string currentPath(DirectoryImpl::GetCurrent());
}
/*!
* \class Nz::Directory
* \brief Core class that represents a directory
*/
/*!
* \brief Constructs a Directory object by default
*/
Directory::Directory() :
m_pattern('*'),
m_impl(nullptr)
{
}
/*!
* \brief Constructs a Directory object with a path
*
* \param dirPath Path to the directory
*/
Directory::Directory(const String& dirPath) :
m_dirPath(dirPath),
m_pattern('*'),
@ -47,11 +62,21 @@ namespace Nz
{
}
/*!
* \brief Destructs the object and calls Close
*
* \see Close
*/
Directory::~Directory()
{
Close();
}
/*!
* \brief Closes the directory
*/
void Directory::Close()
{
NazaraLock(m_mutex);
@ -64,16 +89,26 @@ namespace Nz
}
}
/*!
* \brief Checks whether the directory exists
* \return true if directory exists
*/
bool Directory::Exists() const
{
NazaraLock(m_mutex);
if (IsOpen())
return true; // Le fichier est ouvert, donc il existe
return true; // If directory is open, then it exists
else
return Exists(m_dirPath);
}
/*!
* \brief Gets the path of the directory
* \return Path of the directory
*/
String Directory::GetPath() const
{
NazaraLock(m_mutex);
@ -81,6 +116,11 @@ namespace Nz
return m_dirPath;
}
/*!
* \brief Gets the pattern for the path of the directory
* \return Pattern for the path of the directory
*/
String Directory::GetPattern() const
{
NazaraLock(m_mutex);
@ -88,12 +128,19 @@ namespace Nz
return m_pattern;
}
/*!
* \brief Gets the result name of the directory
* \return Resulting name
*
* \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined
*/
String Directory::GetResultName() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsOpen())
{
NazaraError("Directory not opened");
return String();
@ -103,12 +150,19 @@ namespace Nz
return m_impl->GetResultName();
}
/*!
* \brief Gets the result path of the directory
* \return Resulting path
*
* \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined
*/
String Directory::GetResultPath() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsOpen())
{
NazaraError("Directory not opened");
return String();
@ -118,12 +172,19 @@ namespace Nz
return m_dirPath + NAZARA_DIRECTORY_SEPARATOR + m_impl->GetResultName();
}
/*!
* \brief Gets the resulting size of the directory
* \return Size of the directory
*
* \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined
*/
UInt64 Directory::GetResultSize() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsOpen())
{
NazaraError("Directory not opened");
return 0;
@ -133,6 +194,11 @@ namespace Nz
return m_impl->GetResultSize();
}
/*!
* \brief Checks whether the directory is open
* \return true if open
*/
bool Directory::IsOpen() const
{
NazaraLock(m_mutex);
@ -140,12 +206,19 @@ namespace Nz
return m_impl != nullptr;
}
/*!
* \brief Checks whether the directory is result
* \return true if result
*
* \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined
*/
bool Directory::IsResultDirectory() const
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsOpen())
{
NazaraError("Directory not opened");
return false;
@ -155,12 +228,21 @@ namespace Nz
return m_impl->IsResultDirectory();
}
/*!
* \brief Sets the next result in the directory
* \return true if directory has a next result
*
* \param skipDots Skips the dots in the path
*
* \remark Produces a NazaraError if directory is not open with NAZARA_CORE_SAFE defined
*/
bool Directory::NextResult(bool skipDots)
{
NazaraLock(m_mutex);
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsOpen())
{
NazaraError("Directory not opened");
return false;
@ -185,6 +267,11 @@ namespace Nz
return true;
}
/*!
* \brief Opens the directory
* \return true if opening is successful
*/
bool Directory::Open()
{
NazaraLock(m_mutex);
@ -206,6 +293,12 @@ namespace Nz
return true;
}
/*!
* \brief Sets the path of the directory
*
* \param dirPath Path of the directory
*/
void Directory::SetPath(const String& dirPath)
{
NazaraLock(m_mutex);
@ -215,6 +308,12 @@ namespace Nz
m_dirPath = File::AbsolutePath(dirPath);
}
/*!
* \brief Sets the pattern of the directory
*
* \param dirPath Pattern of the directory
*/
void Directory::SetPattern(const String& pattern)
{
NazaraLock(m_mutex);
@ -222,6 +321,18 @@ namespace Nz
m_pattern = pattern;
}
/*!
* \brief Copies the first directory to a new directory path
* \return true if copy is successful
*
* \param sourcePath Path of the original directory
* \param targetPath Path of the copied directory
*
* \remark Produces a NazaraError if could not create destination directory
* \remark Produces a NazaraError if could not open origin directory
* \remark Produces a NazaraError if could not copy a file
*/
bool Directory::Copy(const String& sourcePath, const String& destPath)
{
if (sourcePath.IsEmpty() || destPath.IsEmpty())
@ -262,6 +373,14 @@ namespace Nz
return true;
}
/*!
* \brief Creates a directory from a path
* \return true if creation is successful
*
* \param dirPath Path of the directory
* \param recursive Creates subdirectories
*/
bool Directory::Create(const String& dirPath, bool recursive)
{
if (dirPath.IsEmpty())
@ -275,7 +394,7 @@ namespace Nz
return false;
#ifdef NAZARA_PLATFORM_WINDOWS
// Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop")
// Unlike to disk (Ex: "C:"), the netwrok path is not considered as a directory (Ex: "\\Laptop")
if (path.Match("\\\\*"))
{
foundPos = path.Find('\\', 2);
@ -309,6 +428,13 @@ namespace Nz
return DirectoryImpl::Create(File::NormalizePath(dirPath));
}
/*!
* \brief Checks whether the directory exists
* \return true if directory exists
*
* \param dirPath Path of the directory
*/
bool Directory::Exists(const String& dirPath)
{
if (dirPath.IsEmpty())
@ -317,14 +443,24 @@ namespace Nz
return DirectoryImpl::Exists(File::NormalizePath(dirPath));
}
/*!
* \brief Gets the current path of this directory
* \return Current path
*/
String Directory::GetCurrent()
{
return currentPath;
}
/*!
* \brief Gets this current file relative to the engine
* \return Path to this file
*/
const char* Directory::GetCurrentFileRelativeToEngine(const char* currentFile)
{
///FIXME: Est-ce que cette méthode est au bon endroit ?
///FIXME: Is this method in the right place ?
const char* ptr = std::strstr(currentFile, "NazaraEngine/");
if (!ptr)
ptr = std::strstr(currentFile, "NazaraEngine\\");
@ -335,6 +471,14 @@ namespace Nz
return ptr;
}
/*!
* \brief Removes the directory
* \return true if remove is successful
*
* \param dirPath Path of the directory
* \param emptyDirectory Remove recursively
*/
bool Directory::Remove(const String& dirPath, bool emptyDirectory)
{
if (dirPath.IsEmpty())
@ -344,7 +488,7 @@ namespace Nz
{
Directory dir(dirPath);
if (!dir.Open())
return DirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer
return DirectoryImpl::Remove(dirPath); // If we can't open the directory, we try to delete it
while (dir.NextResult(true))
{
@ -366,6 +510,13 @@ namespace Nz
return DirectoryImpl::Remove(File::NormalizePath(dirPath));
}
/*!
* \brief Sets the current directory
* \return true if directory path exists
*
* \param dirPath Path of the directory
*/
bool Directory::SetCurrent(const String& dirPath)
{
String path = File::AbsolutePath(dirPath);
@ -376,5 +527,5 @@ namespace Nz
}
else
return false;
}
}
}

View File

@ -25,11 +25,26 @@
namespace Nz
{
/*!
* \class Nz::DynLib
* \brief Core class that represents a dynamic library loader
*/
/*!
* \brief Constructs a DynLib object by default
*/
DynLib::DynLib() :
m_impl(nullptr)
{
}
/*!
* \brief Constructs a DynLib object by move semantic
*
* \param lib DynLib to move into this
*/
DynLib::DynLib(DynLib&& lib) :
m_lastError(std::move(lib.m_lastError)),
m_impl(lib.m_impl)
@ -37,11 +52,22 @@ namespace Nz
lib.m_impl = nullptr;
}
/*!
* \brief Destructs the object and calls Unload
*
* \see Unload
*/
DynLib::~DynLib()
{
Unload();
}
/*!
* \brief Gets the last error
* \return Last error
*/
String DynLib::GetLastError() const
{
NazaraLock(m_mutex)
@ -49,12 +75,19 @@ namespace Nz
return m_lastError;
}
/*!
* \brief Gets the symbol for the name
* \return Function which is the symbol of the function name
*
* \remark Produces a NazaraError if library is not loaded with NAZARA_CORE_SAFE defined
*/
DynLibFunc DynLib::GetSymbol(const String& symbol) const
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!m_impl)
if (!IsLoaded())
{
NazaraError("Library not opened");
return nullptr;
@ -64,11 +97,25 @@ namespace Nz
return m_impl->GetSymbol(symbol, &m_lastError);
}
/*!
* \brief Checks whether the library is loaded
* \return true if loaded
*/
bool DynLib::IsLoaded() const
{
return m_impl != nullptr;
}
/*!
* \brief Loads the library with that path
* \return true if loading is successful
*
* \param libraryPath Path of the library
*
* \remark Produces a NazaraError if library is could not be loaded
*/
bool DynLib::Load(const String& libraryPath)
{
NazaraLock(m_mutex)
@ -87,11 +134,15 @@ namespace Nz
return true;
}
/*!
* \brief Unloads the library
*/
void DynLib::Unload()
{
NazaraLock(m_mutex)
if (m_impl)
if (IsLoaded())
{
m_impl->Unload();
delete m_impl;
@ -99,6 +150,13 @@ namespace Nz
}
}
/*!
* \brief Moves the other lib into this
* \return A reference to this
*
* \param lib DynLib to move in this
*/
DynLib& DynLib::operator=(DynLib&& lib)
{
Unload();

View File

@ -18,11 +18,30 @@
namespace Nz
{
/*!
* \class Nz::Error
* \brief Core class that represents an error
*/
/*!
* \brief Gets the flags of the error
* \return Flag
*/
UInt32 Error::GetFlags()
{
return s_flags;
}
/*!
* \brief Gets the last error
* \return Last error
*
* \param file Optional argument to set last error file
* \param line Optional argument to set last error line
* \param function Optional argument to set last error function
*/
String Error::GetLastError(const char** file, unsigned int* line, const char** function)
{
if (file)
@ -37,6 +56,11 @@ namespace Nz
return s_lastError;
}
/*!
* \brief Gets the last system error code
* \return "errno"
*/
unsigned int Error::GetLastSystemErrorCode()
{
#if defined(NAZARA_PLATFORM_WINDOWS)
@ -49,6 +73,13 @@ namespace Nz
#endif
}
/*!
* \brief Gets the string representation of the last system error code
* \return Message of the error
*
* \param code Code of the error
*/
String Error::GetLastSystemError(unsigned int code)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
@ -65,7 +96,7 @@ namespace Nz
String error(String::Unicode(buffer));
LocalFree(buffer);
error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message
error.Trim(); // For an unknown reason, Windows put two-three line return after the message
return error;
#elif defined(NAZARA_PLATFORM_POSIX)
@ -77,11 +108,27 @@ namespace Nz
#endif
}
/*!
* \brief Sets the flags
*
* \param flags Flags for the error
*/
void Error::SetFlags(UInt32 flags)
{
s_flags = flags;
}
/*!
* \brief Checks if the error should trigger
*
* \param type ErrorType of the error
* \param error Message of the error
*
* \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
*/
void Error::Trigger(ErrorType type, const String& error)
{
if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0)
@ -102,6 +149,19 @@ namespace Nz
throw std::runtime_error(error);
}
/*!
* \brief Checks if the error should trigger
*
* \param type ErrorType of the error
* \param error Message of the error
* \param line Line of the error
* \param file File of the error
* \param function Function of the error
*
* \remark Produces a std::abort on AssertFailed with NAZARA_CORE_EXIT_ON_ASSERT_FAILURE defined
* \remark Produces a std::runtime_error on AssertFailed or throwing exception
*/
void Error::Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
{
if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0)

View File

@ -8,22 +8,50 @@
namespace Nz
{
/*!
* \class Nz::ErrorFlags
* \brief Core class that represents flags for error
*/
/*!
* \brief Constructs a ErrorFlags object with flags
*
* \param flags Flags for the error
* \param replace Replace the entirely the old flag if true, else do a "OR"
*/
ErrorFlags::ErrorFlags(UInt32 flags, bool replace) :
m_previousFlags(Error::GetFlags())
{
SetFlags(flags, replace);
}
/*!
* \brief Destructs the object and sets the old flag
*/
ErrorFlags::~ErrorFlags()
{
Error::SetFlags(m_previousFlags);
}
/*!
* \brief Gets the previous flag
* \return Previous flag
*/
UInt32 ErrorFlags::GetPreviousFlags() const
{
return m_previousFlags;
}
/*!
* \brief Sets the flags
*
* \param flags Flags for the error
* \param replace Replace the entirely the old flag if true, else do a "OR"
*/
void ErrorFlags::SetFlags(UInt32 flags, bool replace)
{
if (!replace)

View File

@ -30,23 +30,51 @@
namespace Nz
{
/*!
* \class Nz::File
* \brief Core class that represents a file
*/
/*!
* \brief Constructs a File object by default
*/
File::File() :
m_impl(nullptr)
{
}
/*!
* \brief Constructs a File object with a file path
*
* \param filePath Path to the file
*/
File::File(const String& filePath) :
File()
{
SetFile(filePath);
}
/*!
* \brief Constructs a File object with a file path and flags
*
* \param filePath Path to the file
* \param openMode Flag of the file
*/
File::File(const String& filePath, UInt32 openMode) :
File()
{
Open(filePath, openMode);
}
/*!
* \brief Constructs a File object by move semantic
*
* \param file File to move into this
*/
File::File(File&& file) noexcept :
Stream(std::move(file)),
m_filePath(std::move(file.m_filePath)),
@ -55,16 +83,33 @@ namespace Nz
file.m_impl = nullptr;
}
/*!
* \brief Destructs the object and calls Close
*
* \see Close
*/
File::~File()
{
Close();
}
/*!
* \brief Copies this file to a new file path
* \return true if copy is successful
*
* \param newFilePath Path of the new file
*/
bool File::Copy(const String& newFilePath)
{
return Copy(m_filePath, newFilePath);
}
/*!
* \brief Closes the file
*/
void File::Close()
{
NazaraLock(m_mutex)
@ -79,6 +124,11 @@ namespace Nz
}
}
/*!
* \brief Deletes the file
* \return true if delete is successful
*/
bool File::Delete()
{
NazaraLock(m_mutex)
@ -88,6 +138,13 @@ namespace Nz
return Delete(m_filePath);
}
/*!
* \brief Checks whether the file has reached the end
* \return true if cursor is at the end of the file
*
* \remark Produces a NazaraError if file is not open with NAZARA_CORE_SAFE defined
*/
bool File::EndOfFile() const
{
NazaraLock(m_mutex)
@ -95,7 +152,7 @@ namespace Nz
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
NazaraError("File not open");
return false;
}
#endif
@ -103,11 +160,25 @@ namespace Nz
return m_impl->EndOfFile();
}
/*!
* \brief Checks whether the file has reached the end of the stream
* \return true if cursor is at the end of the file
*
* \remark Produces a NazaraError if file is not open with NAZARA_CORE_SAFE defined
*
* \see EndOfFile
*/
bool File::EndOfStream() const
{
return EndOfFile();
}
/*!
* \brief Checks whether the file exists
* \return true if file exists
*/
bool File::Exists() const
{
NazaraLock(m_mutex)
@ -118,6 +189,11 @@ namespace Nz
return Exists(m_filePath);
}
/*!
* \brief Gets the creation time of the file
* \return Information about the creation time
*/
time_t File::GetCreationTime() const
{
NazaraLock(m_mutex)
@ -125,15 +201,27 @@ namespace Nz
return GetCreationTime(m_filePath);
}
/*!
* \brief Gets the position of the cursor in the file
* \return Position of the cursor
*
* \remark Produces a NazaraAssert if file is not open
*/
UInt64 File::GetCursorPos() const
{
NazaraLock(m_mutex)
NazaraAssert(IsOpen(), "File is not opened");
NazaraAssert(IsOpen(), "File is not open");
return m_impl->GetCursorPos();
}
/*!
* \brief Gets the directory of the file
* \return Directory of the file
*/
String File::GetDirectory() const
{
NazaraLock(m_mutex)
@ -141,6 +229,11 @@ namespace Nz
return m_filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true);
}
/*!
* \brief Gets the name of the file
* \return Name of the file
*/
String File::GetFileName() const
{
NazaraLock(m_mutex)
@ -148,6 +241,11 @@ namespace Nz
return m_filePath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
}
/*!
* \brief Gets the last time the file was accessed
* \return Information about the last access time
*/
time_t File::GetLastAccessTime() const
{
NazaraLock(m_mutex)
@ -155,6 +253,11 @@ namespace Nz
return GetLastAccessTime(m_filePath);
}
/*!
* \brief Gets the last time the file was written
* \return Information about the last writing time
*/
time_t File::GetLastWriteTime() const
{
NazaraLock(m_mutex)
@ -162,6 +265,11 @@ namespace Nz
return GetLastWriteTime(m_filePath);
}
/*!
* \brief Gets the path of the file
* \return Path of the file
*/
String File::GetPath() const
{
NazaraLock(m_mutex)
@ -169,6 +277,11 @@ namespace Nz
return m_filePath;
}
/*!
* \brief Gets the size of the file
* \return Size of the file
*/
UInt64 File::GetSize() const
{
NazaraLock(m_mutex)
@ -176,6 +289,11 @@ namespace Nz
return GetSize(m_filePath);
}
/*!
* \brief Checks whether the file is open
* \return true if open
*/
bool File::IsOpen() const
{
NazaraLock(m_mutex)
@ -183,22 +301,14 @@ namespace Nz
return m_impl != nullptr;
}
bool File::Rename(const String& newFilePath)
{
NazaraLock(m_mutex)
bool opened = IsOpen();
Close();
bool success = Rename(m_filePath, newFilePath);
if (success)
m_filePath = NormalizePath(newFilePath);
if (opened)
Open();
return success;
}
/*!
* \brief Opens the file with flags
* \return true if opening is successful
*
* \param openMode Flag for file
*
* \remark Produces a NazaraError if OS error to open a file
*/
bool File::Open(unsigned int openMode)
{
@ -215,7 +325,7 @@ namespace Nz
std::unique_ptr<FileImpl> impl(new FileImpl(this));
if (!impl->Open(m_filePath, openMode))
{
ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut
ErrorFlags flags(ErrorFlag_Silent); // Silent by default
NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError());
return false;
}
@ -231,6 +341,16 @@ namespace Nz
return true;
}
/*!
* \brief Opens the file with file path and flags
* \return true if opening is successful
*
* \param filePath Path to the file
* \param openMode Flag for file
*
* \remark Produces a NazaraError if OS error to open a file
*/
bool File::Open(const String& filePath, unsigned int openMode)
{
NazaraLock(m_mutex)
@ -241,24 +361,72 @@ namespace Nz
return Open(openMode);
}
/*!
* \brief Renames the file with a new name
* \return true if rename is successful
*/
bool File::Rename(const String& newFilePath)
{
NazaraLock(m_mutex)
bool open = IsOpen();
Close();
bool success = Rename(m_filePath, newFilePath);
if (success)
m_filePath = NormalizePath(newFilePath);
if (open)
Open();
return success;
}
/*!
* \brief Sets the position of the cursor
* \return true if cursor is successfully positioned
*
* \param pos Position of the cursor
* \param offset Offset according to the cursor position
*
* \remark Produces a NazaraAssert if file is not open
*/
bool File::SetCursorPos(CursorPosition pos, Int64 offset)
{
NazaraLock(m_mutex)
NazaraAssert(IsOpen(), "File is not opened");
NazaraAssert(IsOpen(), "File is not open");
return m_impl->SetCursorPos(pos, offset);
}
/*!
* \brief Sets the position of the cursor
* \return true if cursor is successfully positioned
*
* \param offset Offset according to the cursor begin position
*
* \remark Produces a NazaraAssert if file is not open
*/
bool File::SetCursorPos(UInt64 offset)
{
NazaraLock(m_mutex)
NazaraAssert(IsOpen(), "File is not opened");
NazaraAssert(IsOpen(), "File is not open");
return m_impl->SetCursorPos(CursorPosition_AtBegin, offset);
}
/*!
* \brief Sets the file path
* \return true if file opening is successful
*
* \remark Produces a NazaraError if file path can not be open
*/
bool File::SetFile(const String& filePath)
{
NazaraLock(m_mutex)
@ -285,6 +453,13 @@ namespace Nz
return true;
}
/*!
* \brief Sets the file path
* \return A reference to this
*
* \remark Produces a NazaraError if file path can not be open
*/
File& File::operator=(const String& filePath)
{
SetFile(filePath);
@ -292,6 +467,13 @@ namespace Nz
return *this;
}
/*!
* \brief Moves the other file into this
* \return A reference to this
*
* \param file File to move in this
*/
File& File::operator=(File&& file) noexcept
{
NazaraLock(m_mutex)
@ -302,9 +484,18 @@ namespace Nz
return *this;
}
/*!
* \brief Gets the absolute path of the file
* \return Absolute path of the file
*
* \param filePath Path of the file
*
* \remark Produces a NazaraError if filePath is weird with NAZARA_PLATFORM_WINDOWS defined
*/
String File::AbsolutePath(const String& filePath)
{
// Je n'utilise pas les fonctions de l'OS car elles ne fonctionnent que pour un chemin existant
// We don't use OS functions because they only work for existing path
String path = NormalizePath(filePath);
if (path.IsEmpty())
return String();
@ -319,7 +510,7 @@ namespace Nz
base = "\\\\";
start = 2;
}
else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
else if (path.StartsWith('\\')) // Special : '\' refering to root
{
String drive = Directory::GetCurrent().SubStringTo('\\');
String end = path.SubString(1, -1);
@ -351,14 +542,14 @@ namespace Nz
if (path.Split(sep, NAZARA_DIRECTORY_SEPARATOR) <= 1)
return path;
// Nous avons un chemin absolu, mais il nous faut un peu le nettoyer
// We have the absolute path, but we need to clean it up
for (unsigned int i = 0; i < sep.size(); ++i)
{
if (sep[i] == '.')
sep.erase(sep.begin() + i--);
else if (sep[i] == "..")
{
if (i > start) // Si nous ne sommes pas dans la partie protégée
if (i > start) // If we are not in the protected area
sep.erase(sep.begin() + i--);
sep.erase(sep.begin() + i--);
@ -377,6 +568,14 @@ namespace Nz
return stream;
}
/*!
* \brief Copies the first file to a new file path
* \return true if copy is successful
*
* \param sourcePath Path of the original file
* \param targetPath Path of the copied file
*/
bool File::Copy(const String& sourcePath, const String& targetPath)
{
if (sourcePath.IsEmpty() || targetPath.IsEmpty())
@ -385,6 +584,13 @@ namespace Nz
return FileImpl::Copy(NormalizePath(sourcePath), NormalizePath(targetPath));
}
/*!
* \brief Deletes the file
* \return true if delete is successful
*
* \param filePath Path of the file
*/
bool File::Delete(const String& filePath)
{
if (filePath.IsEmpty())
@ -393,6 +599,13 @@ namespace Nz
return FileImpl::Delete(NormalizePath(filePath));
}
/*!
* \brief Checks whether the file exists
* \return true if file exists
*
* \param filePath Path of the file
*/
bool File::Exists(const String& filePath)
{
if (filePath.IsEmpty())
@ -401,6 +614,13 @@ namespace Nz
return FileImpl::Exists(NormalizePath(filePath));
}
/*!
* \brief Gets the creation time of the file
* \return Information about the creation time
*
* \param filePath Path of the file
*/
time_t File::GetCreationTime(const String& filePath)
{
if (filePath.IsEmpty())
@ -409,10 +629,23 @@ namespace Nz
return FileImpl::GetCreationTime(NormalizePath(filePath));
}
/*!
* \brief Gets the directory of the file
* \return Directory of the file
*
* \param filePath Path of the file
*/
String File::GetDirectory(const String& filePath)
{
return filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true);
}
/*!
* \brief Gets the last time the file was accessed
* \return Information about the last access time
*
* \param filePath Path of the file
*/
time_t File::GetLastAccessTime(const String& filePath)
{
@ -422,6 +655,13 @@ namespace Nz
return FileImpl::GetLastAccessTime(NormalizePath(filePath));
}
/*!
* \brief Gets the last time the file was written
* \return Information about the last writing time
*
* \param filePath Path of the file
*/
time_t File::GetLastWriteTime(const String& filePath)
{
if (filePath.IsEmpty())
@ -430,6 +670,13 @@ namespace Nz
return FileImpl::GetLastWriteTime(NormalizePath(filePath));
}
/*!
* \brief Gets the size of the file
* \return Size of the file
*
* \param filePath Path of the file
*/
UInt64 File::GetSize(const String& filePath)
{
if (filePath.IsEmpty())
@ -438,6 +685,13 @@ namespace Nz
return FileImpl::GetSize(NormalizePath(filePath));
}
/*!
* \brief Checks whether the file path is absolute
* \return true if path is absolute
*
* \param filePath Path to test
*/
bool File::IsAbsolute(const String& filePath)
{
String path(filePath.Trimmed());
@ -451,7 +705,7 @@ namespace Nz
return true;
else if (path.Match("\\\\*")) // Ex: \\Laptop
return true;
else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
else if (path.StartsWith('\\')) // Special : '\' refering to the root
return true;
else
return false;
@ -462,6 +716,13 @@ namespace Nz
#endif
}
/*!
* \brief Normalizes the file path
* \return Path normalized (replacing '/' with '\\' on Windows, ...)
*
* \param filePath Path to normalize
*/
String File::NormalizePath(const String& filePath)
{
String path = NormalizeSeparators(filePath.Trimmed());
@ -475,6 +736,13 @@ namespace Nz
return path;
}
/*!
* \brief Normalizes the path separator
* \return Path normalized (replacing '/' with '\\' on Windows, ...)
*
* \param filePath Path to normalize
*/
String File::NormalizeSeparators(const String& filePath)
{
String path(filePath);
@ -490,6 +758,14 @@ namespace Nz
return path;
}
/*!
* \brief Renames the file with a new name
* \return true if rename is successful
*
* \param sourcePath Path of the original file
* \param targetPath Path of the renamed file
*/
bool File::Rename(const String& sourcePath, const String& targetPath)
{
if (sourcePath.IsEmpty() || targetPath.IsEmpty())
@ -498,6 +774,12 @@ namespace Nz
return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath));
}
/*!
* \brief Flushes the stream
*
* \remark Produces a NazaraAssert if file is not open
*/
void File::FlushStream()
{
NazaraLock(m_mutex)
@ -507,11 +789,21 @@ namespace Nz
m_impl->Flush();
}
/*!
* \brief Reads blocks
* \return Number of blocks read
*
* \param buffer Preallocated buffer to contain information read
* \param size Size of the read and thus of the buffer
*
* \remark Produces a NazaraAssert if file is not open
*/
std::size_t File::ReadBlock(void* buffer, std::size_t size)
{
NazaraLock(m_mutex)
NazaraAssert(IsOpen(), "File is not opened");
NazaraAssert(IsOpen(), "File is not open");
if (size == 0)
return 0;
@ -520,7 +812,7 @@ namespace Nz
return m_impl->Read(buffer, size);
else
{
// Si nous ne devons rien lire, nous avançons simplement
// If we don't have to read, we move forward
UInt64 currentPos = m_impl->GetCursorPos();
m_impl->SetCursorPos(CursorPosition_AtCurrent, size);
@ -529,11 +821,22 @@ namespace Nz
}
}
/*!
* \brief Writes blocks
* \return Number of blocks 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 file is not open
* \remark Produces a NazaraAssert if buffer is nullptr
*/
std::size_t File::WriteBlock(const void* buffer, std::size_t size)
{
NazaraLock(m_mutex)
NazaraAssert(IsOpen(), "File is not opened");
NazaraAssert(IsOpen(), "File is not open");
if (size == 0)
return 0;
@ -543,9 +846,22 @@ namespace Nz
return m_impl->Write(buffer, size);
}
/*!
* \brief Appends the file to the hash
* \return true if hash is successful
*
* \param hash Hash to append data of the file
* \param originalFile Path of the file
*
* \remark Produces a NazaraAssert if hash is nullptr
* \remark Produces a NazaraError if file could not be open
* \remark Produces a NazaraError if file could not be read
*/
NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile)
{
NazaraAssert(hash, "Invalid hash");
File file(originalFile.GetPath());
if (!file.Open(OpenMode_ReadOnly))
{

View File

@ -12,6 +12,17 @@
namespace Nz
{
/*!
* \class Nz::FileLogger
* \brief Core class that represents a file logger
*/
/*!
* \brief Constructs a FileLogger object with a file name
*
* \param logPath Path to log
*/
FileLogger::FileLogger(const String& logPath) :
m_outputFile(logPath),
m_forceStdOutput(false),
@ -20,28 +31,64 @@ namespace Nz
{
}
/*!
* \brief Destructs the object
*/
FileLogger::~FileLogger() = default;
/*!
* \brief Enables the log of the time
*
* \param enable If true, enables the time log
*/
void FileLogger::EnableTimeLogging(bool enable)
{
m_timeLoggingEnabled = enable;
}
/*!
* \brief Enables the replication to the stdout
*
* \param enable If true, enables the replication
*/
void FileLogger::EnableStdReplication(bool enable)
{
m_stdReplicationEnabled = enable;
}
/*!
* \brief Checks whether or not the replication to the stdout is enabled
* \return true If replication is enabled
*/
bool FileLogger::IsStdReplicationEnabled()
{
return m_stdReplicationEnabled;
}
/*!
* \brief Checks whether or not the logging of the time is enabled
* \return true If logging of the time is enabled
*/
bool FileLogger::IsTimeLoggingEnabled()
{
return m_timeLoggingEnabled;
}
/*!
* \brief Writes a string in the log
*
* \param string String to log
*
* \remark Produces a NazaraError if file could not be opened
*
* \see WriteError
*/
void FileLogger::Write(const String& string)
{
if (m_forceStdOutput || m_stdReplicationEnabled)
@ -85,6 +132,18 @@ namespace Nz
m_outputFile.Write(stream);
}
/*!
* \brief Writes an error in the log
*
* \param type The error type
* \param error The error text
* \param line The line the error occurred
* \param file The file the error occurred
* \param function The function the error occurred
*
* \see Write
*/
void FileLogger::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
{
if (m_forceStdOutput || m_stdReplicationEnabled)

View File

@ -16,13 +16,36 @@
namespace Nz
{
/*!
* \class Nz::GuillotineBinPack
* \brief Core class that represents the "Guillotine problem", combination of the "Bin packing problem" and the "cutting stock"
*/
namespace
{
/*!
* \brief Gets the score for fitting the area
* \return Score of the fitting
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreBestAreaFit(int width, int height, const Rectui& freeRectSize)
{
return freeRectSize.width * freeRectSize.height - width * height;
}
/*!
* \brief Gets the score for fitting the area following long side
* \return Score of the fitting following long side
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreBestLongSideFit(int width, int height, const Rectui& freeRectSize)
{
int leftoverHoriz = std::abs(static_cast<int>(freeRectSize.width - width));
@ -32,6 +55,15 @@ namespace Nz
return leftover;
}
/*!
* \brief Gets the score for fitting the area following short side
* \return Score of the fitting following short side
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreBestShortSideFit(int width, int height, const Rectui& freeRectSize)
{
int leftoverHoriz = std::abs(static_cast<int>(freeRectSize.width - width));
@ -41,37 +73,85 @@ namespace Nz
return leftover;
}
/*!
* \brief Gets the worst score for fitting the area
* \return Worst score of the fitting
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreWorstAreaFit(int width, int height, const Rectui& freeRectSize)
{
return -ScoreBestAreaFit(width, height, freeRectSize);
}
/*!
* \brief Gets the worst score for fitting the area following long side
* \return Worst score of the fitting following long side
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreWorstLongSideFit(int width, int height, const Rectui& freeRectSize)
{
return -ScoreBestLongSideFit(width, height, freeRectSize);
}
/*!
* \brief Gets the worst score for fitting the area following short side
* \return Worst score of the fitting following short side
*
* \param width Width
* \param height Height
* \param freeRectSize Free area
*/
int ScoreWorstShortSideFit(int width, int height, const Rectui& freeRectSize)
{
return -ScoreBestShortSideFit(width, height, freeRectSize);
}
}
/*!
* \brief Constructs a GuillotineBinPack object by default
*/
GuillotineBinPack::GuillotineBinPack()
{
Reset();
}
/*!
* \brief Constructs a GuillotineBinPack object with width and height
*
* \param width Width
* \param height Height
*/
GuillotineBinPack::GuillotineBinPack(unsigned int width, unsigned int height)
{
Reset(width, height);
}
/*!
* \brief Constructs a GuillotineBinPack object with area
*
* \param size Vector2 representing the area (width, height)
*/
GuillotineBinPack::GuillotineBinPack(const Vector2ui& size)
{
Reset(size);
}
/*!
* \brief Clears the content
*/
void GuillotineBinPack::Clear()
{
m_freeRectangles.clear();
@ -80,6 +160,15 @@ namespace Nz
m_usedArea = 0;
}
/*!
* \brief Expands the content
*
* \param newWidth New width for the expansion
* \param newHeight New height for the expansion
*
* \see Expand
*/
void GuillotineBinPack::Expand(unsigned int newWidth, unsigned newHeight)
{
unsigned int oldWidth = m_width;
@ -98,52 +187,123 @@ namespace Nz
while (MergeFreeRectangles());
}
/*!
* \brief Expands the content
*
* \param newSize New area for the expansion
*
* \see Expand
*/
void GuillotineBinPack::Expand(const Vector2ui& newSize)
{
Expand(newSize.x, newSize.y);
}
/*!
* \brief Frees the rectangle
*
* \param rect Area to free
*
* \remark This method should only be called with computed rectangles by the method Insert and can produce fragmentation
*/
void GuillotineBinPack::FreeRectangle(const Rectui& rect)
{
///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation
m_freeRectangles.push_back(rect);
m_usedArea -= rect.width * rect.height;
}
/*!
* \brief Gets the height
* \return Height of the area
*/
unsigned int GuillotineBinPack::GetHeight() const
{
return m_height;
}
/*!
* \brief Gets percentage of occupation
* \return Percentage of the already occupied area
*/
float GuillotineBinPack::GetOccupancy() const
{
return static_cast<float>(m_usedArea)/(m_width*m_height);
}
/*!
* \brief Gets the size of the area
* \return Size of the area
*/
Vector2ui GuillotineBinPack::GetSize() const
{
return Vector2ui(m_width, m_height);
}
/*!
* \brief Gets the width
* \return Width of the area
*/
unsigned int GuillotineBinPack::GetWidth() const
{
return m_width;
}
/*!
* \brief Inserts rectangles in the area
* \return true if each rectangle could be inserted
*
* \param rects List of rectangles
* \param count Count of rectangles
* \param merge Merge possible
* \param rectChoice Heuristic to use to free
* \param splitMethod Heuristic to use to split
*/
bool GuillotineBinPack::Insert(Rectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod)
{
return Insert(rects, nullptr, nullptr, count, merge, rectChoice, splitMethod);
}
/*!
* \brief Inserts rectangles in the area
* \return true if each rectangle could be inserted
*
* \param rects List of rectangles
* \param flipped List of flipped rectangles
* \param count Count of rectangles
* \param merge Merge possible
* \param rectChoice Heuristic to use to free
* \param splitMethod Heuristic to use to split
*/
bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod)
{
return Insert(rects, flipped, nullptr, count, merge, rectChoice, splitMethod);
}
/*!
* \brief Inserts rectangles in the area
* \return true if each rectangle could be inserted
*
* \param rects List of rectangles
* \param flipped List of flipped rectangles
* \param flipped List of inserted rectangles
* \param count Count of rectangles
* \param merge Merge possible
* \param rectChoice Heuristic to use to free
* \param splitMethod Heuristic to use to split
*/
bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod)
{
std::vector<Rectui*> remainingRects(count); // La position du rectangle
std::vector<Rectui*> remainingRects(count); // Position of the rectangle
for (unsigned int i = 0; i < count; ++i)
remainingRects[i] = &rects[i];
@ -214,7 +374,7 @@ namespace Nz
// If we didn't manage to find any rectangle to pack, abort.
if (bestScore == std::numeric_limits<int>::max())
{
// Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés
// If we can do it, we mark the rectangle could be inserted
if (inserted)
{
for (Rectui* rect : remainingRects)
@ -259,9 +419,13 @@ namespace Nz
return true;
}
/*!
* \brief Merges free rectangles together
* \return true if there was a merge (and thus if a merge is still possible)
*/
bool GuillotineBinPack::MergeFreeRectangles()
{
///DOC: Renvoie true s'il y a eu fusion (et donc si une fusion est encore possible)
std::size_t oriSize = m_freeRectangles.size();
// Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one.
@ -312,6 +476,10 @@ namespace Nz
return m_freeRectangles.size() < oriSize;
}
/*!
* \brief Resets the area
*/
void GuillotineBinPack::Reset()
{
m_height = 0;
@ -320,6 +488,13 @@ namespace Nz
Clear();
}
/*!
* \brief Resets the area
*
* \param width Width
* \param height Height
*/
void GuillotineBinPack::Reset(unsigned int width, unsigned int height)
{
m_height = height;
@ -328,11 +503,25 @@ namespace Nz
Clear();
}
/*!
* \brief Resets the area
*
* \param size Size of the area
*/
void GuillotineBinPack::Reset(const Vector2ui& size)
{
Reset(size.x, size.y);
}
/*!
* \brief Splits the free rectangle along axis
*
* \param freeRect Free rectangle to split
* \param placedRect Already placed rectangle
* \param splitHorizontal Split horizontally (or vertically)
*/
void GuillotineBinPack::SplitFreeRectAlongAxis(const Rectui& freeRect, const Rectui& placedRect, bool splitHorizontal)
{
// Form the two new rectangles.
@ -365,50 +554,60 @@ namespace Nz
m_freeRectangles.push_back(right);
}
/*!
* \brief Splits the free rectangle using the heuristic
*
* \param freeRect Free rectangle to split
* \param placedRect Already placed rectangle
* \param method Method used to split
*
* \remark Produces a NazaraError if enumeration GuillotineSplitHeuristic is invalid
*/
void GuillotineBinPack::SplitFreeRectByHeuristic(const Rectui& freeRect, const Rectui& placedRect, GuillotineSplitHeuristic method)
{
// Compute the lengths of the leftover area.
// Compute the lengths of the leftover area
const int w = freeRect.width - placedRect.width;
const int h = freeRect.height - placedRect.height;
// Placing placedRect into freeRect results in an L-shaped free area, which must be split into
// two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line.
// We have two choices: horizontal or vertical.
// two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line
// We have two choices: horizontal or vertical
// Use the given heuristic to decide which choice to make.
// Use the given heuristic to decide which choice to make
bool splitHorizontal;
switch (method)
{
case SplitLongerAxis:
// Split along the longer total axis.
// Split along the longer total axis
splitHorizontal = (freeRect.width > freeRect.height);
break;
case SplitLongerLeftoverAxis:
// Split along the longer leftover axis.
// Split along the longer leftover axis
splitHorizontal = (w > h);
break;
case SplitMaximizeArea:
// Maximize the smaller area == minimize the larger area.
// Tries to make the rectangles more even-sized.
// Maximize the smaller area == minimize the larger area
// Tries to make the rectangles more even-sized
splitHorizontal = (placedRect.width * h <= w * placedRect.height);
break;
case SplitMinimizeArea:
// Maximize the larger area == minimize the smaller area.
// Tries to make the single bigger rectangle.
// Maximize the larger area == minimize the smaller area
// Tries to make the single bigger rectangle
splitHorizontal = (placedRect.width * h > w * placedRect.height);
break;
case SplitShorterAxis:
// Split along the shorter total axis.
// Split along the shorter total axis
splitHorizontal = (freeRect.width <= freeRect.height);
break;
case SplitShorterLeftoverAxis:
// Split along the shorter leftover axis.
// Split along the shorter leftover axis
splitHorizontal = (w <= h);
break;
@ -417,10 +616,22 @@ namespace Nz
splitHorizontal = true;
}
// Perform the actual split.
// Perform the actual split
SplitFreeRectAlongAxis(freeRect, placedRect, splitHorizontal);
}
/*!
* \brief Gets the score using heuristic
* \return Score of the heuristic
*
* \param width Width
* \param height Height
* \param freeRect Free area
* \param rectChoice Heuristic to get score
*
* \remark Produces a NazaraError if enumeration FreeRectChoiceHeuristic is invalid
*/
int GuillotineBinPack::ScoreByHeuristic(int width, int height, const Rectui& freeRect, FreeRectChoiceHeuristic rectChoice)
{
switch (rectChoice)

View File

@ -82,11 +82,31 @@ namespace Nz
char s_brandString[48] = "Not initialized";
}
/*!
* \class Nz::HardwareInfo
* \brief Core class that represents the info we can get from hardware
*/
/*!
* \brief Generates the cpuid instruction (available on x86 & x64)
*
* \param functionId Information to retrieve
* \param subFunctionId Additional code for information retrieval
* \param result Supported features of the CPU
*/
void HardwareInfo::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 result[4])
{
return HardwareInfoImpl::Cpuid(functionId, subFunctionId, result);
}
/*!
* \brief Gets the brand of the processor
* \return String of the brand
*
* \remark Produces a NazaraError if not Initialize
*/
String HardwareInfo::GetProcessorBrandString()
{
if (!Initialize())
@ -95,13 +115,26 @@ namespace Nz
return s_brandString;
}
/*!
* \brief Gets the number of threads
* \return Number of threads available on the CPU
*
* \remark Doesn't need the initialization of HardwareInfo
*/
unsigned int HardwareInfo::GetProcessorCount()
{
///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner
static unsigned int processorCount = std::max(HardwareInfoImpl::GetProcessorCount(), 1U);
return processorCount;
}
/*!
* \brief Gets the processor vendor
* \return ProcessorVendor containing information the vendor
*
* \remark Produces a NazaraError if not Initialize
*/
ProcessorVendor HardwareInfo::GetProcessorVendor()
{
if (!Initialize())
@ -110,6 +143,13 @@ namespace Nz
return s_vendorEnum;
}
/*!
* \brief Gets the vendor of the processor
* \return String of the vendor
*
* \remark Produces a NazaraError if not Initialize
*/
String HardwareInfo::GetProcessorVendorName()
{
if (!Initialize())
@ -118,13 +158,26 @@ namespace Nz
return vendorNames[s_vendorEnum+1];
}
/*!
* \brief Gets the amount of total memory
* \return Number of total memory available
*
* \remark Doesn't need the initialization of HardwareInfo
*/
UInt64 HardwareInfo::GetTotalMemory()
{
///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner
static UInt64 totalMemory = HardwareInfoImpl::GetTotalMemory();
return totalMemory;
}
/*!
* \brief Checks whether the processor owns the capacity to handle certain instructions
* \return true If instructions supported
*
* \remark Produces a NazaraError if capability is a wrong enum with NAZARA_DEBUG defined
*/
bool HardwareInfo::HasCapability(ProcessorCap capability)
{
#ifdef NAZARA_DEBUG
@ -138,9 +191,16 @@ namespace Nz
return s_capabilities[capability];
}
/*!
* \brief Initializes the HardwareInfo class
* \return true if successful
*
* \remark Produces a NazaraError if cpuid is not supported
*/
bool HardwareInfo::Initialize()
{
if (s_initialized)
if (IsInitialized())
return true;
if (!HardwareInfoImpl::IsCpuidSupported())
@ -151,21 +211,21 @@ namespace Nz
s_initialized = true;
UInt32 registers[4]; // Récupère les quatre registres (EAX, EBX, ECX et EDX)
UInt32 registers[4]; // Get the four registers (EAX, EBX, ECX et EDX)
// Pour plus de clarté
// To make it more clear
UInt32& eax = registers[0];
UInt32& ebx = registers[1];
UInt32& ecx = registers[2];
UInt32& edx = registers[3];
// Pour commencer, on va récupérer l'identifiant du constructeur ainsi que l'id de fonction maximal supporté par le CPUID
// To begin, we get the id of the constructor and the id of maximal functions supported by the CPUID
HardwareInfoImpl::Cpuid(0, 0, registers);
// Attention à l'ordre : EBX, EDX, ECX
// Watchout to the order : EBX, EDX, ECX
UInt32 manufacturerId[3] = {ebx, edx, ecx};
// Identification du concepteur
// Identification of conceptor
s_vendorEnum = ProcessorVendor_Unknown;
for (const VendorString& vendorString : vendorStrings)
{
@ -178,7 +238,7 @@ namespace Nz
if (eax >= 1)
{
// Récupération de certaines capacités du processeur (ECX et EDX, fonction 1)
// Recuperation of certain capacities of the processor (ECX et EDX, function 1)
HardwareInfoImpl::Cpuid(1, 0, registers);
s_capabilities[ProcessorCap_AVX] = (ecx & (1U << 28)) != 0;
@ -192,53 +252,67 @@ namespace Nz
s_capabilities[ProcessorCap_SSE42] = (ecx & (1U << 20)) != 0;
}
// Récupération de la plus grande fonction étendue supportée (EAX, fonction 0x80000000)
// Recuperation of biggest extended function handled (EAX, fonction 0x80000000)
HardwareInfoImpl::Cpuid(0x80000000, 0, registers);
UInt32 maxSupportedExtendedFunction = eax;
if (maxSupportedExtendedFunction >= 0x80000001)
{
// Récupération des capacités étendues du processeur (ECX et EDX, fonction 0x80000001)
// Recuperation of extended capabilities of the processor (ECX et EDX, fonction 0x80000001)
HardwareInfoImpl::Cpuid(0x80000001, 0, registers);
s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support du 64bits, indépendant de l'OS
s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support of 64bits, independant of the OS
s_capabilities[ProcessorCap_FMA4] = (ecx & (1U << 16)) != 0;
s_capabilities[ProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0;
s_capabilities[ProcessorCap_XOP] = (ecx & (1U << 11)) != 0;
if (maxSupportedExtendedFunction >= 0x80000004)
{
// Récupération d'une chaîne de caractère décrivant le processeur (EAX, EBX, ECX et EDX,
// fonctions de 0x80000002 à 0x80000004 compris)
// Recuperation of the string describing the processor (EAX, EBX, ECX et EDX,
// functions from 0x80000002 to 0x80000004 inclusive)
char* ptr = &s_brandString[0];
for (UInt32 code = 0x80000002; code <= 0x80000004; ++code)
{
HardwareInfoImpl::Cpuid(code, 0, registers);
std::memcpy(ptr, &registers[0], 4*sizeof(UInt32)); // On rajoute les 16 octets à la chaîne
std::memcpy(ptr, &registers[0], 4*sizeof(UInt32)); // We add the 16 bytes to the string
ptr += 4*sizeof(UInt32);
}
// Le caractère nul faisant partie de la chaîne retournée par le CPUID, pas besoin de le rajouter
// The character '\0' is already returned
}
}
return true;
}
/*!
* \brief Checks whether the instruction of cpuid is supported
* \return true if it the case
*/
bool HardwareInfo::IsCpuidSupported()
{
return HardwareInfoImpl::IsCpuidSupported();
}
/*!
* \brief Checks whether the class HardwareInfo is initialized
* \return true if it is initialized
*/
bool HardwareInfo::IsInitialized()
{
return s_initialized;
}
/*!
* \brief Unitializes the class HardwareInfo
*/
void HardwareInfo::Uninitialize()
{
// Rien à faire
// Nothing to do
s_initialized = false;
}
}

View File

@ -8,12 +8,27 @@
namespace Nz
{
/*!
* \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
*/
LockGuard::LockGuard(Mutex& mutex) :
m_mutex(mutex)
{
m_mutex.Lock();
}
/*!
* \brief Destructs a LockGuard object and unlocks the mutex
*/
LockGuard::~LockGuard()
{
m_mutex.Unlock();

View File

@ -15,21 +15,48 @@ namespace Nz
StdLogger s_stdLogger;
}
/*!
* \class Nz::Log
* \brief Core class that represents a logger
*/
/*!
* \brief Enables the log
*
* \param enable If true, enables the log
*/
void Log::Enable(bool enable)
{
s_enabled = enable;
}
/*!
* \brief Gets the logger
* \return An abstract pointer to the logger
*/
AbstractLogger* Log::GetLogger()
{
return s_logger;
}
/*!
* \brief Checks whether or not the logging is enabled
* \return true If logging is enabled
*/
bool Log::IsEnabled()
{
return s_enabled;
}
/*!
* \brief Sets the logger
*
* \param logger AbstractLogger to log
*/
void Log::SetLogger(AbstractLogger* logger)
{
if (s_logger != &s_stdLogger)
@ -40,6 +67,14 @@ namespace Nz
s_logger = &s_stdLogger;
}
/*!
* \brief Writes a string in the log
*
* \param string String to log
*
* \see WriteError
*/
void Log::Write(const String& string)
{
if (s_enabled)
@ -48,6 +83,18 @@ namespace Nz
OnLogWrite(string);
}
/*!
* \brief Writes the error in the log
*
* \param type Type of the error
* \param error Message of the error
* \param line Line of the error
* \param file File of the error
* \param function Function of the error
*
* \see Write
*/
void Log::WriteError(ErrorType type, const String& error, unsigned int line, const char* file, const char* function)
{
if (s_enabled)
@ -56,12 +103,21 @@ namespace Nz
OnLogWriteError(type, error, line, file, function);
}
/*!
* \brief Initializes the Log class
* \return true if successful
*/
bool Log::Initialize()
{
SetLogger(new FileLogger());
return true;
}
/*!
* \brief Unitializes the Log class
*/
void Log::Uninitialize()
{
SetLogger(nullptr);

View File

@ -15,7 +15,7 @@
#include <pthread.h>
#endif
// Le seul fichier n'ayant pas à inclure Debug.hpp
// The only file that does not need to include Debug.hpp
namespace Nz
{
@ -61,18 +61,43 @@ namespace Nz
CRITICAL_SECTION s_mutex;
#elif defined(NAZARA_PLATFORM_POSIX)
pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER;
#else
#error Lack of implementation: Mutex
#endif
}
/*!
* \class Nz::MemoryManager
* \brief Core class that represents a manager for the memory
*/
/*!
* \brief Constructs a MemoryManager object by default
*/
MemoryManager::MemoryManager()
{
}
/*!
* \brief Destructs a MemoryManager object and calls Unitialize
*/
MemoryManager::~MemoryManager()
{
Uninitialize();
}
/*!
* \brief Allocates memory
* \return Raw memory allocated
*
* \param size Size to allocate
* \parma multi Array or not
* \param file File of the allocation
* \param line Line of the allocation in the file
*/
void* MemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
{
if (!s_initialized)
@ -147,16 +172,37 @@ namespace Nz
return reinterpret_cast<UInt8*>(ptr) + sizeof(Block);
}
/*!
* \brief Enables the filling of the allocation
*
* \param allocationFilling If true, sets the rest of the allocation block to '0xFF'
*/
void MemoryManager::EnableAllocationFilling(bool allocationFilling)
{
s_allocationFilling = allocationFilling;
}
/*!
* \brief Enables the logging of the allocation
*
* \param logAllocations If true, registers every allocation
*/
void MemoryManager::EnableAllocationLogging(bool logAllocations)
{
s_allocationLogging = logAllocations;
}
/*!
* \brief Frees the pointer
*
* \param pointer Pointer to free
* \param multi Array or not
*
* \remark If pointer is nullptr, nothing is done
*/
void MemoryManager::Free(void* pointer, bool multi)
{
if (!pointer)
@ -227,37 +273,73 @@ namespace Nz
#endif
}
/*!
* \brief Gets the number of allocated blocks
* \return Number of allocated blocks
*/
unsigned int MemoryManager::GetAllocatedBlockCount()
{
return s_allocatedBlock;
}
/*!
* \brief Gets the allocated size
* \return Size of total allocation
*/
std::size_t MemoryManager::GetAllocatedSize()
{
return s_allocatedSize;
}
/*!
* \brief Gets the number of allocations
* \return Number of allocations
*/
unsigned int MemoryManager::GetAllocationCount()
{
return s_allocationCount;
}
/*!
* \brief Checks whether the filling of allocation is enabled
* \return true if it is filling
*/
bool MemoryManager::IsAllocationFillingEnabled()
{
return s_allocationFilling;
}
/*!
* \brief Checks whether the logging of allocation is enabled
* \return true if it is logging
*/
bool MemoryManager::IsAllocationLoggingEnabled()
{
return s_allocationLogging;
}
/*!
* \brief Sets the next free
*
* \param file Name of the file
* \param line Line in the file
*/
void MemoryManager::NextFree(const char* file, unsigned int line)
{
s_nextFreeFile = file;
s_nextFreeLine = line;
}
/*!
* \brief Initializes the MemoryManager
*/
void MemoryManager::Initialize()
{
char timeStr[23];
@ -282,12 +364,22 @@ namespace Nz
s_initialized = true;
}
/*!
* \brief Gets the time
*
* \param buffer Buffer to set the time in
*/
void MemoryManager::TimeInfo(char buffer[23])
{
time_t currentTime = std::time(nullptr);
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(&currentTime));
}
/*!
* \brief Uninitializes the MemoryManager
*/
void MemoryManager::Uninitialize()
{
#ifdef NAZARA_PLATFORM_WINDOWS
@ -334,5 +426,5 @@ namespace Nz
}
std::fclose(log);
}
}
}

View File

@ -10,33 +10,75 @@
namespace Nz
{
/*!
* \class Nz::MemoryStream
* \brief Core class that represents a stream of memory
*/
/*!
* \brief Clears the content of the stream
*/
void MemoryStream::Clear()
{
m_buffer->Clear();
m_pos = 0;
}
/*!
* \brief Checks whether the stream reached the end of the stream
* \return true if cursor is at the end of the stream
*/
bool MemoryStream::EndOfStream() const
{
return m_pos >= m_buffer->size();
}
/*!
* \brief Gets the position of the cursor
* \return Position of the cursor
*/
UInt64 MemoryStream::GetCursorPos() const
{
return m_pos;
}
/*!
* \brief Gets the size of the raw memory
* \return Size of the memory
*/
UInt64 MemoryStream::GetSize() const
{
return m_buffer->GetSize();
}
/*!
* \brief Sets the buffer for the memory stream
*
* \param byteArray Bytes to stream
* \param openMode Reading/writing mode for the stream
*
* \remark Produces a NazaraAssert if byteArray is nullptr
*/
void MemoryStream::SetBuffer(ByteArray* byteArray, UInt32 openMode)
{
NazaraAssert(byteArray, "Invalid ByteArray");
m_buffer = byteArray;
m_openMode = openMode;
}
/*!
* \brief Sets the position of the cursor
* \return true
*
* \param offset Offset according to the beginning of the stream
*/
bool MemoryStream::SetCursorPos(UInt64 offset)
{
m_pos = offset;
@ -44,11 +86,23 @@ namespace Nz
return true;
}
/*!
* \brief Flushes the stream
*/
void MemoryStream::FlushStream()
{
// Nothing to flush
}
/*!
* \brief Reads blocks
* \return Number of blocks read
*
* \param buffer Preallocated buffer to contain information read
* \param size Size of the read and thus of the buffer
*/
std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size)
{
if (EndOfStream())
@ -63,12 +117,24 @@ namespace Nz
return readSize;
}
/*!
* \brief Writes blocks
* \return Number of blocks 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
*/
std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size)
{
std::size_t endPos = static_cast<std::size_t>(m_pos + size);
if (endPos > m_buffer->GetSize())
m_buffer->Resize(endPos);
NazaraAssert(buffer, "Invalid buffer");
std::memcpy(m_buffer->GetBuffer() + m_pos, buffer, size);
m_pos = endPos;

View File

@ -9,6 +9,20 @@
namespace Nz
{
/*!
* \class Nz::MemoryView
* \brief Core class that represents a view of the memory behaving like a stream
*/
/*!
* \brief Constructs a MemoryView object with a raw memory and a size
*
* \param ptr Pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
MemoryView::MemoryView(void* ptr, UInt64 size) :
Stream(StreamOption_None, OpenMode_ReadWrite),
m_ptr(reinterpret_cast<UInt8*>(ptr)),
@ -17,6 +31,15 @@ namespace Nz
{
}
/*!
* \brief Constructs a MemoryView object with a raw memory and a size
*
* \param ptr Constant pointer to raw memory
* \param size Size that can be read
*
* \remark If preallocated space of ptr is less than the size, the behaviour is undefined
*/
MemoryView::MemoryView(const void* ptr, UInt64 size) :
Stream(StreamOption_None, OpenMode_ReadOnly),
m_ptr(reinterpret_cast<UInt8*>(const_cast<void*>(ptr))), //< Okay, right, const_cast is bad, but this pointer is still read-only
@ -25,21 +48,43 @@ namespace Nz
{
}
/*!
* \brief Checks whether the stream reached the end of the stream
* \return true if cursor is at the end of the stream
*/
bool MemoryView::EndOfStream() const
{
return m_pos >= m_size;
}
/*!
* \brief Gets the position of the cursor
* \return Position of the cursor
*/
UInt64 MemoryView::GetCursorPos() const
{
return m_pos;
}
/*!
* \brief Gets the size of the raw memory
* \return Size of the memory
*/
UInt64 MemoryView::GetSize() const
{
return m_size;
}
/*!
* \brief Sets the position of the cursor
* \return true
*
* \param offset Offset according to the beginning of the stream
*/
bool MemoryView::SetCursorPos(UInt64 offset)
{
m_pos = std::min(offset, m_size);
@ -47,11 +92,23 @@ namespace Nz
return true;
}
/*!
* \brief Flushes the stream
*/
void MemoryView::FlushStream()
{
// Nothing to do
}
/*!
* \brief Reads blocks
* \return Number of blocks read
*
* \param buffer Preallocated buffer to contain information read
* \param size Size of the read and thus of the buffer
*/
std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size)
{
std::size_t readSize = std::min<std::size_t>(size, static_cast<std::size_t>(m_size - m_pos));
@ -63,12 +120,24 @@ namespace Nz
return readSize;
}
/*!
* \brief Writes blocks
* \return Number of blocks 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
*/
std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size)
{
std::size_t endPos = static_cast<std::size_t>(m_pos + size);
if (endPos > m_size)
size = m_size - m_pos;
NazaraAssert(buffer, "Invalid buffer");
std::memcpy(&m_ptr[m_pos], buffer, size);
m_pos += size;

View File

@ -16,26 +16,58 @@
namespace Nz
{
/*!
* \class Nz::Mutex
* \brief Core class that represents a binary semaphore, a mutex
*
* \remark The mutex is recursive, it means that a thread who owns the mutex can call the same function which needs the same mutex
*/
/*!
* \brief Constructs a Mutex object by default
*/
Mutex::Mutex()
{
m_impl = new MutexImpl;
}
/*!
* \brief Destructs the object
*/
Mutex::~Mutex()
{
delete m_impl;
}
/*!
* \brief Locks the mutex
*
* If another thread has already locked the mutex, a call to lock will block execution until the lock is acquired. A thread may call lock on a recursive mutex repeatedly. Ownership will only be released after the thread makes a matching number of calls to unlock
*/
void Mutex::Lock()
{
m_impl->Lock();
}
/*!
* \brief Tries to lock the mutex
* \return true if the lock was acquired successfully
*/
bool Mutex::TryLock()
{
return m_impl->TryLock();
}
/*!
* \brief Unlocks the mutex
*
* Unlocks the mutex if its level of ownership is 1 (there was exactly one more call to Lock() than there were calls to Unlock() made by this thread), reduces the level of ownership by 1 otherwise
*/
void Mutex::Unlock()
{
m_impl->Unlock();

View File

@ -12,16 +12,33 @@
namespace Nz
{
/*!
* \class Nz::ParameterList
* \brief Core class that represents a list of parameters
*/
/*!
* \brief Constructs a ParameterList object by copy
*/
ParameterList::ParameterList(const ParameterList& list)
{
operator=(list);
}
/*!
* \brief Destructs the object and clears
*/
ParameterList::~ParameterList()
{
Clear();
}
/*!
* \brief Clears the list of parameters
*/
void ParameterList::Clear()
{
for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it)
@ -30,8 +47,22 @@ namespace Nz
m_parameters.clear();
}
/*!
* \brief Gets the boolean parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetBooleanParameter(const String& name, bool* value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -50,16 +81,16 @@ namespace Nz
return true;
case ParameterType_String:
{
bool converted;
if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive))
{
*value = converted;
return true;
}
bool converted;
if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive))
{
*value = converted;
return true;
}
break;
}
break;
}
case ParameterType_Float:
case ParameterType_None:
@ -72,8 +103,22 @@ namespace Nz
return false;
}
/*!
* \brief Gets the float parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetFloatParameter(const String& name, float* value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -92,16 +137,16 @@ namespace Nz
return true;
case ParameterType_String:
{
double converted;
if (it->second.value.stringVal.ToDouble(&converted))
{
*value = static_cast<float>(converted);
return true;
}
double converted;
if (it->second.value.stringVal.ToDouble(&converted))
{
*value = static_cast<float>(converted);
return true;
}
break;
}
break;
}
case ParameterType_Boolean:
case ParameterType_None:
@ -114,8 +159,22 @@ namespace Nz
return false;
}
/*!
* \brief Gets the integer parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetIntegerParameter(const String& name, int* value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -138,18 +197,18 @@ namespace Nz
return false;
case ParameterType_String:
{
long long converted;
if (it->second.value.stringVal.ToInteger(&converted))
{
if (converted <= std::numeric_limits<int>::max() && converted >= std::numeric_limits<int>::min())
long long converted;
if (it->second.value.stringVal.ToInteger(&converted))
{
*value = static_cast<int>(converted);
return true;
if (converted <= std::numeric_limits<int>::max() && converted >= std::numeric_limits<int>::min())
{
*value = static_cast<int>(converted);
return true;
}
}
break;
}
break;
}
case ParameterType_None:
case ParameterType_Pointer:
@ -161,8 +220,22 @@ namespace Nz
return false;
}
/*!
* \brief Gets the parameter by name
* \return true if success
*
* \param name Name of the variable
* \param type Type to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetParameterType(const String& name, ParameterType* type) const
{
NazaraAssert(type, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
return false;
@ -172,8 +245,22 @@ namespace Nz
return true;
}
/*!
* \brief Gets the pointer parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetPointerParameter(const String& name, void** value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -203,8 +290,22 @@ namespace Nz
return false;
}
/*!
* \brief Gets the string parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetStringParameter(const String& name, String* value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -247,8 +348,22 @@ namespace Nz
return false;
}
/*!
* \brief Gets the user parameter by name
* \return true if success
*
* \param name Name of the variable
* \param value Value to set
*
* \remark Produces a NazaraAssert if pointer is invalid
* \remark Produces a NazaraError if name is not a variable
* \remark Produces a NazaraError if value could not be convertible
*/
bool ParameterList::GetUserdataParameter(const String& name, void** value) const
{
NazaraAssert(value, "Invalid pointer");
auto it = m_parameters.find(name);
if (it == m_parameters.end())
{
@ -268,11 +383,26 @@ namespace Nz
}
}
/*!
* \brief Checks whether the parameter list has a parameter with that name
* \return true if found
*
* \param name Name of the parameter
*/
bool ParameterList::HasParameter(const String& name) const
{
return m_parameters.find(name) != m_parameters.end();
}
/*!
* \brief Removes the parameter with that name
*
* Removes the parameter with that name, if not found, nothing is done
*
* \param name Name of the parameter
*/
void ParameterList::RemoveParameter(const String& name)
{
auto it = m_parameters.find(name);
@ -283,6 +413,12 @@ namespace Nz
}
}
/*!
* \brief Sets the parameter with the name to ParameterType_None
*
* \param name Name of the parameter
*/
void ParameterList::SetParameter(const String& name)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -294,6 +430,13 @@ namespace Nz
parameter.type = ParameterType_None;
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, const String& value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -307,6 +450,13 @@ namespace Nz
PlacementNew<String>(&parameter.value.stringVal, value);
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, const char* value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -320,6 +470,13 @@ namespace Nz
PlacementNew<String>(&parameter.value.stringVal, value);
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, void* value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -332,6 +489,14 @@ namespace Nz
parameter.value.ptrVal = value;
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
* \param destructor Destructor for dynamic variable
*/
void ParameterList::SetParameter(const String& name, void* value, Destructor destructor)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -344,6 +509,13 @@ namespace Nz
parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value);
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, bool value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -356,6 +528,13 @@ namespace Nz
parameter.value.boolVal = value;
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, float value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -368,6 +547,13 @@ namespace Nz
parameter.value.floatVal = value;
}
/*!
* \brief Sets the parameter with the name to the value
*
* \param name Name of the parameter
* \param value Value of the parameter
*/
void ParameterList::SetParameter(const String& name, int value)
{
std::pair<ParameterMap::iterator, bool> pair = m_parameters.insert(std::make_pair(name, Parameter()));
@ -380,6 +566,13 @@ namespace Nz
parameter.value.intVal = value;
}
/*!
* \brief Assigns the content of the other parameter list to this
* \return A reference to this
*
* \param list List to assign
*/
ParameterList& ParameterList::operator=(const ParameterList& list)
{
Clear();
@ -418,6 +611,12 @@ namespace Nz
return *this;
}
/*!
* \brief Destroys the value for the parameter
*
* \param parameter Parameter to destroy
*/
void ParameterList::DestroyValue(Parameter& parameter)
{
switch (parameter.type)
@ -427,15 +626,15 @@ namespace Nz
break;
case ParameterType_Userdata:
{
Parameter::UserdataValue* userdata = parameter.value.userdataVal;
if (--userdata->counter == 0)
{
userdata->destructor(userdata->ptr);
delete userdata;
Parameter::UserdataValue* userdata = parameter.value.userdataVal;
if (--userdata->counter == 0)
{
userdata->destructor(userdata->ptr);
delete userdata;
}
break;
}
break;
}
case ParameterType_Boolean:
case ParameterType_Float:

View File

@ -24,6 +24,19 @@ namespace Nz
};
}
/*!
* \class Nz::PluginManager
* \brief Core class that represents a manager for plugin
*/
/*!
* \brief Adds a directory
*
* \param directoryPath Path to the directory
*
* \remark Produces a NazaraError if not initialized
*/
void PluginManager::AddDirectory(const String& directoryPath)
{
if (!Initialize())
@ -35,6 +48,11 @@ namespace Nz
s_directories.insert(File::AbsolutePath(directoryPath));
}
/*!
* \brief Initializes the plugin manager
* \return true if everything is ok
*/
bool PluginManager::Initialize()
{
if (s_initialized)
@ -48,11 +66,36 @@ namespace Nz
return true;
}
/*!
* \brief Mounts the plugin
* \return true if mounting was a success
*
* \remark Produces a NazaraError if not initialized
* \remark Produces a NazaraError if plugin is not found
* \remark Produces a NazaraError if fail to load plugin
* \remark Produces a NazaraError if fail to get symbol PluginLoad
* \remark Produces a NazaraError if fail to initialize the plugin with PluginLoad
*/
bool PluginManager::Mount(Plugin plugin)
{
return Mount(s_pluginFiles[plugin]);
}
/*!
* \brief Mounts the plugin with a path
* \return true if mounting was a success
*
* \param pluginPath Path to the plugin
* \param appendExtension Adds the extension to the path or not
*
* \remark Produces a NazaraError if not initialized
* \remark Produces a NazaraError if plugin is not found
* \remark Produces a NazaraError if fail to load plugin
* \remark Produces a NazaraError if fail to get symbol PluginLoad
* \remark Produces a NazaraError if fail to initialize the plugin with PluginLoad
*/
bool PluginManager::Mount(const String& pluginPath, bool appendExtension)
{
if (!Initialize())
@ -119,6 +162,14 @@ namespace Nz
return true;
}
/*!
* \brief Removes a directory
*
* \param directoryPath Path to the directory
*
* \remark Produces a NazaraError if not initialized
*/
void PluginManager::RemoveDirectory(const String& directoryPath)
{
if (!Initialize())
@ -130,11 +181,29 @@ namespace Nz
s_directories.erase(File::AbsolutePath(directoryPath));
}
/*!
* \brief Unmounts the plugin with a path
*
* \param pluginPath Path to the plugin
*
* \remark Produces a NazaraError if not initialized
* \remark Produces a NazaraError if plugin is not loaded
*/
void PluginManager::Unmount(Plugin plugin)
{
Unmount(s_pluginFiles[plugin]);
}
/*!
* \brief Unmounts the plugin with a path
*
* \param pluginPath Path to the plugin
*
* \remark Produces a NazaraError if not initialized
* \remark Produces a NazaraError if plugin is not loaded
*/
void PluginManager::Unmount(const String& pluginPath)
{
if (!Initialize())
@ -160,6 +229,10 @@ namespace Nz
s_plugins.erase(it);
}
/*!
* \brief Uninitializes the plugin manager
*/
void PluginManager::Uninitialize()
{
if (!s_initialized)

View File

@ -18,8 +18,8 @@ namespace Nz
void FileImpl::Close()
{
if (m_fileDescriptor != -1)
close(m_fileDescriptor);
if (m_fileDescriptor != -1)
close(m_fileDescriptor);
}
bool FileImpl::EndOfFile() const
@ -69,9 +69,9 @@ namespace Nz
if (mode & OpenMode_Truncate)
flags |= O_TRUNC;
///TODO: lock
// if ((mode & OpenMode_Lock) == 0)
// shareMode |= FILE_SHARE_WRITE;
///TODO: lock
//if ((mode & OpenMode_Lock) == 0)
// shareMode |= FILE_SHARE_WRITE;
m_fileDescriptor = open64(filePath.GetConstBuffer(), flags, permissions);
return m_fileDescriptor != -1;

View File

@ -13,7 +13,7 @@ namespace Nz
{
SemaphoreImpl::SemaphoreImpl(unsigned int count)
{
if(sem_init(&m_semaphore, 0, count) != 0)
if (sem_init(&m_semaphore, 0, count) != 0)
NazaraError("Failed to create semaphore: " + Error::GetLastSystemError());
}
@ -68,7 +68,7 @@ namespace Nz
return true;
#else
return sem_timedwait(&m_semaphore, &ti) != 0;
return sem_timedwait(&m_semaphore, &ti) != 0;
#endif
}
}

View File

@ -8,71 +8,199 @@
namespace Nz
{
/*!
* \class Nz::PrimitiveList
* \brief Core class that represents a list of geometric primitives
*/
/*!
* \brief Adds a box centered
*
* \param lengths (Width, Height, Depht)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
*/
void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::Box(lengths, subdivision, transformMatrix));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::Box(lengths, subdivision, position, rotation));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::Cone(length, radius, subdivision, transformMatrix));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::Cone(length, radius, subdivision, position, rotation));
}
/*!
* \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 transformMatrix Matrix to apply
*/
void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::CubicSphere(size, subdivision, transformMatrix));
}
/*!
* \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
*/
void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::CubicSphere(size, subdivision, position, rotation));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, transformMatrix));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, position, rotation));
}
/*!
* \brief Adds a plane, centered in (0, 0, 0)
*
* \param size (Width, Depth)
* \param subdivision Number of subdivision for the axis
* \param transformMatrix Matrix to apply
*/
void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::Plane(size, subdivision, transformMatrix));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo)
{
m_primitives.push_back(Primitive::Plane(size, subdivision, planeInfo));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::Plane(size, subdivision, position, rotation));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix)
{
m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, transformMatrix));
}
/*!
* \brief Adds 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
*/
void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation)
{
m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, position, rotation));
}
/*!
* \brief Gets the ith primitive
* \return A reference to the ith primitive
*
* \param i Index of the primitive
*
* \remark Produces a NazaraAssert if index is greather than the size
*/
Primitive& PrimitiveList::GetPrimitive(std::size_t i)
{
NazaraAssert(i < m_primitives.size(), "Primitive index out of range");
@ -80,6 +208,15 @@ namespace Nz
return m_primitives[i];
}
/*!
* \brief Gets the ith primitive
* \return A constant reference to the ith primitive
*
* \param i Index of the primitive
*
* \remark Produces a NazaraAssert if index is greather than the size
*/
const Primitive& PrimitiveList::GetPrimitive(std::size_t i) const
{
NazaraAssert(i < m_primitives.size(), "Primitive index out of range");
@ -87,16 +224,39 @@ namespace Nz
return m_primitives[i];
}
/*!
* \brief Gets the number of primitives
* \return Number of primitives
*/
std::size_t PrimitiveList::GetSize() const
{
return m_primitives.size();
}
/*!
* \brief Gets the ith primitive
* \return A reference to the ith primitive
*
* \param i Index of the primitive
*
* \remark Produces a NazaraAssert if index is greather than the size
*/
Primitive& PrimitiveList::operator()(unsigned int i)
{
return GetPrimitive(i);
}
/*!
* \brief Gets the ith primitive
* \return A constant reference to the ith primitive
*
* \param i Index of the primitive
*
* \remark Produces a NazaraAssert if index is greather than the size
*/
const Primitive& PrimitiveList::operator()(unsigned int i) const
{
return GetPrimitive(i);

View File

@ -16,12 +16,29 @@
namespace Nz
{
/*!
* \class Nz::RefCounted
* \brief Core class that represents a reference with a counter
*/
/*!
* \brief Constructs a RefCounted object with a persistance aspect
*
* \param persistent if false, object is destroyed when no more referenced
*/
RefCounted::RefCounted(bool persistent) :
m_persistent(persistent),
m_referenceCount(0)
{
}
/*!
* \brief Destructs the object
*
* \remark Produces a NazaraWarning if still referenced with NAZARA_CORE_SAFE defined
*/
RefCounted::~RefCounted()
{
#if NAZARA_CORE_SAFE
@ -30,21 +47,42 @@ namespace Nz
#endif
}
/*!
* \brief Adds a reference to the object
*/
void RefCounted::AddReference() const
{
m_referenceCount++;
}
/*!
* \brief Gets the number of references to the object
* \return Number of references
*/
unsigned int RefCounted::GetReferenceCount() const
{
return m_referenceCount;
}
/*!
* \brief Checks whether the object is persistent
* \return true if object is not destroyed when no more referenced
*/
bool RefCounted::IsPersistent() const
{
return m_persistent;
}
/*!
* \brief Removes a reference to the object
* \return true if object is deleted because no more referenced
*
* \remark Produces a NazaraError if counter is already 0 with NAZARA_CORE_SAFE defined
*/
bool RefCounted::RemoveReference() const
{
#if NAZARA_CORE_SAFE
@ -65,6 +103,14 @@ namespace Nz
return false;
}
/*!
* \brief Sets the persistence of the object
* \return true if object is deleted because no more referenced
*
* \param persistent Sets the persistence of the object
* \param checkReferenceCount Checks if the object should be destroyed if true
*/
bool RefCounted::SetPersistent(bool persistent, bool checkReferenceCount)
{
m_persistent = persistent;

View File

@ -7,13 +7,29 @@
namespace Nz
{
/*!
* \class Nz::Resource
* \brief Core class that represents a resource
*/
Resource::~Resource() = default;
/*!
* \brief Gets the file path associated with the resource
* \return A reference to the path
*/
const String& Resource::GetFilePath() const
{
return m_filePath;
}
/*!
* \brief Sets the file path associated with the resource
*
* \param filePath Path to the resource
*/
void Resource::SetFilePath(const String& filePath)
{
m_filePath = filePath;

View File

@ -16,31 +16,68 @@
namespace Nz
{
/*!
* \class Nz::Semaphore
* \brief Core class that represents a counting semaphore
*/
/*!
* \brief Constructs a semaphore object with a count
*/
Semaphore::Semaphore(unsigned int count)
{
m_impl = new SemaphoreImpl(count);
}
/*!
* \brief Destructs the object
*/
Semaphore::~Semaphore()
{
delete m_impl;
}
/*!
* \brief Gets the number of count that can handle the semaphore
* \return Number of count associated with the semaphore
*/
unsigned int Semaphore::GetCount() const
{
return m_impl->GetCount();
}
/*!
* \brief Increments the count of the semaphore and wait if count equals zero
*
* Increments the value of semaphore variable by 1. After the increment, if the pre-increment value was negative (meaning there are processes waiting for a resource), it transfers a blocked process from the semaphore's waiting queue to the ready queue
*/
void Semaphore::Post()
{
m_impl->Post();
}
/*!
* \brief Decrements the count of the semaphore and wait if count equals zero
*
* If the value of semaphore variable is not negative, decrements it by 1. If the semaphore variable is now negative, the process executing Wait is blocked (i.e., added to the semaphore's queue) until the value is greater or equal to 1. Otherwise, the process continues execution, having used a unit of the resource
*/
void Semaphore::Wait()
{
m_impl->Wait();
}
/*!
* \brief Decrements the count of the semaphore and wait if count equals zero
* \return true if the semaphore successfully decrements before timeout
*
* If the value of semaphore variable is not negative, decrements it by 1. If the semaphore variable is now negative, the process executing Wait is blocked (i.e., added to the semaphore's queue) until the value is greater or equal to 1. Otherwise, the process continues execution, having used a unit of the resource
*/
bool Semaphore::Wait(UInt32 timeout)
{
return m_impl->Wait(timeout);

View File

@ -13,8 +13,8 @@ namespace Nz
const char* errorType[] = {
"Assert failed", // ErrorType_AssertFailed
"Internal error", // ErrorType_Internal
"Error", // ErrorType_Normal
"Warning" // ErrorType_Warning
"Error", // ErrorType_Normal
"Warning" // ErrorType_Warning
};
static_assert(sizeof(errorType) / sizeof(const char*) == ErrorType_Max + 1, "Error type array is incomplete");
@ -22,15 +22,17 @@ namespace Nz
/*!
* \class Nz::StdLogger
* \brief Logger writing to standard output (stdout, stderr)
* \brief Core class that represents a logger writing to standard output (stdout, stderr)
*/
StdLogger::~StdLogger() = default;
/*!
* \brief Enable replication to standard output
* \brief Enables replication to standard output
*
* Does nothing, as the std logger always write to standard output
*
* \param enable Unused argument
*/
void StdLogger::EnableStdReplication(bool enable)
@ -40,9 +42,8 @@ namespace Nz
}
/*!
* \brief Get the standard output replication status
*
* Always returns true
* \brief Gets the standard output replication status
* \return Always returns true
*/
bool StdLogger::IsStdReplicationEnabled()
@ -51,7 +52,8 @@ namespace Nz
}
/*!
* Write to the console
* \brief Writes to the console
*
* \param string The log to write to the console
*
* \see WriteError
@ -64,7 +66,8 @@ namespace Nz
}
/*!
* Write an error to the console
* \brief Writes an error to the console
*
* \param type The error type
* \param error The error text
* \param line The line the error occurred

View File

@ -11,22 +11,50 @@
namespace Nz
{
/*!
* \class Nz::Stream
* \brief Core class that represents a stream
*/
/*!
* \brief Destructs the object
*/
Stream::~Stream() = default;
/*!
* \brief Gets the directory of the stream
* \return Empty string (meant to be virtual)
*/
String Stream::GetDirectory() const
{
return String();
}
/*!
* \brief Gets the path of the stream
* \return Empty string (meant to be virtual)
*/
String Stream::GetPath() const
{
return String();
}
/*!
* \brief Reads characters in the stream
* \return Line containing characters
*
* \param lineSize Number of characters to read, if lineSize is 0, read as much as possible
*
* \remark Produces a NazaraWarning if cursor position could not be reset
*/
String Stream::ReadLine(unsigned int lineSize)
{
String line;
if (lineSize == 0) // Taille maximale indéterminée
if (lineSize == 0) // Maximal size undefined
{
const unsigned int bufferSize = 64;
@ -63,7 +91,7 @@ namespace Nz
line.Set(lineSize, '\0');
std::size_t readSize = Read(&line[0], lineSize);
std::size_t pos = line.Find('\n');
if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier)
if (pos <= readSize) // False only if the character is not available (npos being the biggest integer)
{
if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos - 1] == '\r')
line.Resize(pos);
@ -80,12 +108,26 @@ namespace Nz
return line;
}
/*!
* \brief Writes a ByteArray into the stream
* \return true if successful
*
* \param byteArray Bytes to write
*/
bool Stream::Write(const ByteArray& byteArray)
{
ByteArray::size_type size = byteArray.GetSize();
return Write(byteArray.GetConstBuffer(), size) == size;
}
/*!
* \brief Writes a String into the stream
* \return true if successful
*
* \param string String to write
*/
bool Stream::Write(const String& string)
{
String temp(string);

File diff suppressed because it is too large Load Diff

View File

@ -7,17 +7,37 @@
namespace Nz
{
/*!
* \class Nz::StringStream
* \brief Core class that represents a stream of strings
*/
/*!
* \brief Constructs a StringStream object by default
*/
StringStream::StringStream() :
m_bufferSize(0)
{
}
/*!
* \brief Constructs a StringStream object with a string
*
* \param str First value of the stream
*/
StringStream::StringStream(const String& str) :
m_bufferSize(str.GetSize())
{
m_strings.push_back(str);
}
/*!
* \brief Gives a string representation
* \return A string representation of the object where every objects of the stream has been converted with Nz::String
*/
String StringStream::ToString() const
{
String string;
@ -29,6 +49,13 @@ namespace Nz
return string;
}
/*!
* \brief Adds the representation of the boolean
* \return A reference to this
*
* \param boolean Boolean value
*/
StringStream& StringStream::operator<<(bool boolean)
{
m_strings.push_back(String::Boolean(boolean));
@ -37,6 +64,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the short
* \return A reference to this
*
* \param number Short value
*/
StringStream& StringStream::operator<<(short number)
{
m_strings.push_back(String::Number(number));
@ -45,6 +79,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the unsigned short
* \return A reference to this
*
* \param number Short value
*/
StringStream& StringStream::operator<<(unsigned short number)
{
m_strings.push_back(String::Number(number));
@ -53,6 +94,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the int
* \return A reference to this
*
* \param number Int value
*/
StringStream& StringStream::operator<<(int number)
{
m_strings.push_back(String::Number(number));
@ -61,6 +109,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the unsigned int
* \return A reference to this
*
* \param number Int value
*/
StringStream& StringStream::operator<<(unsigned int number)
{
m_strings.push_back(String::Number(number));
@ -69,6 +124,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the long
* \return A reference to this
*
* \param number Long value
*/
StringStream& StringStream::operator<<(long number)
{
m_strings.push_back(String::Number(number));
@ -77,6 +139,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the unsigned long
* \return A reference to this
*
* \param number Long value
*/
StringStream& StringStream::operator<<(unsigned long number)
{
m_strings.push_back(String::Number(number));
@ -85,6 +154,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the long long
* \return A reference to this
*
* \param number Long long value
*/
StringStream& StringStream::operator<<(long long number)
{
m_strings.push_back(String::Number(number));
@ -93,6 +169,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the unsigned long long
* \return A reference to this
*
* \param number Long long value
*/
StringStream& StringStream::operator<<(unsigned long long number)
{
m_strings.push_back(String::Number(number));
@ -101,6 +184,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the float
* \return A reference to this
*
* \param number Float value
*/
StringStream& StringStream::operator<<(float number)
{
m_strings.push_back(String::Number(number));
@ -109,6 +199,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the double
* \return A reference to this
*
* \param number Double value
*/
StringStream& StringStream::operator<<(double number)
{
m_strings.push_back(String::Number(number));
@ -117,6 +214,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the long double
* \return A reference to this
*
* \param number Long double value
*/
StringStream& StringStream::operator<<(long double number)
{
m_strings.push_back(String::Number(number));
@ -125,6 +229,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the char
* \return A reference to this
*
* \param character Char value
*/
StringStream& StringStream::operator<<(char character)
{
m_strings.push_back(String(character));
@ -133,6 +244,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the unsigned char
* \return A reference to this
*
* \param character Char value
*/
StringStream& StringStream::operator<<(unsigned char character)
{
m_strings.push_back(String(static_cast<char>(character)));
@ -141,6 +259,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the const char*
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const char* string)
{
m_strings.push_back(string);
@ -149,6 +274,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the std::string
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const std::string& string)
{
m_strings.push_back(string);
@ -157,6 +289,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the Nz::String
* \return A reference to this
*
* \param string String value
*/
StringStream& StringStream::operator<<(const String& string)
{
m_strings.push_back(string);
@ -165,6 +304,13 @@ namespace Nz
return *this;
}
/*!
* \brief Adds the representation of the pointer
* \return A reference to this
*
* \param ptr Pointer value
*/
StringStream& StringStream::operator<<(const void* ptr)
{
m_strings.push_back(String::Pointer(ptr));
@ -173,6 +319,11 @@ namespace Nz
return *this;
}
/*!
* \brief Converts this to Nz::String
* \return The string representation of the stream
*/
StringStream::operator String() const
{
return ToString();

View File

@ -24,16 +24,39 @@ namespace Nz
unsigned int s_workerCount = 0;
}
/*!
* \class Nz::TaskScheduler<T>
* \brief Core class that represents a pool of threads
*
* \remark Initialized should be called first
*/
/*!
* \brief Gets the number of threads
* \return Number of threads, if none, the number of simulatenous threads on the processor is returned
*/
unsigned int TaskScheduler::GetWorkerCount()
{
return (s_workerCount > 0) ? s_workerCount : HardwareInfo::GetProcessorCount();
}
/*!
* \brief Initializes the TaskScheduler class
* \return true if everything is ok
*/
bool TaskScheduler::Initialize()
{
return TaskSchedulerImpl::Initialize(GetWorkerCount());
}
/*!
* \brief Runs the pending works
*
* \remark Produce a NazaraError if the class is not initialized
*/
void TaskScheduler::Run()
{
if (!Initialize())
@ -49,6 +72,14 @@ namespace Nz
}
}
/*!
* \brief Sets the number of workers
*
* \param workerCount Number of simulatnous threads handling the tasks
*
* \remark Produce a NazaraError if the class is not initialized and NAZARA_CORE_SAFE is defined
*/
void TaskScheduler::SetWorkerCount(unsigned int workerCount)
{
#ifdef NAZARA_CORE_SAFE
@ -62,12 +93,22 @@ namespace Nz
s_workerCount = workerCount;
}
/*!
* \brief Uninitializes the TaskScheduler class
*/
void TaskScheduler::Uninitialize()
{
if (TaskSchedulerImpl::IsInitialized())
TaskSchedulerImpl::Uninitialize();
}
/*!
* \brief Waits for tasks to be done
*
* \remark Produce a NazaraError if the class is not initialized
*/
void TaskScheduler::WaitForTasks()
{
if (!Initialize())
@ -79,6 +120,15 @@ namespace Nz
TaskSchedulerImpl::WaitForTasks();
}
/*!
* \brief Adds a task on the pending list
*
* \param taskFunctor Functor represeting a task to be done
*
* \remark Produce a NazaraError if the class is not initialized
* \remark A task containing a call on this class is undefined behaviour
*/
void TaskScheduler::AddTaskFunctor(Functor* taskFunctor)
{
if (!Initialize())

View File

@ -21,17 +21,36 @@
namespace Nz
{
/*!
* \class Nz::Thread<T>
* \brief Core class that represents a thread
*/
/*!
* \brief Constructs a Thread<T> object by default
*/
Thread::Thread() :
m_impl(nullptr)
{
}
/*!
* \brief Constructs a Thread<T> object by move semantic
*
* \param other Thread to move into this
*/
Thread::Thread(Thread&& other) noexcept :
m_impl(other.m_impl)
{
other.m_impl = nullptr;
}
/*!
* \brief Waits that the thread ends and then destroys this
*/
Thread::~Thread()
{
if (m_impl)
@ -42,6 +61,10 @@ namespace Nz
}
}
/*!
* \brief Detaches the thread
*/
void Thread::Detach()
{
if (m_impl)
@ -52,16 +75,32 @@ namespace Nz
}
}
/*!
* \brief Gets the id of the thread
* \return The identifiant of the thread (PID)
*/
Thread::Id Thread::GetId() const
{
return Thread::Id(m_impl);
}
/*!
* \brief Checks whether the thread can be joined
* \return true if well formed and not detached
*/
bool Thread::IsJoinable() const
{
return m_impl != nullptr;
}
/*!
* \brief Waits that the thread ends
*
* \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined
*/
void Thread::Join()
{
#if NAZARA_CORE_SAFE
@ -77,6 +116,16 @@ namespace Nz
m_impl = nullptr;
}
/*!
* \brief Moves the other thread into this
* \return A reference to this
*
* \param thread Thread to move in this
*
* \remark Produce a NazaraError if no functor was assigned and NAZARA_CORE_SAFE is defined
* \remark And call std::terminate if no functor was assigned and NAZARA_CORE_SAFE is defined
*/
Thread& Thread::operator=(Thread&& thread)
{
#if NAZARA_CORE_SAFE
@ -91,16 +140,33 @@ namespace Nz
return *this;
}
/*!
* \brief Gets the number of simulatenous threads that can run on the same cpu
* \return The number of simulatenous threads
*/
unsigned int Thread::HardwareConcurrency()
{
return HardwareInfo::GetProcessorCount();
}
/*!
* \brief Makes sleep this thread
*
* \param milliseconds The number of milliseconds to sleep
*/
void Thread::Sleep(UInt32 milliseconds)
{
ThreadImpl::Sleep(milliseconds);
}
/*!
* \brief Creates the implementation of this thread
*
* \param functor The task the thread will represent
*/
void Thread::CreateImpl(Functor* functor)
{
m_impl = new ThreadImpl(functor);
@ -108,41 +174,103 @@ namespace Nz
/*********************************Thread::Id********************************/
/*!
* \brief Constructs a Thread<T> object with a thread implementation
*
* \param thread Thread implementation assigned to the thread
*/
Thread::Id::Id(ThreadImpl* thread) :
m_id(thread)
{
}
/*!
* \brief Compares two Thread::Id
* \return true if the two thread ids are the same
*
* \param lhs First id
* \param rhs Second id
*/
bool operator==(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id == rhs.m_id;
}
/*!
* \brief Compares two Thread::Id
* \return false if the two thread ids are the same
*
* \param lhs First id
* \param rhs Second id
*/
bool operator!=(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id != rhs.m_id;
}
/*!
* \brief Compares two Thread::Id
* \return true if the first thread id is inferior to the second one
*
* \param lhs First id
* \param rhs Second id
*/
bool operator<(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id < rhs.m_id;
}
/*!
* \brief Compares two Thread::Id
* \return true if the first thread id is inferior or equal to the second one
*
* \param lhs First id
* \param rhs Second id
*/
bool operator<=(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id <= rhs.m_id;
}
/*!
* \brief Compares two Thread::Id
* \return true if the first thread id is superior to the second one
*
* \param lhs First id
* \param rhs Second id
*/
bool operator>(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id > rhs.m_id;
}
/*!
* \brief Compares two Thread::Id
* \return true if the first thread id is superior or equal to the second one
*
* \param lhs First id
* \param rhs Second id
*/
bool operator>=(const Thread::Id& lhs, const Thread::Id& rhs)
{
return lhs.m_id >= rhs.m_id;
}
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param id The thread id to output
*/
std::ostream& operator<<(std::ostream& o, const Nz::Thread::Id& id)
{
o << id.m_id;

View File

@ -11,20 +11,32 @@ namespace Nz
{
struct Character
{
UInt16 category; // Le type du caractère
UInt8 direction; // Le sens de lecure du caractère
UInt32 lowerCase; // Le caractère correspondant en minuscule
UInt32 titleCase; // Le caractère correspondant en titre
UInt32 upperCase; // Le caractère correspondant en majuscule
UInt16 category; // The type of the character
UInt8 direction; // The reading way of the character
UInt32 lowerCase; // The corresponding lower character
UInt32 titleCase; // The corresponding title character
UInt32 upperCase; // The corresponding upper character
};
}
#include <Nazara/Core/UnicodeData.hpp>
#else // Implémentation supportant la table ASCII
#else // Implementation handling ASCII table
namespace Nz
{
/*!
* \class Nz::Unicode
* \brief Core class that represents a Unicode character
*/
/*!
* \brief Gets the category of the character
* \return Unicode category
*
* \param character Character to get assignated category
*/
Unicode::Category Unicode::GetCategory(char32_t character)
{
switch (character)
@ -188,6 +200,13 @@ namespace Nz
return Category_NoCategory;
}
/*!
* \brief Gets the direction of reading of the character
* \return Unicode direction
*
* \param character Character to get assignated direction
*/
Unicode::Direction Unicode::GetDirection(char32_t character)
{
switch (character)
@ -347,6 +366,15 @@ namespace Nz
return Direction_Boundary_Neutral;
}
/*!
* \brief Gets the lower case of the character
* \return Unicode lower
*
* \param character Character to get assignated lower case
*
* \remark Only handling ASCII
*/
char32_t Unicode::GetLowercase(char32_t character)
{
if (character >= 'A' && character <= 'Z')
@ -355,11 +383,29 @@ namespace Nz
return character;
}
/*!
* \brief Gets the title case of the character
* \return Unicode title
*
* \param character Character to get assignated title case
*
* \remark Only handling ASCII
*/
char32_t Unicode::GetTitlecase(char32_t character)
{
return GetUppercase(character);
}
/*!
* \brief Gets the upper case of the character
* \return Unicode upper
*
* \param character Character to get assignated upper case
*
* \remark Only handling ASCII
*/
char32_t Unicode::GetUppercase(char32_t character)
{
if (character >= 'a' && character <= 'z')

View File

@ -136,7 +136,6 @@ namespace Nz
OpenEWMHConnection(sharedConnection);
}
NazaraNotice("Initialized: Display module");
return true;
}
@ -208,8 +207,6 @@ namespace Nz
xcb_disconnect(sharedConnection);
}
NazaraNotice("Uninitialized: Display module");
}
xcb_window_t X11::XCBDefaultRootWindow(xcb_connection_t* connection)

View File

@ -0,0 +1,27 @@
#include <Nazara/Core/AbstractHash.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Core/ByteArray.hpp>
#include <array>
SCENARIO("AbstractHash", "[CORE][ABSTRACTHASH]")
{
GIVEN("The hash SHA512")
{
std::unique_ptr<Nz::AbstractHash> SHA512 = Nz::AbstractHash::Get(Nz::HashType_SHA512);
SHA512->Begin();
WHEN("We introduce data")
{
std::array<Nz::UInt8, 4> array{ 0, 1, 2, 3 };
SHA512->Append(array.begin(), array.size());
THEN("We ask for the bytearray")
{
Nz::ByteArray byteArray = SHA512->End();
REQUIRE(byteArray.GetSize() == SHA512->GetDigestLength());
}
}
}
}

View File

@ -0,0 +1,40 @@
#include <Nazara/Core/Algorithm.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <array>
TEST_CASE("Apply", "[CORE][ALGORITHM]")
{
SECTION("Apply lambda to two vector2")
{
Nz::Vector2<int> vector = Nz::Vector2<int>::Unit();
auto lambda = [](const Nz::Vector2<int>& vec1, const Nz::Vector2<int>& vec2)
{
return vec1 + vec2;
};
Nz::Vector2<int> result = Nz::Apply(lambda, std::make_tuple(vector, vector));
REQUIRE(result == (Nz::Vector2<int>::Unit() * 2));
}
SECTION("Apply member function to vector2")
{
Nz::Vector2<int> vector = Nz::Vector2<int>::Unit();
int result = Nz::Apply(vector, &Nz::Vector2<int>::Distance, std::make_tuple(vector));
REQUIRE(result == 0);
}
}
TEST_CASE("ComputeHash", "[CORE][ALGORITHM]")
{
SECTION("Compute hash of '0'")
{
auto result = Nz::ComputeHash(Nz::HashType_SHA512, "1234");
REQUIRE(result.ToHex().ToUpper() == "D404559F602EAB6FD602AC7680DACBFAADD13630335E951F097AF3900E9DE176B6DB28512F2E000B9D04FBA5133E8B1C6E8DF59DB3A8AB9D60BE4B97CC9E81DB");
}
}

View File

@ -0,0 +1,117 @@
#include <Nazara/Core/Bitset.hpp>
#include <Catch/catch.hpp>
#include <string>
SCENARIO("Bitset", "[CORE][BITSET]")
{
GIVEN("Allocate and constructor")
{
Nz::Bitset<> bitset(3);
THEN("Capacity is 3 and size is 3")
{
REQUIRE(bitset.GetSize() == 3);
REQUIRE(bitset.GetCapacity() >= 3);
}
}
GIVEN("Iterator and default constructor")
{
Nz::String anotherDataString("0101");
Nz::Bitset<> defaultByte;
Nz::Bitset<> anotherData(anotherDataString.GetConstBuffer());
WHEN("We assign 'anotherData'")
{
defaultByte = anotherDataString;
REQUIRE(anotherData == defaultByte);
REQUIRE(defaultByte.GetSize() == 4);
REQUIRE(defaultByte.GetCapacity() >= 4);
REQUIRE(anotherData.GetSize() == 4);
REQUIRE(anotherData.GetCapacity() >= 4);
}
}
GIVEN("Copy and Move constructor")
{
Nz::Bitset<> originalArray(3, true);
WHEN("We copy")
{
Nz::Bitset<> copyBitset(originalArray);
THEN("We get a copy")
{
REQUIRE(copyBitset == originalArray);
AND_WHEN("We modify one")
{
for (auto i = 0; i < copyBitset.GetSize(); ++i)
copyBitset[i] = false;
THEN("They are no more equal")
{
REQUIRE(copyBitset != originalArray);
REQUIRE(copyBitset == Nz::Bitset<>(3, false));
}
}
}
}
WHEN("We move")
{
Nz::Bitset<> moveBitset(std::move(originalArray));
THEN("These results are expected")
{
REQUIRE(moveBitset == Nz::Bitset<>(3, true));
REQUIRE(originalArray.GetCapacity() == 0);
}
}
}
GIVEN("Three bitsets")
{
Nz::Bitset<> first("01001");
Nz::Bitset<> second("10110");
Nz::Bitset<> third;
WHEN("We swap first and third, then second and third and finally third and first")
{
Nz::Bitset<> oldFirst(first);
Nz::Bitset<> oldSecond(second);
first.Swap(third);
std::swap(second, third);
third.Swap(first);
THEN("First and second have been swapped and third is still empty.")
{
REQUIRE(oldFirst == second);
REQUIRE(oldSecond == first);
REQUIRE(third.GetSize() == 0);
}
}
}
GIVEN("Two bitsets")
{
Nz::Bitset<> first("01001");
Nz::Bitset<> second("10111");
WHEN("We perform operators")
{
Nz::Bitset<> andBitset = first & second;
Nz::Bitset<> orBitset = first | second;
Nz::Bitset<> xorBitset = first ^ second;
THEN("They should operate as logical operators")
{
REQUIRE(andBitset == Nz::Bitset<>("00001"));
REQUIRE(orBitset == Nz::Bitset<>("11111"));
REQUIRE(xorBitset == Nz::Bitset<>("11110"));
}
}
}
}

View File

@ -0,0 +1,28 @@
#include <Nazara/Core/MemoryPool.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Math/Vector2.hpp>
SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]")
{
GIVEN("A MemoryPool to contain one Nz::Vector2<int>")
{
Nz::MemoryPool memoryPool(sizeof(Nz::Vector2<int>), 1, false);
WHEN("We construct a Nz::Vector2<int>")
{
Nz::Vector2<int>* vector2 = memoryPool.New<Nz::Vector2<int>>(1, 2);
THEN("Memory is available")
{
vector2->x = 3;
REQUIRE(*vector2 == Nz::Vector2<int>(3, 2));
}
THEN("We can destroy the vector2")
{
memoryPool.Delete(vector2);
}
}
}
}

View File

@ -0,0 +1,41 @@
#include <Nazara/Core/ObjectRef.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Utility/Font.hpp>
SCENARIO("ObjectRef", "[CORE][OBJECTREF]")
{
GIVEN("A ObjectRef")
{
Nz::ObjectRef<Nz::Font> objectRef;
WHEN("We have two objectRef handling the same object")
{
Nz::Font font;
objectRef = &font;
Nz::ObjectRef<Nz::Font> otherRef(&font);
THEN("Pointers the same")
{
REQUIRE(objectRef.IsValid());
REQUIRE(otherRef.IsValid());
}
objectRef.Reset(nullptr);
}
WHEN("We assign it to a simple font")
{
Nz::Font font;
THEN("Release suppress the reference to the object")
{
objectRef.Reset(&font);
objectRef.Release();
REQUIRE(!objectRef.IsValid());
}
}
}
}

View File

@ -0,0 +1,52 @@
#include <Nazara/Core/ParameterList.hpp>
#include <Catch/catch.hpp>
#include <Nazara/Core/String.hpp>
SCENARIO("ParameterList", "[CORE][PARAMETERLIST]")
{
GIVEN("An empty ParameterList")
{
Nz::ParameterList parameterList;
WHEN("We add String 'string'")
{
Nz::String string("string");
parameterList.SetParameter("string", string);
THEN("We can get it back")
{
Nz::String newString;
REQUIRE(parameterList.GetStringParameter("string", &newString));
REQUIRE(newString == string);
}
}
WHEN("We add Float '3.f'")
{
float fl = 3.f;
parameterList.SetParameter("float", fl);
THEN("We can get it back")
{
float newFl;
REQUIRE(parameterList.GetFloatParameter("float", &newFl));
REQUIRE(newFl == fl);
}
}
WHEN("We add Pointer to stack value")
{
int stackValue = 3;
void* ptrToStackValue = &stackValue; // Ugly conversion
parameterList.SetParameter("ptr", ptrToStackValue);
THEN("We can get it back")
{
void* newPtrToStackValue = nullptr;
REQUIRE(parameterList.GetPointerParameter("ptr", &newPtrToStackValue));
REQUIRE(newPtrToStackValue == ptrToStackValue);
}
}
}
}

View File

@ -0,0 +1,31 @@
#include <Nazara/Core/PrimitiveList.hpp>
#include <Catch/catch.hpp>
SCENARIO("PrimitiveList", "[CORE][PRIMITIVELIST]")
{
GIVEN("An empty PrimitiveList")
{
Nz::PrimitiveList primitiveList;
WHEN("We add two primitives")
{
float size = 1.f;
unsigned int subdivision = 1;
unsigned int recursionLevel = 1;
Nz::Matrix4f identity = Nz::Matrix4f::Identity();
primitiveList.AddCubicSphere(size, subdivision, identity);
primitiveList.AddIcoSphere(size, subdivision, identity);
THEN("There must be two items")
{
REQUIRE(primitiveList.GetSize() == 2);
}
THEN("The first one is the cubic sphere")
{
REQUIRE(primitiveList(0).sphere.type == Nz::SphereType_Cubic);
}
}
}
}

View File

@ -0,0 +1,29 @@
#include <Nazara/Core/RefCounted.hpp>
#include <Catch/catch.hpp>
SCENARIO("RefCounted", "[CORE][REFCOUNTED]")
{
GIVEN("A refcounted persistent")
{
Nz::RefCounted refCounted;
REQUIRE(refCounted.IsPersistent() == true);
WHEN("We add a reference to this persistent object")
{
THEN("Number of references should be one")
{
refCounted.AddReference();
REQUIRE(refCounted.GetReferenceCount() == 1);
REQUIRE(refCounted.RemoveReference() == false);
}
AND_THEN("We suppress the reference, object is still alive")
{
refCounted.AddReference();
REQUIRE(refCounted.IsPersistent());
REQUIRE(refCounted.RemoveReference() == false);
REQUIRE(refCounted.GetReferenceCount() == 0);
}
}
}
}

View File

@ -0,0 +1,48 @@
#include <Nazara/Core/Signal.hpp>
#include <Catch/catch.hpp>
struct Incrementer
{
void increment(int* inc)
{
*inc += 1;
}
};
void increment(int* inc)
{
*inc += 1;
}
SCENARIO("Signal", "[CORE][SIGNAL]")
{
GIVEN("A signal")
{
Nz::Signal<int*> signal;
WHEN("We connection different callbacks")
{
auto connection = signal.Connect(increment);
signal.Connect([](int* inc){ *inc += 1; });
Incrementer incrementer;
signal.Connect(incrementer, &Incrementer::increment);
THEN("The call of signal with inc = 0 must return 3")
{
int inc = 0;
signal(&inc);
REQUIRE(inc == 3);
}
AND_THEN("When we disconnect one function, there should be only two listeners")
{
connection.Disconnect();
REQUIRE(!connection.IsConnected());
int inc = 0;
signal(&inc);
REQUIRE(inc == 2);
}
}
}
}

View File

@ -0,0 +1,47 @@
#include <Nazara/Core/SparsePtr.hpp>
#include <Catch/catch.hpp>
#include <array>
SCENARIO("SparsePtr", "[CORE][SPARSEPTR]")
{
GIVEN("A sparse pointer pointing to an array with a stride of 2")
{
std::array<int, 5> arrays{0, 1, 2, 3, 4};
Nz::SparsePtr<int> sparsePtr(arrays.begin(), 2 * sizeof(int));
WHEN("We use operators")
{
THEN("Operator[] with 2 should be 4")
{
REQUIRE(4 == sparsePtr[2]);
}
THEN("Operator++ and Operator-- should be opposite")
{
++sparsePtr;
REQUIRE(2 == *sparsePtr);
auto old = sparsePtr++;
REQUIRE(2 == *old);
REQUIRE(4 == *sparsePtr);
--sparsePtr;
REQUIRE(2 == *sparsePtr);
auto oldMinus = sparsePtr--;
REQUIRE(2 == *oldMinus);
REQUIRE(0 == *sparsePtr);
}
THEN("Operator+ and operator-")
{
auto offsetTwo = sparsePtr + 2;
REQUIRE(4 == *offsetTwo);
auto offsetZero = offsetTwo - 2;
REQUIRE(0 == *offsetZero);
REQUIRE((offsetTwo - offsetZero) == 2);
}
}
}
}

View File

@ -0,0 +1,256 @@
#include <Nazara/Math/Algorithm.hpp>
#include <Catch/catch.hpp>
TEST_CASE("Approach", "[MATH][ALGORITHM]")
{
SECTION("Approach 8 with 5 by 2")
{
REQUIRE(Nz::Approach(5, 8, 2) == 7);
}
SECTION("Approach 5 with 8 by 2")
{
REQUIRE(Nz::Approach(8, 5, 2) == 6);
}
SECTION("Approach 8 with 8 by 2")
{
REQUIRE(Nz::Approach(8, 8, 2) == 8);
}
}
TEST_CASE("Clamp", "[MATH][ALGORITHM]")
{
SECTION("Clamp 8 between 5 and 10")
{
REQUIRE(Nz::Clamp(8, 5, 10) == 8);
}
SECTION("Clamp 4 between 5 and 10")
{
REQUIRE(Nz::Clamp(4, 5, 10) == 5);
}
SECTION("Clamp 12 between 5 and 10")
{
REQUIRE(Nz::Clamp(12, 5, 10) == 10);
}
}
TEST_CASE("CountBits", "[MATH][ALGORITHM]")
{
SECTION("Number 10 has 2 bits set to 1")
{
REQUIRE(Nz::CountBits(10) == 2);
}
SECTION("Number 0 has 0 bit set to 1")
{
REQUIRE(Nz::CountBits(0) == 0);
}
}
TEST_CASE("DegreeToRadian", "[MATH][ALGORITHM]")
{
SECTION("Convert 45.f degree to radian")
{
REQUIRE(Nz::DegreeToRadian(45.f) == Approx(M_PI / 4));
}
}
TEST_CASE("GetNearestPowerOfTwo", "[MATH][ALGORITHM]")
{
SECTION("Nearest power of two of 0 = 1")
{
REQUIRE(Nz::GetNearestPowerOfTwo(0) == 1);
}
SECTION("Nearest power of two of 16 = 16")
{
REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16);
}
SECTION("Nearest power of two of 17 = 32")
{
REQUIRE(Nz::GetNearestPowerOfTwo(17) == 32);
}
}
TEST_CASE("GetNumberLength", "[MATH][ALGORITHM]")
{
SECTION("GetNumberLength of -127 signed char")
{
signed char minus127 = -127;
REQUIRE(Nz::GetNumberLength(minus127) == 4);
}
SECTION("GetNumberLength of 255 unsigned char")
{
unsigned char plus255 = 255;
REQUIRE(Nz::GetNumberLength(plus255) == 3);
}
SECTION("GetNumberLength of -1270 signed int")
{
signed int minus1270 = -1270;
REQUIRE(Nz::GetNumberLength(minus1270) == 5);
}
SECTION("GetNumberLength of 2550 unsigned int")
{
unsigned int plus2550 = 2550;
REQUIRE(Nz::GetNumberLength(plus2550) == 4);
}
SECTION("GetNumberLength of -1270 signed long long")
{
signed long long minus12700 = -12700;
REQUIRE(Nz::GetNumberLength(minus12700) == 6);
}
SECTION("GetNumberLength of 2550 unsigned long long")
{
unsigned long long plus25500 = 25500;
REQUIRE(Nz::GetNumberLength(plus25500) == 5);
}
SECTION("GetNumberLength of -2.456f float")
{
float minus2P456 = -2.456f;
REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6);
}
SECTION("GetNumberLength of -2.456 double")
{
double minus2P456 = -2.456;
REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6);
}
SECTION("GetNumberLength of -2.456 long double")
{
long double minus2P456 = -2.456L;
REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6);
}
}
TEST_CASE("IntegralLog2", "[MATH][ALGORITHM]")
{
SECTION("According to implementation, log in base 2 of 0 = 0")
{
REQUIRE(Nz::IntegralLog2(0) == 0);
}
SECTION("Log in base 2 of 1 = 0")
{
REQUIRE(Nz::IntegralLog2(1) == 0);
}
SECTION("Log in base 2 of 4 = 2")
{
REQUIRE(Nz::IntegralLog2(4) == 2);
}
SECTION("Log in base 2 of 5 = 2")
{
REQUIRE(Nz::IntegralLog2(5) == 2);
}
}
TEST_CASE("IntegralLog2Pot", "[MATH][ALGORITHM]")
{
SECTION("According to implementation, log in base 2 of 0 = 0")
{
REQUIRE(Nz::IntegralLog2Pot(0) == 0);
}
SECTION("Log in base 2 of 1 = 0")
{
REQUIRE(Nz::IntegralLog2Pot(1) == 0);
}
SECTION("Log in base 2 of 4 = 2")
{
REQUIRE(Nz::IntegralLog2Pot(4) == 2);
}
}
TEST_CASE("IntegralPow", "[MATH][ALGORITHM]")
{
SECTION("2 to power 4")
{
REQUIRE(Nz::IntegralPow(2, 4) == 16);
}
}
TEST_CASE("Lerp", "[MATH][ALGORITHM]")
{
SECTION("Lerp 2 to 6 with 0.5")
{
REQUIRE(Nz::Lerp(2, 6, 0.5) == 4);
}
}
TEST_CASE("MultiplyAdd", "[MATH][ALGORITHM]")
{
SECTION("2 * 3 + 1")
{
REQUIRE(Nz::MultiplyAdd(2, 3, 1) == 7);
}
}
TEST_CASE("NumberEquals", "[MATH][ALGORITHM]")
{
SECTION("2.35 and 2.351 should be the same at 0.01")
{
CHECK(Nz::NumberEquals(2.35, 2.35, 0.01));
}
SECTION("3 and 4 unsigned should be the same at 1")
{
CHECK(Nz::NumberEquals(3U, 4U, 1U));
}
}
TEST_CASE("NumberToString", "[MATH][ALGORITHM]")
{
SECTION("235 to string")
{
REQUIRE(Nz::NumberToString(235) == "235");
}
SECTION("-235 to string")
{
REQUIRE(Nz::NumberToString(-235) == "-235");
}
SECTION("16 in base 16 to string")
{
REQUIRE(Nz::NumberToString(16, 16) == "10");
}
}
TEST_CASE("RadianToDegree", "[MATH][ALGORITHM]")
{
SECTION("PI / 4 to degree")
{
REQUIRE(Nz::RadianToDegree(M_PI / 4) == Approx(45.f));
}
}
TEST_CASE("StringToNumber", "[MATH][ALGORITHM]")
{
SECTION("235 in string")
{
REQUIRE(Nz::StringToNumber("235") == 235);
}
SECTION("-235 in string")
{
REQUIRE(Nz::StringToNumber("-235") == -235);
}
SECTION("16 in base 16 in string")
{
REQUIRE(Nz::StringToNumber("10", 16) == 16);
}
}