<commit_before>//
//  yas_ui_metal_render_encoder.mm
//

#include "yas_objc_ptr.h"
#include "yas_ui_mesh.h"
#include "yas_ui_metal_encode_info.h"
#include "yas_ui_metal_render_encoder.h"
#include "yas_ui_metal_system.h"
#include "yas_ui_renderer.h"

using namespace yas;

struct ui::metal_render_encoder::impl : base::impl, render_encodable::impl {
    std::deque<ui::metal_encode_info> &all_encode_infos() {
        return this->_all_encode_infos;
    }

    void push_encode_info(ui::metal_encode_info info) {
        this->_all_encode_infos.push_front(info);
        this->_current_encode_infos.push_front(info);
    }

    void pop_encode_info() {
        this->_current_encode_infos.pop_front();
    }

    ui::metal_encode_info &current_encode_info() {
        if (this->_current_encode_infos.size() > 0) {
            return this->_current_encode_infos.front();
        } else {
            static ui::metal_encode_info _null_info{nullptr};
            return _null_info;
        }
    }

    void push_back_mesh(ui::mesh &&mesh) override {
        if (auto &info = this->current_encode_info()) {
            info.push_back_mesh(std::move(mesh));
        }
    }

    encode_result_t encode(ui::metal_system &metal_system, id<MTLCommandBuffer> const commandBuffer) {
        metal_system.renderable().prepare_uniforms_buffer(_mesh_count_in_all_encode_infos());

        std::size_t encoded_count = 0;

        for (auto &metal_encode_info : this->_all_encode_infos) {
            auto renderPassDesc = metal_encode_info.renderPassDescriptor();
            auto render_encoder = make_objc_ptr<id<MTLRenderCommandEncoder>>([&commandBuffer, &renderPassDesc]() {
                return [commandBuffer renderCommandEncoderWithDescriptor:renderPassDesc];
            });
            auto renderEncoder = render_encoder.object();

            for (auto &mesh : metal_encode_info.meshes()) {
                auto &mesh_renderable = mesh.renderable();
                if (mesh_renderable.pre_render()) {
                    metal_system.renderable().mesh_encode(mesh, renderEncoder, metal_encode_info);

                    ++encoded_count;
                }
            }

            [renderEncoder endEncoding];
        }

        return encode_result_t{.encoded_mesh_count = encoded_count};
    }

   private:
    std::deque<ui::metal_encode_info> _all_encode_infos;
    std::deque<ui::metal_encode_info> _current_encode_infos;

    uint32_t _mesh_count_in_all_encode_infos() const {
        uint32_t count = 0;
        for (auto &metal_encode_info : this->this->_all_encode_infos) {
            count += metal_encode_info.meshes().size();
        }
        return count;
    }<commit_msg>fix metal_render_encoder<commit_after>//
//  yas_ui_metal_render_encoder.mm
//

#include "yas_objc_ptr.h"
#include "yas_ui_mesh.h"
#include "yas_ui_metal_encode_info.h"
#include "yas_ui_metal_render_encoder.h"
#include "yas_ui_metal_system.h"
#include "yas_ui_renderer.h"

using namespace yas;

struct ui::metal_render_encoder::impl : base::impl, render_encodable::impl {
    std::deque<ui::metal_encode_info> &all_encode_infos() {
        return this->_all_encode_infos;
    }

    void push_encode_info(ui::metal_encode_info info) {
        this->_all_encode_infos.push_front(info);
        this->_current_encode_infos.push_front(info);
    }

    void pop_encode_info() {
        this->_current_encode_infos.pop_front();
    }

    ui::metal_encode_info &current_encode_info() {
        if (this->_current_encode_infos.size() > 0) {
            return this->_current_encode_infos.front();
        } else {
            static ui::metal_encode_info _null_info{nullptr};
            return _null_info;
        }
    }

    void push_back_mesh(ui::mesh &&mesh) override {
        if (auto &info = this->current_encode_info()) {
            info.push_back_mesh(std::move(mesh));
        }
    }

    encode_result_t encode(ui::metal_system &metal_system, id<MTLCommandBuffer> const commandBuffer) {
        metal_system.renderable().prepare_uniforms_buffer(_mesh_count_in_all_encode_infos());

        std::size_t encoded_count = 0;

        for (auto &metal_encode_info : this->_all_encode_infos) {
            auto renderPassDesc = metal_encode_info.renderPassDescriptor();
            auto render_encoder = make_objc_ptr<id<MTLRenderCommandEncoder>>([&commandBuffer, &renderPassDesc]() {
                return [commandBuffer renderCommandEncoderWithDescriptor:renderPassDesc];
            });
            auto renderEncoder = render_encoder.object();

            for (auto &mesh : metal_encode_info.meshes()) {
                auto &mesh_renderable = mesh.renderable();
                if (mesh_renderable.pre_render()) {
                    metal_system.renderable().mesh_encode(mesh, renderEncoder, metal_encode_info);

                    ++encoded_count;
                }
            }

            [renderEncoder endEncoding];
        }

        return encode_result_t{.encoded_mesh_count = encoded_count};
    }

   private:
    std::deque<ui::metal_encode_info> _all_encode_infos;
    std::deque<ui::metal_encode_info> _current_encode_infos;

    uint32_t _mesh_count_in_all_encode_infos() const {
        uint32_t count = 0;
        for (auto &metal_encode_info : this->_all_encode_infos) {
            count += metal_encode_info.meshes().size();
        }
        return count;
    }
{'fraction_non_alphanumeric': 0.10729534063486171, 'fraction_numerical': 0.0025988490811212177, 'mean_word_length': 2.9472527472527474, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 36, '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': '1765408', 'n_tokens_mistral': 1762, 'n_tokens_neox': 1682, 'n_words': 239}