<commit_before>#pragma once

#include "gl/Buffer.h"
#include "gl/State.h"
#include "gl/Texture.h"
#include "gl/Matrix.h"

#include <array>

namespace chr
{
  namespace gl
  {
    class Batch
    {
    public:
      Batch() = default;

      virtual void clear() = 0;
      virtual bool empty() const = 0;
      virtual void bind(ShaderProgram &shader) = 0;
    };

    template<int V = XYZ>
    class VertexBatch : public Batch
    {
    public:
      GLenum primitive = GL_TRIANGLES;
      Buffer<Vertex<V>> vertexBuffer;

      ShaderProgram shader;
      bool hasShader = false;

      glm::vec4 color;
      bool hasColor = false;

      glm::mat3 matrices3[1]; // XXX
      bool hasMatrix3[1] = { false }; // XXX

      glm::mat4 matrices4[3]; // XXX
      bool hasMatrix4[3] = { false, false, false }; // XXX

      Texture texture;
      bool hasTexture = false;

      VertexBatch()
      :
      Batch()
      {}

      VertexBatch(GLenum primitive)
      :
      primitive(primitive),
      Batch()
      {}

      VertexBatch(const Buffer<Vertex<V>> &vertexBuffer)
      :
      vertexBuffer(vertexBuffer),
      Batch()
      {}

      VertexBatch(GLenum primitive, const Buffer<Vertex<V>> &vertexBuffer)
      :
      primitive(primitive),
      vertexBuffer(vertexBuffer),
      Batch()
      {}

      // ---

      void clear() override
      {
        vertexBuffer.clear();
        vertexBuffer.requestUpload();
      }

      bool empty() const override
      {
        return vertexBuffer.empty();
      }

      void flush()
      {
        if (hasTexture)
        {
          texture.bind();
        }

        if (hasShader)
        {
          shader.bind();
          state::current.apply(shader);
          apply(shader);
          bind(shader);
        }
        else
        {
          apply(state::current->shader);
          bind(state::current->shader);
        }
      }

      inline std::vector<Vertex<V>>& vertices() const
      {
        return vertexBuffer->storage;
      }

      inline Vertex<V>& vertex(size_t i) const
      {
        return vertexBuffer->storage[i];
      }

      inline size_t vertexCount() const
      {
        return vertexBuffer->storage.size();
      }

      template<typename... Args>
      inline VertexBatch& addVertex(Args&&... args)
      {
        vertexBuffer->storage.emplace_back(std::forward<Args>(args)...);
        return *this;
      }

      template<typename... Args>
      inline VertexBatch& addVertices(Args&&... args)
      {
        for (Vertex<V>&& vertex : {args...})
        {
          vertexBuffer->storage.emplace_back(vertex);
        }

        return *this;
      }

      inline VertexBatch& addVertices(const std::vector<Vertex<V>> &vertices)
      {
        vertexBuffer->storage.insert(vertexBuffer->storage.end(), vertices.begin(), vertices.end());
        return *this;
      }

      template<typename... Args>
      inline VertexBatch& addTransformedVertices(const Matrix &matrix, Args&&... args)
      {
        for (Vertex<V>&& vertex : {args...})
        {
          vertexBuffer->storage.emplace_back(matrix.transformPoint(vertex));
        }

        return *this;
      }

      VertexBatch& setPrimitive(GLenum primitive)
      {
        this->primitive = primitive;
        return *this;
      }

      VertexBatch& setShader(const ShaderProgram &shader)
      {
        this->shader = shader;
        hasShader = true;
        return *this;
      }<commit_msg>CANCELLING gl::Batch::addTransformedVertices() -- NOT WORKING AS INTENDED<commit_after>#pragma once

#include "gl/Buffer.h"
#include "gl/State.h"
#include "gl/Texture.h"
#include "gl/Matrix.h"

#include <array>

namespace chr
{
  namespace gl
  {
    class Batch
    {
    public:
      Batch() = default;

      virtual void clear() = 0;
      virtual bool empty() const = 0;
      virtual void bind(ShaderProgram &shader) = 0;
    };

    template<int V = XYZ>
    class VertexBatch : public Batch
    {
    public:
      GLenum primitive = GL_TRIANGLES;
      Buffer<Vertex<V>> vertexBuffer;

      ShaderProgram shader;
      bool hasShader = false;

      glm::vec4 color;
      bool hasColor = false;

      glm::mat3 matrices3[1]; // XXX
      bool hasMatrix3[1] = { false }; // XXX

      glm::mat4 matrices4[3]; // XXX
      bool hasMatrix4[3] = { false, false, false }; // XXX

      Texture texture;
      bool hasTexture = false;

      VertexBatch()
      :
      Batch()
      {}

      VertexBatch(GLenum primitive)
      :
      primitive(primitive),
      Batch()
      {}

      VertexBatch(const Buffer<Vertex<V>> &vertexBuffer)
      :
      vertexBuffer(vertexBuffer),
      Batch()
      {}

      VertexBatch(GLenum primitive, const Buffer<Vertex<V>> &vertexBuffer)
      :
      primitive(primitive),
      vertexBuffer(vertexBuffer),
      Batch()
      {}

      // ---

      void clear() override
      {
        vertexBuffer.clear();
        vertexBuffer.requestUpload();
      }

      bool empty() const override
      {
        return vertexBuffer.empty();
      }

      void flush()
      {
        if (hasTexture)
        {
          texture.bind();
        }

        if (hasShader)
        {
          shader.bind();
          state::current.apply(shader);
          apply(shader);
          bind(shader);
        }
        else
        {
          apply(state::current->shader);
          bind(state::current->shader);
        }
      }

      inline std::vector<Vertex<V>>& vertices() const
      {
        return vertexBuffer->storage;
      }

      inline Vertex<V>& vertex(size_t i) const
      {
        return vertexBuffer->storage[i];
      }

      inline size_t vertexCount() const
      {
        return vertexBuffer->storage.size();
      }

      inline VertexBatch& addVertex(const Vertex<V> &vertex)
      {
        vertexBuffer->storage.push_back(vertex);
        return *this;
      }

      template<typename... Args>
      inline VertexBatch& addVertex(Args&&... args)
      {
        vertexBuffer->storage.emplace_back(std::forward<Args>(args)...);
        return *this;
      }

      template<typename... Args>
      inline VertexBatch& addVertices(Args&&... args)
      {
        for (Vertex<V>&& vertex : {args...})
        {
          vertexBuffer->storage.emplace_back(vertex);
        }

        return *this;
      }

      inline VertexBatch& addVertices(const std::vector<Vertex<V>> &vertices)
      {
        vertexBuffer->storage.insert(vertexBuffer->storage.end(), vertices.begin(), vertices.end());
        return *this;
      }

      VertexBatch& setPrimitive(GLenum primitive)
      {
        this->primitive = primitive;
        return *this;
      }

      VertexBatch& setShader(const ShaderProgram &shader)
      {
        this->shader = shader;
        hasShader = true;
        return *this;
      }
{'fraction_non_alphanumeric': 0.12432511308915803, 'fraction_numerical': 0.0040858018386108275, 'mean_word_length': 1.8546438983756768, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2053483', 'n_tokens_mistral': 2055, 'n_tokens_neox': 1987, 'n_words': 411}