1

I am trying to pass a custom c++ object reference to a simple chai script so that the chai script can eventually read/access/call public variables & methods.

I'm not certain if this is even possible, nor if once it is passed inside of the chai script function if it will have access to the classes values without having the class previously defined within chai... Any insight would be very helpful, as I can't find a specific section in the documentation relating to this.

Here is a very basic implementation.

ChaiScript.h

#pragma once

#include "ChaiScript\include\chaiscript\chaiscript.hpp"

class ChaiScript
{
public:
   explicit ChaiScript(
      const std::string& script_name);

   ~ChaiScript();

   chaiscript::ChaiScript chai;

private:
};

ChaiScript.cpp

#include "ChaiScript.h"

ChaiScript::ChaiScript(
   const std::string& script_name)
{
   chai.add(chaiscript::vector_conversion<std::vector<int>>());

   chai.eval_file(script_name);
}

ChaiScript::~ChaiScript()
{

}

SampleClass.h

#pragma once
#include <string>

class SampleClass
{
public:
   SampleClass(
      const int id,
      const int x,
      const int y,
      const std::string& name);

   const int m_id;
   int m_x;
   int m_y;
   std::string m_name;

private:

   // Disable copying as we don't want to make a copy each time we pass the class to chai...
   SampleClass();
   SampleClass(const SampleClass& rhs);
   SampleClass& operator=(const SampleClass& rhs);
};

SampleClass.cpp

#include "SampleClass.h"

SampleClass::SampleClass(
   const int id,
   const int x,
   const int y,
   const std::string& name) : 
   m_id(id),
   m_x(x),
   m_y(y),
   m_name(name)
{

}

main.cpp

#include "ChaiScript.h"
#include "SampleClass.h"

int main()
{
   SampleClass* sample_class = new SampleClass(0, 1, 2, "Test");
   ChaiScript* script = new ChaiScript("Scripts\\SampleScript.chai");

   // This line is where I start to need help as it does not compile.
   script->chai.eval<std::function<void(&SampleClass)>>("ReceiveSampleClass")(&sample_class);

   system("pause");
   return 0;
}

SampleScript.chai

def ReceiveSampleClass(SampleClass sample)
{
    var result = sample.m_x + sample.m_y;
    print("2+2=" + to_string(result));
}
Rick
  • 97
  • 1
  • 8

1 Answers1

1

After a bit more searching, I found out how to do this!

I've changed ChaiScript.cpp to the following:

#include "ChaiScript.h"
#include "SampleClass.h"

ChaiScript::ChaiScript(
   const std::string& script_name)
{
   chai.add(chaiscript::vector_conversion<std::vector<int>>());

   chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());

   chaiscript::utility::add_class<SampleClass>(*m,
      "SampleClass",
      { 
         chaiscript::constructor<SampleClass(const int id, const int x, const int y, const std::string & name)>() 
      },
      { 
         {chaiscript::fun(&SampleClass::m_x), "X"} 
      });

   chai.add(m);

   chai.eval_file(script_name);
}

ChaiScript::~ChaiScript()
{

}

My SampleScript.chai also changed to:

def ReceiveSampleClass(SampleClass sample)
{
    var result = sample.X;
    sample.X += 2;
    var result2 = sample.X;
    print("1) " + to_string(result));
    print("2) " + to_string(result2));
}

The process I was missing was adding the class to a module and adding that to chai script.

   chaiscript::ModulePtr m = chaiscript::ModulePtr(new chaiscript::Module());

   chaiscript::utility::add_class<SampleClass>(*m,
      "SampleClass",
      { 
         chaiscript::constructor<SampleClass(const int id, const int x, const int y, const std::string & name)>() 
      },
      { 
         {chaiscript::fun(&SampleClass::m_x), "X"} 
      });

   chai.add(m);
Rick
  • 97
  • 1
  • 8