How to override C# class in JS and return instance back to C# #1429
Unanswered
achimmihca
asked this question in
Q&A
Replies: 1 comment 2 replies
-
Instead of trying to implement C# interface directly in js (which doesn't work), you can make a C# class that implement your C# interface that calls the corresponding js function. untested pseudocodepublic interface IHighscoreProvider
{
void SetScore(int score);
int GetScore();
}
public class ScriptingHighscoreProvider : IHighscoreProvider
{
private Engine engine;
public ScriptingHighscoreProvider()
{
this.engine = new Engine();
var jscode = File.ReadAllText("...");
this.engine.Execute(jscode);
}
public void SetScore(int score)
{
this.engine.Invoke("setScore", score);
}
public int GetScore()
{
return (int)this.engine.Invoke("getScore").AsNumber();
}
} Tested example: public interface IHighscoreProvider
{
void SetScore(int score);
int GetScore();
}
public class ScriptingHighscoreProvider : IHighscoreProvider
{
private readonly Engine engine;
private ObjectInstance provider;
public ScriptingHighscoreProvider()
{
engine = new Engine();
engine.SetValue("setHighscoreProvider", (JsValue value) =>
{
if (!value.IsObject())
{
throw new JavaScriptException(engine.Realm.Intrinsics.Error, "only object can be passed");
}
provider = value.AsObject();
});
engine.Execute("""
class MyHighscoreProvider {
constructor() { this.score = 2000; }
setScore(score) { this.score = score; }
getScore() { return this.score; }
}
setHighscoreProvider(new MyHighscoreProvider())
""");
if (provider is null)
{
throw new Exception("script did not call setHighscoreProvider");
}
}
public int GetScore()
{
return (int) provider.Get("getScore").Call(thisObj: provider).AsNumber();
}
public void SetScore(int score)
{
provider.Get("setScore").Call(thisObj: provider, score);
}
}
public class Test
{
[Fact]
public void TestRun()
{
IHighscoreProvider provider = new ScriptingHighscoreProvider();
Assert.Equal(2000, provider.GetScore());
provider.SetScore(123);
Assert.Equal(123, provider.GetScore());
}
} Keep in mind Depending on how you want to implement scripting in your project, you could also create a new |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Is it possible to
My goal is to integrate Jint in a Unity game to let users register custom code, e.g. a
HighscoreProvider
.Is this possible?
In my test, it always returns the value of the C# method. Thus, overriding the method does not seem to work.
BTW: how is upper/lower case handled? I notice that PascalCase in C# seems to be available as camelCase in JS.
I am thinking about a ScriptRegistry that is accessible in JS so users can add stuff to it.
The HighscoreProvider and Registry are made available to the Engine:
Above nearly works.
AddHighscoreProvider
is called with some object, but it does not seem to include the overriddengetScore
method.GetScore
still returns 10.What would be even better than a C# class would be a C# interface that can be implemented in JS.
Is it possible to implement a C# interface in JS and return an instance to C#?
Beta Was this translation helpful? Give feedback.
All reactions