besen icon indicating copy to clipboard operation
besen copied to clipboard

Calling object prototype functions does not work.

Open JernejL opened this issue 6 years ago • 3 comments

I'm really determined to use besen in my project, and am still working on my game with it and writing a tutorial for others to do so, but i have a odd issue which i cannot figure out how to do properly, but it's most likely a bug:

I have registered native object:

BesenInst.RegisterNativeObject('Actor', TActorInterface); The object has a property for OnCreate:

property OnCreate : TBESENObjectFunction read FOnCreate write FOnCreate; In Javascript i've created an additional function on class:

Actor.prototype.OnCreate = function(OtherPlayer, AIClass) {
	
	console.log('actor_stack pushing - Actor.OnCreate')
	actor_stack.push(self);
	
}

Inside the constructor, i am attempting to call this function:

procedure TActorInterface.ConstructObject(const ThisArgument: TBESENValue; Arguments: PPBESENValues; CountArguments: integer);

...

	if Assigned(FOnCreate) then begin

		TBESEN(BesenInst).GarbageCollector.Protect(OnCreate);

	    try

	        AResult.ValueType := bvtBOOLEAN;
		    OnCreate.Call(BESENObjectValue(OnCreate), @CallParams, 3, AResult);

	    except

	       on e: exception do HandleBesenException(e);

	    end;

		TBESEN(BesenInst).GarbageCollector.Unprotect(OnCreate);

	end; 

This however does not work as planned, it does seem to work if a function is added on an instance of class itself - but how do i call a prototype method added in javascript - Assigned(FOnCreate) check fails and nothing is called.

Omiting assigned check does not work either.

I've also tried to check prototype - Prototype.HasProperty('OnCreate') to no avail.

I'm not totally sure how i should be handling this, any help will be appreciated.

JernejL avatar Jan 10 '20 06:01 JernejL

Hello @JernejL

In my case i defined https://github.com/Coldzer0/Cmulator/blob/master/Core/jsplugins_bengine.pas#L20 https://github.com/Coldzer0/Cmulator/blob/master/Core/jsplugins_bengine.pas#L29

then assigned it on JS code then check if it's not nil and finally call it

Coldzer0 avatar Jan 10 '20 14:01 Coldzer0

Plus you can check my project for QJS (is a JS Engine with Almost Complete ES2019 & Alot of ES2020 support)

https://github.com/Coldzer0/QuickJS-Pascal

It's very easy to use, I already updated my Cmulator project to use it.

Coldzer0 avatar Jan 10 '20 14:01 Coldzer0

@Coldzer0 thanks - i did find your project and am trying to learn from it as much as possible, as it is a rare project using besen.

I also use that approach that you described and it works, the problem that i have is, that this cannot be used to call prototype functions - it works well for individual instances only, and it means copying the function to each newly created object to achieve that.

I added a function to main instance of object - by appending a function to Actor.prototype - and that itself cannot be called or reached from inside besen.

quickjs looks interesting, but so far i'll try to stick with besen - i think it has a lot of potential, it just lacks more complete examples on integration and usage scenatios.

JernejL avatar Jan 10 '20 15:01 JernejL