<commit_before>#include "girl_x.h"
#include "lua_var_scope.h"
#include "../table/table.h"



namespace saki
{



GirlX::GirlX(Who who, std::string luaCode)
    : Girl(who, Girl::Id::CUSTOM)
{
    setupLuaGlobal();

    runInGirlEnv(luaCode);
}

GirlX::GirlX(const GirlX &copy)
    : Girl(copy)
{
    // TODO
    // support cloning Lua state to enable skills inside future vision
    // strategy:
    // - Copy everything reachable from the 'girldata' table
    // - Ignore metatables
    //     - Userdata metatables are generated by fixed steps
    // - Ignore coroutines
    // - Deep copy all GC object
    // - Smartize Objects whose lifetime managed by C++
    // - Copy C functions (i.e. pointers), deep copy their upvalues
    // - Copy Lua functions by lua_dump, deep copy their upvalues
    // - Type-switch userdatas, use C++ copy ctor to copy them
    // deep copy should detect cycle

//    setupLuaGlobal();
//    cloneLuaTable(mLua["girldata"], const_cast<GirlX &>(copy).mLua["girldata"]);
}

std::unique_ptr<Girl> GirlX::clone() const
{
    return std::make_unique<GirlX>(*this);
}

void GirlX::onDraw(const Table &table, Mount &mount, Who who, bool rinshan)
{
    sol::object cb = mGirlEnv["ondraw"];
    if (!cb.is<sol::function>())
        return;

    LuaVarScope scope(
        mGirlEnv,
        "game", &table,
        "mount", &mount,
        "who", who,
        "rinshan", rinshan
    );

    (void) scope;

    runInGirlEnv("ondraw()");
    popUpIfAny(table);
}

std::string GirlX::popUpStr() const
{
    std::ostringstream oss;
    oss << "Lua";
    oss << mErrStream.str();
    return oss.str();
}

void GirlX::onTableEvent(const Table &table, const TableEvent &event)
{
    if (event.type() == TableEvent::Type::TABLE_STARTED)
        popUpIfAny(table);
}

void GirlX::setupLuaGlobal()
{
    mLua.open_libraries();

    mLua.script(R"(
        girldata = {}
        girl = {
            math = math,
            table = table,
            string = string,
            pairs = pairs,
            ipairs = ipairs,
            print = function(...)
                for _, v in ipairs({...}) do
                    girl.printone(v)
                    girl.printone(" ")
                end
                girl.printone("\n")
            end,
            __index = function(t, k)
                return girldata[k]
            end,
            __newindex = function(t, k, v)
                girldata[k] = v<commit_msg>fix nil-ignored in lua print func<commit_after>#include "girl_x.h"
#include "lua_var_scope.h"
#include "../table/table.h"



namespace saki
{



GirlX::GirlX(Who who, std::string luaCode)
    : Girl(who, Girl::Id::CUSTOM)
{
    setupLuaGlobal();

    runInGirlEnv(luaCode);
}

GirlX::GirlX(const GirlX &copy)
    : Girl(copy)
{
    // TODO
    // support cloning Lua state to enable skills inside future vision
    // strategy:
    // - Copy everything reachable from the 'girldata' table
    // - Ignore metatables
    //     - Userdata metatables are generated by fixed steps
    // - Ignore coroutines
    // - Deep copy all GC object
    // - Smartize Objects whose lifetime managed by C++
    // - Copy C functions (i.e. pointers), deep copy their upvalues
    // - Copy Lua functions by lua_dump, deep copy their upvalues
    // - Type-switch userdatas, use C++ copy ctor to copy them
    // deep copy should detect cycle

//    setupLuaGlobal();
//    cloneLuaTable(mLua["girldata"], const_cast<GirlX &>(copy).mLua["girldata"]);
}

std::unique_ptr<Girl> GirlX::clone() const
{
    return std::make_unique<GirlX>(*this);
}

void GirlX::onDraw(const Table &table, Mount &mount, Who who, bool rinshan)
{
    sol::object cb = mGirlEnv["ondraw"];
    if (!cb.is<sol::function>())
        return;

    LuaVarScope scope(
        mGirlEnv,
        "game", &table,
        "mount", &mount,
        "who", who,
        "rinshan", rinshan
    );

    (void) scope;

    runInGirlEnv("ondraw()");
    popUpIfAny(table);
}

std::string GirlX::popUpStr() const
{
    std::ostringstream oss;
    oss << "Lua";
    oss << mErrStream.str();
    return oss.str();
}

void GirlX::onTableEvent(const Table &table, const TableEvent &event)
{
    if (event.type() == TableEvent::Type::TABLE_STARTED)
        popUpIfAny(table);
}

void GirlX::setupLuaGlobal()
{
    mLua.open_libraries();

    mLua.script(R"(
        girldata = {}
        girl = {
            math = math,
            table = table,
            string = string,
            pairs = pairs,
            ipairs = ipairs,
            print = function(...)
                local args = table.pack(...)
                for i = 1, args.n do
                    girl.printone(args[i])
                    girl.printone(" ")
                end
                girl.printone("\n")
            end,
            __index = function(t, k)
                return girldata[k]
            end,
            __newindex = function(t, k, v)
                girldata[k] = v
{'fraction_non_alphanumeric': 0.13482918940772184, 'fraction_numerical': 0.00020214271275520516, 'mean_word_length': 2.079029247044182, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 11, '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': '7169537', 'n_tokens_mistral': 1671, 'n_tokens_neox': 1581, 'n_words': 399}