Unable to access object after I inject it


#1

I have a number of instances of the same class. I want to be able to use the same method on all of them. So, I wrote the following:

chai.add(chaiscript::fun(static_cast<void (Foo::*)(int, float)>(&Foo::setParameter)), “setParameter”); // add method
chai.add(chaiscript::var(std::ref(ap)), “Filt”); // add object

No errors adding them but when I try to invoke a call, e.g.

Filt.setParameter(3, 0.7);

I get the error, Script error in script:Error: “Can not find object: Filt” during evaluation at (EVAL 30, 10)

What am I doing wrong, please?

Thanks,


#2

I’m guessing there’s a piece of info missing here, like perhaps you are calling

Filt.setParameter(3,0.7);

From inside of another function? When you are inside of a function you can only see 3 things:

  1. Explicitly passed parameters
  2. Other functions
  3. Global values

So, you either need to pass your ‘Filt’ object around, or you want to do:

chai.add_global(chaiscript::var(std::ref(ap)), "Filt"); // add global object.

-Jason


#3

Yeah, you’re absolutely right. Thank you. However, I think this opened up a different can of worms. Although the method name is the same, the objects are part of a hierarchy and the methods are virtual.
I’m getting a crash everytime I invoke that method and I suspect (hard to tell from the ADT tree) that the base method is being called, and there’s no such implementation for the base.


#4

virtual methods and base class hierarchies are well supported. All you should need to do is register the base class version of the method, then use chaiscript::base_class to tell chai about the relationship.

example:


#5

Again, thanks for the quick response — had to read that code in github. If I am understanding correctly, I have to use that base_class template to define EVERY relationship between parents and children?
If I have 4 classes in a strict hierarchy Base, D1, D2, D3 (D2 inherits from D1, D3 from D2, etc) do I now have to define the relationship between every possible combination, i.e. <Base, D1>, <Base, D2>, <Base, D3>, <D1, D2> <D1, D3>, <D2, D3> ?
If so that sounds like combinatoric hell as the hierarchy grows.

Cheers,
D


#6

You are correct that I do not do automatic chaining.

However I think you are over-thinking the issue. You probably don’t care about every relationship.

Just do:

base_class<Base, D1>()
base_class<Base, D2>()
base_class<Base, D3>()
base_class<Base, D4>()

This would make each derived convertible back to base, but not between each other.


#7

Unfortunately, some of the classes in the hierarchy are hidden (i.e. defined in C++ implementation files, not headers) so I can’t actually references the ones I need.
(Throwing in forward declarations of those classes just results in the error "No matching function for call to ‘base_class’)

I might have to give up on this concept and just hardcode names to specific instances.

Cheers,
D


#8

I’m going to try setting up a “forwarder” class instead — (I forget the design pattern name for this (Proxy, maybe), it has been too long) but keeping instances of those around might be a worthwhile workaround. Figured I’d mention it in case anybody else runs into this kind of thing.


#9

ChaiScript <-> C++ is excellent for passing function objects around. Create them in script, create them in C++, doesn’t matter. Give you a nice level of abstraction. Probably similar to what you are implementing. Something to consider.

-Jason


#10

I’m already convinced that under the covers chaiscript can do what I need and have already created some very useful userscripts for our system. However, I’m seriously considering putting together a simpler “language” for users and using a tool that would spit out chaiscript, either by quickly hand-rolling a recursive descent parser or using something like ANTLR (downside being that I’d have to include a Java app with the product). The reason for doing this is because I would like to be able to write in the style

On ReceivedNoteEvent B3 note velocity
End

which makes it clear that this is a callback function and then that would get translated into something like

def B3_ReceivedNoteEvent(int note, int velocity)
{
}

If I go down that route then I’ll never actually need to expose objects because my C++ code will automatically inject the appropriate chaiscript function directly, i.e. chai.add( …, “B3_ReceivedNoteEvent”) associated with an internal object called B3