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
-
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