<commit_before>#ifndef AVALON_PHYSICS_BOX2DCONTAINER_H
#define AVALON_PHYSICS_BOX2DCONTAINER_H

#include "Box2D/Box2D.h"
#include "cocos2d.h"

class B2DebugDrawLayer;

namespace avalon {
namespace physics {

class Box2dContainer : public cocos2d::Node
{
private:
    using NodeId = int*;

    NodeId lastNodeId = nullptr;
    B2DebugDrawLayer* debugLayer = nullptr;
    std::unordered_map<NodeId, const cocos2d::Node*> idToNode;
    std::unordered_map<const cocos2d::Node*, NodeId> nodeToId;

    NodeId generateId();

public:
    std::shared_ptr<b2World> world;
    float32 timeStep = 1.0f / 60.0f;
    int32 velocityIterations = 8;
    int32 positionIterations = 3;
    float pixelsInMeter = 32; // todo: read only

    CREATE_FUNC(Box2dContainer);
    bool init() override;

    void update(float delta) override;
    void enableDebugDraw(const bool enable);

    b2Body* createBody(const b2BodyDef& bodyDef);
    b2Body* createBody(const b2BodyDef& bodyDef, const cocos2d::Node& node);

    void removeNode(const cocos2d::Node& node);

    template<typename T>
    T* getNode(const b2Fixture& fixture)
    {
        auto body = fixture.GetBody();
        if (!body) {
            throw new std::invalid_argument("Fixture is not attached to a body yet");
        }

        return getNode<T>(body);
    }

    template<typename T>
    T* getNode(const b2Body& body)
    {
        auto userDataPtr = body.GetUserData();<commit_msg>move magic number into own constant<commit_after>#ifndef AVALON_PHYSICS_BOX2DCONTAINER_H
#define AVALON_PHYSICS_BOX2DCONTAINER_H

#include "Box2D/Box2D.h"
#include "cocos2d.h"

class B2DebugDrawLayer;

namespace avalon {
namespace physics {

class Box2dContainer : public cocos2d::Node
{
private:
    using NodeId = int*;

    NodeId lastNodeId = nullptr;
    B2DebugDrawLayer* debugLayer = nullptr;
    std::unordered_map<NodeId, const cocos2d::Node*> idToNode;
    std::unordered_map<const cocos2d::Node*, NodeId> nodeToId;

    NodeId generateId();

public:
    constexpr static float DEFAULT_PIXEL_IN_METER = 32;
    
    std::shared_ptr<b2World> world;
    float32 timeStep = 1.0f / 60.0f;
    int32 velocityIterations = 8;
    int32 positionIterations = 3;
    float pixelsInMeter = DEFAULT_PIXEL_IN_METER; // todo: read only

    CREATE_FUNC(Box2dContainer);
    bool init() override;

    void update(float delta) override;
    void enableDebugDraw(const bool enable);

    b2Body* createBody(const b2BodyDef& bodyDef);
    b2Body* createBody(const b2BodyDef& bodyDef, const cocos2d::Node& node);

    void removeNode(const cocos2d::Node& node);

    template<typename T>
    T* getNode(const b2Fixture& fixture)
    {
        auto body = fixture.GetBody();
        if (!body) {
            throw new std::invalid_argument("Fixture is not attached to a body yet");
        }

        return getNode<T>(body);
    }

    template<typename T>
    T* getNode(const b2Body& body)
    {
        auto userDataPtr = body.GetUserData();
{'fraction_non_alphanumeric': 0.0983496126641967, 'fraction_numerical': 0.0242505894240485, 'mean_word_length': 3.618973561430793, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, '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': '1532078', 'n_tokens_mistral': 1050, 'n_tokens_neox': 999, 'n_words': 241}