<commit_before>#pragma once

#include "vboMesh.h"

template<class T>
class TypedMesh : public VboMesh {

public:
    
    TypedMesh(std::shared_ptr<VertexLayout> _vertexLayout, GLenum _drawMode, GLenum _hint = GL_STATIC_DRAW)
        : VboMesh(_vertexLayout, _drawMode, _hint) {};

    void addVertices(std::vector<T>&& _vertices,
                     std::vector<int>&& _indices) {
        vertices.push_back(_vertices);
        indices.push_back(_indices);

        m_nVertices += _vertices.size();
        m_nIndices += _indices.size();
    }

    virtual void compileVertexBuffer() override {
        compile(vertices, indices);
    }
    
    /*
     * Update _nVerts vertices in the mesh with the new T value _newVertexValue starting after 
     * _byteOffset in the mesh vertex data memory
     */
    void updateVertices(GLintptr _byteOffset, unsigned int _nVerts, const T& _newVertexValue);
    
    /*
     * Update _nVerts vertices in the mesh with the new attribute A _newAttributeValue starting 
     * after _byteOffset in the mesh vertex data memory
     */
    template<class A>
    void updateAttribute(GLintptr _byteOffset, unsigned int _nVerts, const A& _newAttributeValue) {
        if (!m_isCompiled) {
            return;
        }
        
        size_t aSize = sizeof(A);
        size_t tSize = sizeof(T);
        
        // update the vertices attributes
        for (int i = 0; i < _nVerts; ++i) {
            std::memcpy(m_glVertexData + _byteOffset + i * tSize, &_newAttributeValue, aSize);
        }
        
        setDirty(_byteOffset + aSize, _nVerts * tSize + aSize);
    }

protected:
    
    void setDirty(GLintptr _byteOffset, GLsizei _byteSize);
    
    std::vector<std::vector<T>> vertices;
    std::vector<std::vector<int>> indices;
    
};

template<class T>
void TypedMesh<T>::setDirty(GLintptr _byteOffset, GLsizei _byteSize) {
    
    // not dirty at all, init the dirtyness of the buffer
    if(!m_dirty) {
        m_dirtySize = _byteSize;
        m_dirtyOffset = _byteOffset;
        m_dirty = true;
    } else {
        // distance in bytes
        long dBytes = std::abs(_byteOffset - m_dirtyOffset);
        long newEnd = _byteOffset + _byteSize;
        long oldEnd = m_dirtySize + m_dirtyOffset;
        
        if(_byteOffset < m_dirtyOffset) {
            // update before the old buffer offset (left part of the buffer)
            m_dirtyOffset = _byteOffset;
            
            // merge sizes
            if(newEnd > oldEnd) {
                m_dirtySize = _byteSize;
            } else {
                m_dirtySize += dBytes;
            }
            
            m_dirty = true;
        } else if(newEnd > oldEnd) {
            // update starting after the old buffer offset (right part of the buffer)
            m_dirtySize = dBytes + _byteSize;
            m_dirty = true;
        }
    }
}

template<class T>
void TypedMesh<T>::updateVertices(GLintptr _byteOffset, unsigned int _nVerts, const T& _newVertexValue) {
    if (!m_isCompiled) {
        return;
    }
    
    size_t tSize = sizeof(T);
    <commit_msg>warning when wrong usage provided to vbo & use of gl types<commit_after>#pragma once

#include "vboMesh.h"

template<class T>
class TypedMesh : public VboMesh {

public:
    
    TypedMesh(std::shared_ptr<VertexLayout> _vertexLayout, GLenum _drawMode, GLenum _hint = GL_STATIC_DRAW)
        : VboMesh(_vertexLayout, _drawMode, _hint) {};

    void addVertices(std::vector<T>&& _vertices,
                     std::vector<int>&& _indices) {
        vertices.push_back(_vertices);
        indices.push_back(_indices);

        m_nVertices += _vertices.size();
        m_nIndices += _indices.size();
    }

    virtual void compileVertexBuffer() override {
        compile(vertices, indices);
    }
    
    /*
     * Update _nVerts vertices in the mesh with the new T value _newVertexValue starting after 
     * _byteOffset in the mesh vertex data memory
     */
    void updateVertices(GLintptr _byteOffset, unsigned int _nVerts, const T& _newVertexValue);
    
    /*
     * Update _nVerts vertices in the mesh with the new attribute A _newAttributeValue starting 
     * after _byteOffset in the mesh vertex data memory
     */
    template<class A>
    void updateAttribute(GLintptr _byteOffset, unsigned int _nVerts, const A& _newAttributeValue) {
        if (!m_isCompiled) {
            return;
        }
        
        if (m_hint == GL_STATIC_DRAW) {
            logMsg("WARNING: wrong usage hint provided to the Vbo\n");
        }
        
        size_t aSize = sizeof(A);
        size_t tSize = sizeof(T);
        
        // update the vertices attributes
        for (int i = 0; i < _nVerts; ++i) {
            std::memcpy(m_glVertexData + _byteOffset + i * tSize, &_newAttributeValue, aSize);
        }
        
        setDirty(_byteOffset + aSize, _nVerts * tSize + aSize);
    }

protected:
    
    void setDirty(GLintptr _byteOffset, GLsizei _byteSize);
    
    std::vector<std::vector<T>> vertices;
    std::vector<std::vector<int>> indices;
    
};

template<class T>
void TypedMesh<T>::setDirty(GLintptr _byteOffset, GLsizei _byteSize) {
    
    // not dirty at all, init the dirtyness of the buffer
    if (!m_dirty) {
        
        m_dirtySize = _byteSize;
        m_dirtyOffset = _byteOffset;
        m_dirty = true;
        
    } else {
        GLsizei dBytes = std::abs(_byteOffset - m_dirtyOffset); // distance in bytes
        GLintptr nOff = _byteOffset + _byteSize; // new offset
        GLintptr pOff = m_dirtySize + m_dirtyOffset; // previous offset
        
        if (_byteOffset < m_dirtyOffset) { // left part of the buffer
            
            // update before the old buffer offset
            m_dirtyOffset = _byteOffset;
            
            // merge sizes
            if (nOff > pOff) {
                m_dirtySize = _byteSize;
            } else {
                m_dirtySize += dBytes;
            }
            
            m_dirty = true;
            
        } else if (nOff > pOff) { // right part of the buffer
            
            // update starting after the old buffer offset
            m_dirtySize = dBytes + _byteSize;
            m_dirty = true;
        }
    }
    
}

template<class T>
void TypedMesh<T>::updateVertices(GLintptr _byteOffset, unsigned int _nVerts, const T& _newVertexValue) {
    if (!m_isCompiled) {
        return;
    }
    
    if (m_hint == GL_STATIC_DRAW) {
        logMsg("WARNING: wrong usage hint provided to the Vbo\n");
    }
    
    size_t tSize = sizeof(T);
    
{'fraction_non_alphanumeric': 0.08888550083854246, 'fraction_numerical': 0.0003049245311785333, 'mean_word_length': 2.0943396226415096, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, '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': '4194709', 'n_tokens_mistral': 2001, 'n_tokens_neox': 1982, 'n_words': 528}