Luabridge weak reference to LuaRef data - c++

Consider the following example:
function Process()
local Container=NewContainer()
Container:On(EventType.Add,function()
Container:DoSomething()
end)
-- Does not Garbage Collect
end
In luabridge, I store the function() as LuaRef which extends the lifetime for the Container and it will not be GCed because it's a RefCountedObjectPtr
Here is a workaround that I use to use a weak table which works, but it looks ugly:
function Process()
local Container=NewContainer()
local ParamsTable={ Container=Container }
setmetatable(ParamsTable, { __mode = 'k' })
Container:On(EventType.Add,function()
ParamsTable.Container:DoSomething()
end)
-- Garbage Collects fine
end
Is there any way to have a LuaRef that functions similar to this? Or maybe there is another workaround?

Here is the way I approached this problem:
Create a wrapper class around C++ luabridge class (If you have class Display.A() in C++, create class A() in Lua)
Store a weak table inside that wrapper class (self.WeakTable={} and setmetatable(self.WeakTable, { __mode = 'k' }))
In the weak table, reference self: (self.WeakTable.self=self)
Pass self.WeakTable to C++ and store in as LuaRef - this will gc
Create a wrapper function like so:
Container:On(EventType.Add,function(WeakTableParams)
WeakTableParams.self.Callback();
end)

Related

Python: passing local variable reference as string

I use an interactive interpreter for data analysis, so I tend to just define functions and call them when I need them. In this case, I would like to call some function:
def function(var):
do stuff
ax.plot(x, y)
blah
ax.set_title('var')
where var in the function call is ndarray and var in set_title is the reference of the ndarray.
I'm currently implementing this with
def function(var, varstring):
do stuff
ax.plot(x, y)
blah
ax.set_title(varstring)
where var is foo and varstring is just 'foo' - an example call:
module.function(foo, 'foo')
now, my function takes many more variables and it's unwieldy to duplicate everything over and over again, but I can't figure out how to just get var as 'var' .. any attempt to do so provides me with a string of the ndarray values.
If you're working in the interpreter, the variables are likely in the global scope. Thus, you can access them using var = globals()[varstring] and then pass in the string name into each function.
Note that an object (var) has no knowledge of its names (varstring) which is why the global name needs to be passed to the function rather than the object itself.
you have to define your function in this way:
def function(varstring):
var = globals()[varstring]
# do stuff with `var` variable
ax.plot(x, y)
ax.set_title(varstring)
and then call module.function('foo')

How to override KeyValuePair<TKey, TValue> in C#?

I want to override the default structure of KeyValuePair in C#, so that I can make a KeyValuePair to accept a 'var' types.
Something like this :
List<KeyValuePair<string, var>> kvpList = new List<KeyValuePair<string, var>>()
{
new KeyValuePair<string, var>("Key1", 000),
new KeyValuePair<string, var>("Key2", "value2"),
new KeyValuePair<string, var>("Key3", 25.45),
};
Even if its possible for dictionary, then also it will solve my problem.
You could use object as your type, and then cast to/from object to desired outcomes. However, it's important to note that this is very much the opposite of object oriented programming, and generally indicates an error in your design and architecture.
Hmm I am wondering if this might help you: To have a list as you want, it is really possible BUT the "var" type (as you named it) must be the same for all KeyValuePair instances. For having whatever type you must use object or dynamic (use Haney's answer).
So considering that you want a single type for all KeyValuePair instances, here is a solution:
Firstly, create this helper class:
public static class KeyValuePairExtentions
{
public static List<KeyValuePair<string, T>> GetNewListOfType<T>(Expression<Func<T>> type)
{
return new List<KeyValuePair<string, T>>();
}
public static void AddNewKeyValuePair<T>(this List<KeyValuePair<string, T>> #this, string key, T element)
{
#this.Add(new KeyValuePair<string, T>(key, element));
}
}
To consume these functions, here is an example:
var lst = KeyValuePairExtentions.GetNewListOfType(() => new {Id = default (int), Name = default (string)});
lst.AddNewKeyValuePair("test1", new {Id = 3, Name = "Keith"});
The ideea is to rely on the powerfull type inference feature that we have in C#.
Some notes:
1) if T is anonymous and you create a new instance of a list in an assembly and consume it in another assembly it is VERY possible that this will NOT work due to the fact that an anonymous type is compiled per assembly (in other words, if you have a variable var x = new { X = 3 } in an assembly and in another var y = new { X = 3 } then x.GetType () != y.GeTType () but in the same assembly types are the same.)
2) If you are wondering whether an instance it's created or not by calling GetNewListOfType, the answer is NO because it is an expression tree function and the function is not even compiled. Even with a Func will work because I am not calling the function in my code. I am using the function just for type inference.

How do I get a custom element definition without instantiating it?

