mirror of
https://github.com/NoelFB/blah.git
synced 2024-11-25 16:18:57 +08:00
changing back to custom vector class
This commit is contained in:
parent
088e3a9103
commit
b5e2c53613
|
@ -35,7 +35,8 @@ add_library(blah
|
|||
public/blah/input/virtual_button.h
|
||||
public/blah/input/virtual_axis.cpp
|
||||
public/blah/input/virtual_axis.h
|
||||
|
||||
|
||||
public/blah/containers/vector.h
|
||||
public/blah/containers/stackvector.h
|
||||
public/blah/containers/str.cpp
|
||||
public/blah/containers/str.h
|
||||
|
@ -83,6 +84,7 @@ add_library(blah
|
|||
public/blah/math/vec2.h
|
||||
public/blah/math/vec4.h
|
||||
|
||||
public/blah/streams/endian.h
|
||||
public/blah/streams/bufferstream.cpp
|
||||
public/blah/streams/bufferstream.h
|
||||
public/blah/streams/filestream.cpp
|
||||
|
@ -99,7 +101,7 @@ add_library(blah
|
|||
private/blah/internal/graphics_opengl.cpp
|
||||
private/blah/internal/input.h
|
||||
private/blah/internal/platform.h
|
||||
private/blah/internal/platform_sdl2.cpp "public/blah/containers/vector.h")
|
||||
private/blah/internal/platform_sdl2.cpp)
|
||||
|
||||
target_include_directories(blah
|
||||
PUBLIC
|
||||
|
|
|
@ -49,4 +49,5 @@
|
|||
#include <blah/streams/bufferstream.h>
|
||||
#include <blah/streams/filestream.h>
|
||||
#include <blah/streams/memorystream.h>
|
||||
#include <blah/streams/stream.h>
|
||||
#include <blah/streams/stream.h>
|
||||
#include <blah/streams/endian.h>
|
|
@ -1,317 +0,0 @@
|
|||
#pragma once
|
||||
#include <blah/log.h>
|
||||
#include <type_traits>
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
template<class T>
|
||||
class List
|
||||
{
|
||||
private:
|
||||
// internal list buffer
|
||||
T* m_buffer;
|
||||
|
||||
// total elements
|
||||
int m_count;
|
||||
|
||||
// total capacity
|
||||
int m_capacity;
|
||||
|
||||
public:
|
||||
|
||||
List();
|
||||
List(int capacity);
|
||||
List(const List& src);
|
||||
List(List&& src) noexcept;
|
||||
~List();
|
||||
|
||||
List& operator=(const List& src);
|
||||
List& operator=(List&& src) noexcept;
|
||||
|
||||
// reserves the given amount of capacity
|
||||
void reserve(int new_capacity);
|
||||
|
||||
// adds an element to the list
|
||||
void add(const T& item);
|
||||
|
||||
template<class ...Args>
|
||||
void emplace(Args&&...args);
|
||||
|
||||
// moves an element into the list
|
||||
void add(T&& item);
|
||||
|
||||
// expands the list by the given amount, and returns a pointer to the first element
|
||||
T* expand(int amount = 1);
|
||||
|
||||
// returns a reference to the element at the given index
|
||||
T& operator[](int index);
|
||||
|
||||
// returns a reference to the element at the given index
|
||||
const T& operator[](int index) const;
|
||||
|
||||
// returns a pointer to the first element
|
||||
T* begin() { return m_buffer; }
|
||||
|
||||
// returns a pointer to the first element
|
||||
const T* begin() const { return m_buffer; }
|
||||
|
||||
// returns a pointer to the last element
|
||||
T* end() { return m_buffer + m_count; }
|
||||
|
||||
// returns a pointer to the last element
|
||||
const T* end() const { return m_buffer + m_count; }
|
||||
|
||||
// clears all elements
|
||||
void clear();
|
||||
|
||||
// removes the element at the index
|
||||
void remove_at(int index);
|
||||
|
||||
// checks whether the given value is in the List (uses == operator)
|
||||
bool contains(const T& item) const;
|
||||
|
||||
// returns the index of the given value in the list (uses == operator, -1 if not in list)
|
||||
int index_of(const T& item) const;
|
||||
|
||||
// pops the top element off the list
|
||||
T pop();
|
||||
|
||||
// returns the total number of elements
|
||||
int count() const { return m_count; }
|
||||
|
||||
// returns the internal buffer capacity of the list
|
||||
int capacity() const { return m_capacity; }
|
||||
|
||||
// removes all elements and disposes the internal buffer
|
||||
void dispose();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
List<T>::List()
|
||||
{
|
||||
m_buffer = nullptr;
|
||||
m_count = m_capacity = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>::List(int capacity)
|
||||
{
|
||||
m_buffer = nullptr;
|
||||
m_count = m_capacity = capacity;
|
||||
reserve(m_capacity);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>::List(const List<T>& src)
|
||||
{
|
||||
m_buffer = (T*)(::operator new (sizeof(T) * src.m_capacity));
|
||||
m_count = src.m_count;
|
||||
m_capacity = src.m_capacity;
|
||||
|
||||
for (int n = 0; n < m_count; n++)
|
||||
new (m_buffer + n) T(*(src.m_buffer + n));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>::List(List<T>&& src) noexcept
|
||||
{
|
||||
m_buffer = src.m_buffer;
|
||||
m_count = src.m_count;
|
||||
m_capacity = src.m_capacity;
|
||||
src.m_buffer = nullptr;
|
||||
src.m_count = src.m_capacity = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>& List<T>::operator=(const List<T>& src)
|
||||
{
|
||||
clear();
|
||||
|
||||
if (m_capacity < src.m_count)
|
||||
reserve(src.m_count);
|
||||
m_count = src.m_count;
|
||||
|
||||
for (int n = 0; n < m_count; n++)
|
||||
new (m_buffer + n) T(*(src.m_buffer + n));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>& List<T>::operator=(List<T>&& src) noexcept
|
||||
{
|
||||
dispose();
|
||||
m_buffer = src.m_buffer;
|
||||
m_count = src.m_count;
|
||||
m_capacity = src.m_capacity;
|
||||
src.m_buffer = nullptr;
|
||||
src.m_count = src.m_capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
List<T>::~List()
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::reserve(int new_capacity)
|
||||
{
|
||||
if (new_capacity >= m_capacity)
|
||||
{
|
||||
auto last_capacity = m_capacity;
|
||||
|
||||
if (m_capacity <= 0)
|
||||
m_capacity = 8;
|
||||
|
||||
while (new_capacity >= m_capacity)
|
||||
m_capacity = m_capacity * 2;
|
||||
|
||||
T* new_buffer = (T*)::operator new (sizeof(T) * m_capacity);
|
||||
|
||||
if (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
memcpy(new_buffer, m_buffer, sizeof(T) * m_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int n = 0; n < m_count; n++)
|
||||
{
|
||||
new (new_buffer + n) T(std::move(m_buffer[n]));
|
||||
m_buffer[n].~T();
|
||||
}
|
||||
}
|
||||
|
||||
::operator delete (m_buffer, sizeof(T) * last_capacity);
|
||||
m_buffer = new_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* List<T>::expand(int amount)
|
||||
{
|
||||
reserve(m_count + amount);
|
||||
for (int n = m_count; n < m_count + amount; n++)
|
||||
new (m_buffer + n) T();
|
||||
m_count += amount;
|
||||
return (m_buffer + m_count - amount);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::add(const T& item)
|
||||
{
|
||||
reserve(m_count + 1);
|
||||
new (m_buffer + m_count) T(item);
|
||||
m_count++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class ...Args>
|
||||
void List<T>::emplace(Args&&...args)
|
||||
{
|
||||
reserve(m_count + 1);
|
||||
new (m_buffer + m_count) T(args);
|
||||
m_count++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::add(T&& item)
|
||||
{
|
||||
reserve(m_count + 1);
|
||||
new (m_buffer + m_count) T(std::move(item));
|
||||
m_count++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& List<T>::operator[](int index)
|
||||
{
|
||||
BLAH_ASSERT(index >= 0 && index < m_count, "Index is out of range");
|
||||
return m_buffer[index];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T& List<T>::operator[](int index) const
|
||||
{
|
||||
BLAH_ASSERT(index >= 0 && index < m_count, "Index is out of range");
|
||||
return m_buffer[index];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::clear()
|
||||
{
|
||||
for (T* it = m_buffer; it < m_buffer + m_count; it++)
|
||||
it->~T();
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::remove_at(int index)
|
||||
{
|
||||
BLAH_ASSERT(index >= 0 && index < m_count, "Index is out of range");
|
||||
|
||||
m_buffer[index].~T();
|
||||
|
||||
if (index < m_count - 1)
|
||||
{
|
||||
int diff = (m_count - index - 1);
|
||||
if (diff <= 0)
|
||||
diff = 0;
|
||||
|
||||
if (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
memmove(m_buffer + index, m_buffer + index + 1, (size_t)diff * sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = index; i < m_count - 1; i++)
|
||||
m_buffer[i] = std::move(m_buffer[i + 1]);
|
||||
m_buffer[m_count - 1].~T();
|
||||
}
|
||||
}
|
||||
|
||||
m_count--;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool List<T>::contains(const T& item) const
|
||||
{
|
||||
for (int i = 0; i < m_count; i++)
|
||||
if (*(m_buffer + i) == item)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
int List<T>::index_of(const T& item) const
|
||||
{
|
||||
for (int i = 0; i < m_count; i++)
|
||||
if (*(m_buffer + i) == item)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T List<T>::pop()
|
||||
{
|
||||
BLAH_ASSERT(m_count > 0, "There are no elements to pop");
|
||||
m_count--;
|
||||
|
||||
T item = m_buffer[m_count];
|
||||
m_buffer[m_count].~T();
|
||||
return item;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void List<T>::dispose()
|
||||
{
|
||||
clear();
|
||||
::operator delete (m_buffer, sizeof(T) * m_capacity);
|
||||
m_buffer = nullptr;
|
||||
m_count = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,317 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <blah/log.h>
|
||||
#include <type_traits>
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
template<typename T>
|
||||
using Vector = std::vector<T>;
|
||||
}
|
||||
template<class T>
|
||||
class Vector
|
||||
{
|
||||
private:
|
||||
T* m_buffer;
|
||||
size_t m_size;
|
||||
size_t m_capacity;
|
||||
|
||||
public:
|
||||
|
||||
Vector();
|
||||
Vector(int capacity);
|
||||
Vector(const Vector& src);
|
||||
Vector(Vector&& src) noexcept;
|
||||
~Vector();
|
||||
|
||||
Vector& operator=(const Vector& src);
|
||||
Vector& operator=(Vector&& src) noexcept;
|
||||
|
||||
// reserves the given amount of capacity
|
||||
void reserve(size_t new_capacity);
|
||||
|
||||
// adds an element to the Vector
|
||||
void push_back(const T& item);
|
||||
|
||||
// moves an element into the Vector
|
||||
void push_back(T&& item);
|
||||
|
||||
template<class ...Args>
|
||||
void emplace_back(Args&&...args);
|
||||
|
||||
// resizes the vector
|
||||
void resize(size_t capacity);
|
||||
|
||||
// expands the Vector by the given amount, and returns a pointer to the first element
|
||||
T* expand(size_t amount = 1);
|
||||
|
||||
// returns a reference to the element at the given index
|
||||
T& operator[](int index);
|
||||
|
||||
// returns a reference to the element at the given index
|
||||
const T& operator[](int index) const;
|
||||
|
||||
// returns a pointer to the first element
|
||||
T* data() { return m_buffer; }
|
||||
|
||||
// returns a pointer to the first element
|
||||
const T* data() const { return m_buffer; }
|
||||
|
||||
// returns a pointer to the first element
|
||||
T* begin() { return m_buffer; }
|
||||
|
||||
// returns a pointer to the first element
|
||||
const T* begin() const { return m_buffer; }
|
||||
|
||||
// returns a pointer to the last element plus 1
|
||||
T* end() { return m_buffer + m_size; }
|
||||
|
||||
// returns a pointer to the last element plus 1
|
||||
const T* end() const { return m_buffer + m_size; }
|
||||
|
||||
// returns the front element
|
||||
T& front() { BLAH_ASSERT(m_size > 0, "Index out of range"); return *begin(); }
|
||||
|
||||
// returns the front element
|
||||
const T& front() const { BLAH_ASSERT(m_size > 0, "Index out of range"); return *begin(); }
|
||||
|
||||
// returns the last element
|
||||
T& back() { BLAH_ASSERT(m_size > 0, "Index out of range"); return *(end() - 1); }
|
||||
|
||||
// returns the last element
|
||||
const T& back() const { BLAH_ASSERT(m_size > 0, "Index out of range"); return *(end() - 1); }
|
||||
|
||||
// clears all elements
|
||||
void clear();
|
||||
|
||||
// removes the element at the index
|
||||
void erase(const T* position);
|
||||
|
||||
// returns the total number of elements
|
||||
size_t size() const { return m_size; }
|
||||
|
||||
// returns the internal buffer capacity of the Vector
|
||||
size_t capacity() const { return m_capacity; }
|
||||
|
||||
// removes all elements and disposes the internal buffer
|
||||
void dispose();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
Vector<T>::Vector()
|
||||
{
|
||||
m_buffer = nullptr;
|
||||
m_size = m_capacity = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>::Vector(int capacity)
|
||||
{
|
||||
m_buffer = nullptr;
|
||||
m_size = m_capacity = capacity;
|
||||
reserve(m_capacity);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>::Vector(const Vector<T>& src)
|
||||
{
|
||||
m_buffer = (T*)(::operator new (sizeof(T) * src.m_capacity));
|
||||
m_size = src.m_size;
|
||||
m_capacity = src.m_capacity;
|
||||
|
||||
for (int n = 0; n < m_size; n++)
|
||||
new (m_buffer + n) T(*(src.m_buffer + n));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>::Vector(Vector<T>&& src) noexcept
|
||||
{
|
||||
m_buffer = src.m_buffer;
|
||||
m_size = src.m_size;
|
||||
m_capacity = src.m_capacity;
|
||||
src.m_buffer = nullptr;
|
||||
src.m_size = src.m_capacity = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>& Vector<T>::operator=(const Vector<T>& src)
|
||||
{
|
||||
clear();
|
||||
|
||||
if (m_capacity < src.m_size)
|
||||
reserve(src.m_size);
|
||||
m_size = src.m_size;
|
||||
|
||||
for (int n = 0; n < m_size; n++)
|
||||
new (m_buffer + n) T(*(src.m_buffer + n));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>& Vector<T>::operator=(Vector<T>&& src) noexcept
|
||||
{
|
||||
dispose();
|
||||
m_buffer = src.m_buffer;
|
||||
m_size = src.m_size;
|
||||
m_capacity = src.m_capacity;
|
||||
src.m_buffer = nullptr;
|
||||
src.m_size = src.m_capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Vector<T>::~Vector()
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::reserve(size_t new_capacity)
|
||||
{
|
||||
if (new_capacity >= m_capacity)
|
||||
{
|
||||
auto last_capacity = m_capacity;
|
||||
|
||||
if (m_capacity <= 0)
|
||||
m_capacity = 8;
|
||||
|
||||
while (new_capacity >= m_capacity)
|
||||
m_capacity = m_capacity * 2;
|
||||
|
||||
T* new_buffer = (T*)::operator new (sizeof(T) * m_capacity);
|
||||
|
||||
if (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
memcpy(new_buffer, m_buffer, sizeof(T) * m_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int n = 0; n < m_size; n++)
|
||||
{
|
||||
new (new_buffer + n) T(std::move(m_buffer[n]));
|
||||
m_buffer[n].~T();
|
||||
}
|
||||
}
|
||||
|
||||
::operator delete (m_buffer, sizeof(T) * last_capacity);
|
||||
m_buffer = new_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::resize(size_t new_size)
|
||||
{
|
||||
if (new_size > m_size)
|
||||
{
|
||||
reserve(new_size);
|
||||
for (int n = m_size; n < new_size; n++)
|
||||
new (m_buffer + n) T();
|
||||
}
|
||||
else if (new_size < m_size)
|
||||
{
|
||||
for (int i = new_size; i < m_size; i ++)
|
||||
m_buffer[i].~T();
|
||||
}
|
||||
|
||||
m_size = new_size;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* Vector<T>::expand(size_t amount)
|
||||
{
|
||||
reserve(m_size + amount);
|
||||
for (int n = m_size; n < m_size + amount; n++)
|
||||
new (m_buffer + n) T();
|
||||
m_size += amount;
|
||||
return (m_buffer + m_size - amount);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::push_back(const T& item)
|
||||
{
|
||||
reserve(m_size + 1);
|
||||
new (m_buffer + m_size) T(item);
|
||||
m_size++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::push_back(T&& item)
|
||||
{
|
||||
reserve(m_size + 1);
|
||||
new (m_buffer + m_size) T(std::move(item));
|
||||
m_size++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template<class ...Args>
|
||||
void Vector<T>::emplace_back(Args&&...args)
|
||||
{
|
||||
reserve(m_size + 1);
|
||||
new (m_buffer + m_size) T(std::forward<Args>(args)...);
|
||||
m_size++;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& Vector<T>::operator[](int index)
|
||||
{
|
||||
BLAH_ASSERT(index >= 0 && index < m_size, "Index is out of range");
|
||||
return m_buffer[index];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T& Vector<T>::operator[](int index) const
|
||||
{
|
||||
BLAH_ASSERT(index >= 0 && index < m_size, "Index is out of range");
|
||||
return m_buffer[index];
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::clear()
|
||||
{
|
||||
for (T* it = m_buffer; it < m_buffer + m_size; it++)
|
||||
it->~T();
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::erase(const T* position)
|
||||
{
|
||||
BLAH_ASSERT(position >= begin() && position < end(), "Index is out of range");
|
||||
|
||||
const size_t index = position - begin();
|
||||
|
||||
if (index < m_size - 1)
|
||||
{
|
||||
size_t diff = (m_size - index - 1);
|
||||
if (diff <= 0) diff = 0;
|
||||
|
||||
if (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
m_buffer[index].~T();
|
||||
memmove(m_buffer + index, m_buffer + index + 1, (size_t)diff * sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = index; i < m_size - 1; i++)
|
||||
m_buffer[i] = std::move(m_buffer[i + 1]);
|
||||
m_buffer[m_size - 1].~T();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer[index].~T();
|
||||
}
|
||||
|
||||
m_size--;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void Vector<T>::dispose()
|
||||
{
|
||||
clear();
|
||||
::operator delete (m_buffer, sizeof(T) * m_capacity);
|
||||
m_buffer = nullptr;
|
||||
m_size = 0;
|
||||
m_capacity = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,38 +67,47 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
#define MAKE_VERTEX(mat, px, py, tx, ty, c, m, w, f) \
|
||||
{ \
|
||||
Vec2( \
|
||||
((px)*mat.m11) + ((py)*mat.m21) + mat.m31, \
|
||||
((px)*mat.m12) + ((py)*mat.m22) + mat.m32), \
|
||||
Vec2(tx, (m_batch.flip_vertically ? 1.0f - ty : ty)), \
|
||||
c, m, w, f \
|
||||
}
|
||||
#define MAKE_VERTEX(vert, mat, px, py, tx, ty, c, m, w, f) \
|
||||
(vert)->pos.x = ((px) * mat.m11) + ((py) * mat.m21) + mat.m31; \
|
||||
(vert)->pos.y = ((px) * mat.m12) + ((py) * mat.m22) + mat.m32; \
|
||||
(vert)->tex.x = tx; \
|
||||
if (m_batch.flip_vertically) \
|
||||
(vert)->tex.y = 1.0f - ty; \
|
||||
else \
|
||||
(vert)->tex.y = ty; \
|
||||
(vert)->col = c; \
|
||||
(vert)->mult = m; \
|
||||
(vert)->wash = w; \
|
||||
(vert)->fill = f;
|
||||
|
||||
#define PUSH_QUAD(px0, py0, px1, py1, px2, py2, px3, py3, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, col0, col1, col2, col3, mult, fill, wash) \
|
||||
{ \
|
||||
const int __v = (int)m_vertices.size(); \
|
||||
m_batch.elements += 2; \
|
||||
m_indices.insert(m_indices.end(), { __v + 0, __v + 1, __v + 2, __v + 0, __v + 2, __v + 3 }); \
|
||||
m_vertices.insert(m_vertices.end(), { \
|
||||
MAKE_VERTEX(m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash), \
|
||||
MAKE_VERTEX(m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash), \
|
||||
MAKE_VERTEX(m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash), \
|
||||
MAKE_VERTEX(m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash) \
|
||||
}); \
|
||||
int* _i = m_indices.expand(6); \
|
||||
*_i++ = m_vertices.size() + 0; \
|
||||
*_i++ = m_vertices.size() + 1; \
|
||||
*_i++ = m_vertices.size() + 2; \
|
||||
*_i++ = m_vertices.size() + 0; \
|
||||
*_i++ = m_vertices.size() + 2; \
|
||||
*_i++ = m_vertices.size() + 3; \
|
||||
Vertex* _v = m_vertices.expand(4); \
|
||||
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash); \
|
||||
}
|
||||
|
||||
#define PUSH_TRIANGLE(px0, py0, px1, py1, px2, py2, tx0, ty0, tx1, ty1, tx2, ty2, col0, col1, col2, mult, fill, wash) \
|
||||
{ \
|
||||
const int __v = (int)m_vertices.size(); \
|
||||
m_batch.elements += 1; \
|
||||
m_indices.insert(m_indices.end(), { __v + 0, __v + 1, __v + 2 }); \
|
||||
m_vertices.insert(m_vertices.end(), { \
|
||||
MAKE_VERTEX(m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash), \
|
||||
MAKE_VERTEX(m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash), \
|
||||
MAKE_VERTEX(m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash) \
|
||||
}); \
|
||||
int* _i = m_indices.expand(3); \
|
||||
*_i++ = m_vertices.size() + 0; \
|
||||
*_i++ = m_vertices.size() + 1; \
|
||||
*_i++ = m_vertices.size() + 2; \
|
||||
Vertex* _v = m_vertices.expand(3); \
|
||||
MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \
|
||||
MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); \
|
||||
}
|
||||
|
||||
// Compares a Batcher variable, and starts a new batch if it has changed
|
||||
|
|
39
public/blah/streams/endian.h
Normal file
39
public/blah/streams/endian.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
enum class Endian
|
||||
{
|
||||
Little,
|
||||
Big
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline void swap_endian(T* value)
|
||||
{
|
||||
for (int i = 0; i < sizeof(T) / 2; i++)
|
||||
{
|
||||
char* _ptr = (char*)&value;
|
||||
char _temp = *(_ptr + i);
|
||||
*(_ptr + i) = *(_ptr + sizeof(T) - i - 1);
|
||||
*(_ptr + sizeof(T) - i - 1) = _temp;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_big_endian()
|
||||
{
|
||||
return (*((short*)"AB") == 0x4243);
|
||||
}
|
||||
|
||||
inline bool is_little_endian()
|
||||
{
|
||||
return (*((short*)"AB") != 0x4243);
|
||||
}
|
||||
|
||||
inline bool is_endian(const Endian& endian)
|
||||
{
|
||||
return
|
||||
(endian == Endian::Little && is_little_endian()) ||
|
||||
(endian == Endian::Big && is_big_endian());
|
||||
}
|
||||
}
|
|
@ -5,11 +5,6 @@
|
|||
|
||||
using namespace Blah;
|
||||
|
||||
Stream::Stream()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int64_t Stream::pipe(Stream& stream, int64_t length)
|
||||
{
|
||||
const int BUFFER_LENGTH = 4096;
|
||||
|
@ -32,91 +27,4 @@ int64_t Stream::pipe(Stream& stream, int64_t length)
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String Stream::read_line()
|
||||
{
|
||||
String string;
|
||||
read_line(string);
|
||||
return string;
|
||||
}
|
||||
|
||||
int64_t Stream::read_line(String& writeTo)
|
||||
{
|
||||
const int bufferSize = 512;
|
||||
char buffer[bufferSize];
|
||||
|
||||
int64_t pos = position();
|
||||
int64_t length = 0;
|
||||
int64_t count = 0;
|
||||
bool hit = false;
|
||||
|
||||
// read chunk-by-chunk
|
||||
do
|
||||
{
|
||||
count = (int)read(buffer, bufferSize);
|
||||
pos += count;
|
||||
|
||||
// check for a newline
|
||||
int64_t end = count;
|
||||
for (int n = 0; n < count; n++)
|
||||
if (buffer[n] == '\n' || buffer[n] == '\r')
|
||||
{
|
||||
hit = true;
|
||||
end = n;
|
||||
|
||||
// skip to the end of the line for future reading
|
||||
int64_t lineEnd = pos - count + end + 1;
|
||||
|
||||
// there might be a trailing '\n'
|
||||
if (buffer[n] == '\r')
|
||||
{
|
||||
if (end < count && buffer[n + 1] == '\n')
|
||||
{
|
||||
lineEnd++;
|
||||
}
|
||||
// our buffer aligned perfectly ..... :/
|
||||
else if (count == bufferSize && end == count)
|
||||
{
|
||||
char ch;
|
||||
if (read(&ch, 1) != 0 && ch == '\n')
|
||||
lineEnd++;
|
||||
}
|
||||
}
|
||||
|
||||
seek(lineEnd);
|
||||
break;
|
||||
}
|
||||
|
||||
// copy to string
|
||||
writeTo.set_length((int)(length + end));
|
||||
memcpy(writeTo.cstr() + length, buffer, (size_t)end);
|
||||
*(writeTo.cstr() + length + end) = '\0';
|
||||
|
||||
// increment length
|
||||
length += end;
|
||||
|
||||
} while (!hit && count >= bufferSize);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
String Stream::read_string(int length)
|
||||
{
|
||||
if (length >= 0)
|
||||
{
|
||||
String str;
|
||||
str.set_length(length);
|
||||
read_into(str.cstr(), length);
|
||||
str[length] = '\0';
|
||||
return str;
|
||||
}
|
||||
else
|
||||
{
|
||||
String str;
|
||||
char next;
|
||||
while (read_into(&next, 1) && next != '\0')
|
||||
str.append(next);
|
||||
return str;
|
||||
}
|
||||
}
|
|
@ -1,29 +1,14 @@
|
|||
#pragma once
|
||||
#include <inttypes.h>
|
||||
#include <blah/containers/str.h>
|
||||
|
||||
#define BLAH_SWAP_ENDIAN(value, type) \
|
||||
for (int i = 0; i < sizeof(type) / 2; i ++) { \
|
||||
uint8_t* _ptr = (uint8_t*)&value;\
|
||||
uint8_t _temp = *(_ptr + i); \
|
||||
*(_ptr + i) = *(_ptr + sizeof(type) - i - 1); \
|
||||
*(_ptr + sizeof(type) - i - 1) = _temp; \
|
||||
}
|
||||
|
||||
#define BLAH_BIG_ENDIAN (*((short*)"AB") == 0x4243)
|
||||
#include <blah/streams/endian.h>
|
||||
|
||||
namespace Blah
|
||||
{
|
||||
enum class Endian
|
||||
{
|
||||
Little,
|
||||
Big
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
Stream() = default;
|
||||
Stream(const Stream&) = delete;
|
||||
Stream& operator=(const Stream&) = delete;
|
||||
|
||||
|
@ -53,44 +38,92 @@ namespace Blah
|
|||
// pipes the contents of this tream to another stream
|
||||
int64_t pipe(Stream& to, int64_t length);
|
||||
|
||||
// reads a single line from this stream (up until \r or \n)
|
||||
String read_line();
|
||||
|
||||
// reada a single line from this stream, to the given string (up until \r or \n)
|
||||
int64_t read_line(String& writeTo);
|
||||
|
||||
// reads a string of a given length, or until a null terminator if -1
|
||||
String read_string(int length = -1);
|
||||
|
||||
// reads the amount of bytes into the given buffer, and returns the amount read
|
||||
int64_t read(void* buffer, int64_t length) { return read_into(buffer, length); }
|
||||
|
||||
template<class T>
|
||||
T read() { return read<T>(Endian::Little); }
|
||||
// reads a string. if length < 0, assumes null-terminated
|
||||
String read_string(int length = -1)
|
||||
{
|
||||
String result;
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
char next;
|
||||
while (read(&next, 1) && next != '\0')
|
||||
result.append(next);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.set_length(length);
|
||||
read_into(result.cstr(), length);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String read_line()
|
||||
{
|
||||
String result;
|
||||
|
||||
char next;
|
||||
while (read(&next, 1) && next != '\n' && next != '\0')
|
||||
result.append(next);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// reads a number
|
||||
template<class T>
|
||||
T read()
|
||||
{
|
||||
return read<T>(Endian::Little);
|
||||
}
|
||||
|
||||
// reads a number
|
||||
template<class T>
|
||||
T read(Endian endian)
|
||||
{
|
||||
T value;
|
||||
read(&value, sizeof(T));
|
||||
|
||||
if ((endian == Endian::Little && BLAH_BIG_ENDIAN) || (endian == Endian::Big && !BLAH_BIG_ENDIAN))
|
||||
BLAH_SWAP_ENDIAN(value, T);
|
||||
|
||||
return value;
|
||||
T result;
|
||||
read(&result, sizeof(T));
|
||||
if (!Blah::is_endian(endian))
|
||||
Blah::swap_endian(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t write(const void* buffer, int64_t length) { return write_from(buffer, length); }
|
||||
// writes the amount of bytes to the stream from the given buffer, and returns the amount written
|
||||
int64_t write(const void* buffer, int64_t length)
|
||||
{
|
||||
return write_from(buffer, length);
|
||||
}
|
||||
|
||||
// writes a null-terminated string, and returns the amount written
|
||||
int64_t write_cstr(const Str& string)
|
||||
{
|
||||
return write(string.cstr(), string.length() + 1);
|
||||
}
|
||||
|
||||
// writes a null-terminated string, and returns the amount written
|
||||
int64_t write_cstr(const char* cstr)
|
||||
{
|
||||
return write(cstr, strlen(cstr) + 1);
|
||||
}
|
||||
|
||||
// writes a number
|
||||
template<class T>
|
||||
int64_t write(const T& value) { return write<T>(value, Endian::Little); }
|
||||
int64_t write(const T& value)
|
||||
{
|
||||
return write<T>(value, Endian::Little);
|
||||
}
|
||||
|
||||
// writes a number
|
||||
template<class T>
|
||||
int64_t write(const T& value, Endian endian)
|
||||
{
|
||||
T writing = value;
|
||||
if ((endian == Endian::Little && BLAH_BIG_ENDIAN) || (endian == Endian::Big && !BLAH_BIG_ENDIAN))
|
||||
BLAH_SWAP_ENDIAN(writing, T);
|
||||
|
||||
if (!Blah::is_endian(endian))
|
||||
Blah::swap_endian(&writing);
|
||||
|
||||
return write(&writing, sizeof(T));
|
||||
}
|
||||
|
||||
|
@ -100,7 +133,6 @@ namespace Blah
|
|||
|
||||
// writes from the stream from the given buffer, and returns the number of bytes written
|
||||
virtual int64_t write_from(const void* buffer, int64_t length) = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user