After looking at the custom element spec, it's not immediately obvious how I get a reference to a custom element definition without first instantiating it (which can be problematic). Is there a way to directly reference a custom element's prototype?
More concretely, if I have:
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() { // some heavy operation };
document.registerElement('x-foo', {prototype: proto});
At some point later, I would love to reference the prototype with something like:
// wish
var XFoo = document.getElementDefinition('x-foo');
But instead the only way I've come up with is:
// reality
var XFoo = document.createElement('x-foo').__proto__;
This is especially problematic when trying to write tests against heavy components - as there's no way to stub out the heavy behavior (with something like XFoo.createdCallback = // stub; before the original method is actually called.
If you have reference to the constructor of the custom element, you can use it to access the prototype.
var XFoo = document.registerElement('x-foo', {prototype: proto});
XFoo.prototype // this will give u access to the prototype object.
there's no way to stub out the heavy behavior
Use a function reference rather than an anonymous function:
proto.createdCallback = model.foo;
define it:
var model = {};
model.foo = function(){/*some heavy operation*/};
then stub it by redefining it:
var XModel = {};
XModel.foo = function(){/*stub*/};
and reference it in the test:
XFoo.createdCallback = XModel.foo;
References
AOP Aspect of JavaScript
AJAX Interception
Intro to Aspect Oriented Programming

Lua/Luabind: Objects constructed by objects remain allocated

I have a simple Lua script
function TestFunction(Id)
local Factory = TestParent();
local ChildDirect = TestChild("DirectCall");
local ChildFactory1 = Factory:CreateChild("Factory1");
local ChildFactory2 = Factory:CreateChild("Factory2");
result = Ret()
return result
end
that uses two C++ exposed objects (trough luabind)
void TestParent::RegisterToLua(lua_State* lua)
{
// Export our class with LuaBind
luabind::module(lua)
[
luabind::class_<TestParent>("TestParent")
.def(luabind::constructor<>())
.def("CreateChild", &TestParent::CreateChild)
];
}
void TestChild::RegisterToLua(lua_State* lua)
{
// Export our class with LuaBind
luabind::module(lua)
[
luabind::class_<TestChild>("TestChild")
.def(luabind::constructor<std::string>())
.def("GetValue", &TestChild::GetValue)
];
}
I call the function
luabind::object obj = luabind::call_function< luabind::object >(LuaState, "TestFunction", IdParam);
if ( obj.is_valid() )
{
....
}
lua_gc(LuaState, LUA_GCCOLLECT, 0);
During lua_gc call only Factory and ChildDirect objects are destroyed. ChildFactory1 and ChildFactory2 remains allocated. The lua stack remains balanced (has same value - 5 - some tables ) after the luabind::call_function.
What is the problem ? The objects created by Factory remain somehow referenced ? By who ?
CreateChild body is
TestChild* TestParent::CreateChild(std::string strname)
{
return new TestChild(strname);
}
The ownership of the new constructed object should be taken by lua object and destroyed if ChildFactory1 or ChildFactory2 is nil-ed or out of scope.
adopt: Used to transfer ownership across language boundaries.
module(L)
[
def("create", &create, adopt(result))
];
You should return a smart pointer (i.e. a boost::shared_ptr) from your factory.
see: LuaBind Documentation # smart pointer
and a discussion in the LuaBridge docu

Can I use a C++ Class Instance as an Objective-C++ id?

In connecting my C++ data model to my Cocoa table column UI, I'm wondering if I can provide the a C++ class instance at the id (identifier) to initWithIdentifier
// what magic needs to occur to create an id from a CPP class?
id someIDMadeFromAClassInstance = a_ptr_to_a_cpp_class_instance;
NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];
The whole point of this is so that when the NSTable's datasource method objectValueForTableColumn gets called, I can retrieve the id and somehow convert if back to a valid C++ class instance:
id columnIdentifer = [aTableColumn identifier];
MyCPPClass* pAValidClass = [someMagicOnTheID columnIdentifer];
pAValidClass->AClassMethod();
I'm guessing there's a more traditional method of doing this, but I wanted to simplify the connection between the Cocoa UI and a pure C++ model.
A C++ object pointer cannot be stored in an id type variable. In Objective-C, id is a pointer to an Objective-C object of unknown type. Since a C++ object is not an Objective-C object, it is not safe to store the pointer to a C++ object in an id.
The solution is to add a property to your Objective-C class that will store a C++ object pointer. If you must use an id, you could make an Objective-C class that wraps a property that stores the C++ object pointer, for example:
#interface MyCPPClassWrapper : NSObject
#property (nonatomic, assign) MyCPPClass *myCPPClass;
#end
// ...
MyCPPClassWrapper *wrapper = [[MyCPPClassWrapper alloc] initWithMyCPPClass:myCPPClass];
// Hand wrapper off to your NSTable
Take a look at NSValue as well. It provides a storage mechanism for C-style pointers. For NSValue, you could do something like this:
NSValue *someIDMadeFromAClassInstance = [NSValue valueWithPointer:a_ptr_to_a_cpp_class_instance];
NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];
// ...
NSValue *columnIdentifer = (NSValue *)[aTableColumn identifier];
MyCPPClass* pAValidClass = (MyCPPClass *)[columnIdentifer pointerValue];
pAValidClass->AClassMethod();