Skip to content

Commit 16fd9a4

Browse files
committed
In configuration settings of the Yantra JS engine was added two new properties: ConsoleCallback (default null) and Debugger (default null)
1 parent ca370b3 commit 16fd9a4

File tree

6 files changed

+446
-22
lines changed

6 files changed

+446
-22
lines changed

src/JavaScriptEngineSwitcher.Yantra/JsEngineFactoryCollectionExtensions.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,55 @@ public static JsEngineFactoryCollection AddYantra(this JsEngineFactoryCollection
2222
throw new ArgumentNullException(nameof(source));
2323
}
2424

25-
source.Add(new YantraJsEngineFactory());
25+
return source.AddYantra(new YantraSettings());
26+
}
27+
28+
/// <summary>
29+
/// Adds a instance of <see cref="YantraJsEngineFactory"/> to
30+
/// the specified <see cref="JsEngineFactoryCollection"/>
31+
/// </summary>
32+
/// <param name="source">Instance of <see cref="JsEngineFactoryCollection"/></param>
33+
/// <param name="configure">The delegate to configure the provided <see cref="YantraSettings"/></param>
34+
/// <returns>Instance of <see cref="JsEngineFactoryCollection"/></returns>
35+
public static JsEngineFactoryCollection AddYantra(this JsEngineFactoryCollection source,
36+
Action<YantraSettings> configure)
37+
{
38+
if (source == null)
39+
{
40+
throw new ArgumentNullException(nameof(source));
41+
}
42+
43+
if (configure == null)
44+
{
45+
throw new ArgumentNullException(nameof(configure));
46+
}
47+
48+
var settings = new YantraSettings();
49+
configure(settings);
50+
51+
return source.AddYantra(settings);
52+
}
53+
54+
/// <summary>
55+
/// Adds a instance of <see cref="YantraJsEngineFactory"/> to
56+
/// the specified <see cref="JsEngineFactoryCollection"/>
57+
/// </summary>
58+
/// <param name="source">Instance of <see cref="JsEngineFactoryCollection"/></param>
59+
/// <param name="settings">Settings of the Yantra JS engine</param>
60+
/// <returns>Instance of <see cref="JsEngineFactoryCollection"/></returns>
61+
public static JsEngineFactoryCollection AddYantra(this JsEngineFactoryCollection source, YantraSettings settings)
62+
{
63+
if (source == null)
64+
{
65+
throw new ArgumentNullException(nameof(source));
66+
}
67+
68+
if (settings == null)
69+
{
70+
throw new ArgumentNullException(nameof(settings));
71+
}
72+
73+
source.Add(new YantraJsEngineFactory(settings));
2674

2775
return source;
2876
}

src/JavaScriptEngineSwitcher.Yantra/YantraEngineFactory.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,28 @@ namespace JavaScriptEngineSwitcher.Yantra
77
/// </summary>
88
public sealed class YantraJsEngineFactory : IJsEngineFactory
99
{
10+
/// <summary>
11+
/// Settings of the Yantra JS engine
12+
/// </summary>
13+
private readonly YantraSettings _settings;
14+
15+
1016
/// <summary>
1117
/// Constructs an instance of the Yantra JS engine factory
1218
/// </summary>
1319
public YantraJsEngineFactory()
20+
: this(new YantraSettings())
1421
{ }
1522

23+
/// <summary>
24+
/// Constructs an instance of the Yantra JS engine factory
25+
/// </summary>
26+
/// <param name="settings">Settings of the Yantra JS engine</param>
27+
public YantraJsEngineFactory(YantraSettings settings)
28+
{
29+
_settings = settings;
30+
}
31+
1632

1733
#region IJsEngineFactory implementation
1834

@@ -29,7 +45,7 @@ public string EngineName
2945
/// <returns>Instance of the Yantra JS engine</returns>
3046
public IJsEngine CreateEngine()
3147
{
32-
return new YantraJsEngine();
48+
return new YantraJsEngine(_settings);
3349
}
3450

3551
#endregion
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace JavaScriptEngineSwitcher.Yantra
2+
{
3+
/// <summary>
4+
/// The JS debugging console callback
5+
/// </summary>
6+
/// <param name="type">Type of message</param>
7+
/// <param name="args">A array of objects to output</param>
8+
public delegate void YantraJsConsoleCallback(string type, object[] args);
9+
}

src/JavaScriptEngineSwitcher.Yantra/YantraJsEngine.cs

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
using OriginalClrProxy = YantraJS.Core.Clr.ClrProxy;
1212
using OriginalClrType = YantraJS.Core.Clr.ClrType;
1313
using OriginalContext = YantraJS.Core.JSContext;
14+
using OriginalDate = YantraJS.Core.JSDate;
1415
using OriginalException = YantraJS.Core.JSException;
1516
using OriginalFunction = YantraJS.Core.JSFunction;
17+
using OriginalJsonObject = YantraJS.Core.JSJSON;
1618
using OriginalTypeConverter = YantraJS.Utils.TypeConverter;
1719
using OriginalUndefined = YantraJS.Core.JSUndefined;
1820
using OriginalValue = YantraJS.Core.JSValue;
@@ -59,6 +61,11 @@ public sealed class YantraJsEngine : JsEngineBase
5961
/// </summary>
6062
private OriginalContext _jsContext;
6163

64+
/// <summary>
65+
/// JS debugging console callback
66+
/// </summary>
67+
private YantraJsConsoleCallback _consoleCallback;
68+
6269
/// <summary>
6370
/// Synchronizer of code execution
6471
/// </summary>
@@ -75,11 +82,35 @@ public sealed class YantraJsEngine : JsEngineBase
7582
/// Constructs an instance of adapter for the Yantra JS engine
7683
/// </summary>
7784
public YantraJsEngine()
85+
: this(new YantraSettings())
86+
{ }
87+
88+
/// <summary>
89+
/// Constructs an instance of adapter for the Yantra JS engine
90+
/// </summary>
91+
/// <param name="settings">Settings of the Yantra JS engine</param>
92+
public YantraJsEngine(YantraSettings settings)
7893
{
79-
_jsContext = new OriginalContext()
94+
YantraSettings yantraSettings = settings ?? new YantraSettings();
95+
_consoleCallback = yantraSettings.ConsoleCallback;
96+
97+
try
98+
{
99+
_jsContext = new OriginalContext()
100+
{
101+
ClrMemberNamingConvention = OriginalClrMemberNamingConvention.Declared,
102+
Debugger = yantraSettings.Debugger
103+
};
104+
105+
if (_consoleCallback != null)
106+
{
107+
_jsContext.ConsoleEvent += OnConsoleWrite;
108+
}
109+
}
110+
catch (Exception e)
80111
{
81-
ClrMemberNamingConvention = OriginalClrMemberNamingConvention.Declared
82-
};
112+
throw JsErrorHelpers.WrapEngineLoadException(e, EngineName, EngineVersion, true);
113+
}
83114
}
84115

85116

@@ -139,6 +170,21 @@ private static object MapToHostType(OriginalValue value)
139170
{
140171
result = value.ToString();
141172
}
173+
else if (value is OriginalDate)
174+
{
175+
var jsDate = (OriginalDate)value;
176+
result = jsDate.DateTime;
177+
}
178+
else if (value is OriginalClrProxy)
179+
{
180+
var clrProxy = (OriginalClrProxy)value;
181+
result = clrProxy.Target;
182+
}
183+
else if (value is OriginalClrType)
184+
{
185+
var clrType = (OriginalClrType)value;
186+
result = clrType.Type;
187+
}
142188
else
143189
{
144190
result = value;
@@ -201,7 +247,7 @@ private static OriginalFunction CreateEmbeddedFunction(Delegate del)
201247
{
202248
MethodInfo method = del.GetMethodInfo();
203249
ParameterInfo[] parameters = method.GetParameters();
204-
object[] processedArgs = GetHostDelegateArguments(args.ToArray(), parameters.Length);
250+
object[] processedArgs = GetHostDelegateArguments(args, parameters.Length);
205251

206252
ReflectionHelpers.FixArgumentTypes(ref processedArgs, parameters);
207253

@@ -231,28 +277,21 @@ private static OriginalFunction CreateEmbeddedFunction(Delegate del)
231277
return originalFunction;
232278
}
233279

234-
private static object[] GetHostDelegateArguments(OriginalValue[] args, int maxArgCount)
280+
private static object[] GetHostDelegateArguments(in OriginalArguments args, int maxArgCount)
235281
{
236-
if (args == null)
282+
int argCount = args.Length;
283+
if (argCount == 0)
237284
{
238-
throw new ArgumentNullException(nameof(args));
285+
return new object[0];
239286
}
240287

241-
int argCount = args.Length;
242-
int processedArgCount = argCount > maxArgCount ? maxArgCount : argCount;
243-
object[] processedArgs;
288+
int processedArgCount = Math.Min(argCount, maxArgCount);
289+
var processedArgs = new object[processedArgCount];
244290

245-
if (processedArgCount > 0)
291+
for (int argIndex = 0; argIndex < processedArgCount; argIndex++)
246292
{
247-
processedArgs = args
248-
.Take(processedArgCount)
249-
.Select(MapToHostType)
250-
.ToArray()
251-
;
252-
}
253-
else
254-
{
255-
processedArgs = new object[0];
293+
OriginalValue arg = args.GetAt(argIndex);
294+
processedArgs[argIndex] = MapToHostType(arg);
256295
}
257296

258297
return processedArgs;
@@ -345,6 +384,43 @@ private WrapperException WrapJsException(OriginalException originalException)
345384
return wrapperException;
346385
}
347386

387+
private void OnConsoleWrite(OriginalContext context, string type, in OriginalArguments args)
388+
{
389+
int argCount = args.Length;
390+
var processedArgs = new object[argCount];
391+
392+
for (int argIndex = 0; argIndex < argCount; argIndex++)
393+
{
394+
OriginalValue arg = args.GetAt(argIndex);
395+
object processedArg = MapToHostType(arg);
396+
397+
if (processedArg is OriginalValue)
398+
{
399+
if (arg.IsFunction)
400+
{
401+
var jsFunction = (OriginalFunction)arg;
402+
processedArg = string.Format("[Function: {0}]", jsFunction.name);
403+
}
404+
else if (arg.IsSymbol)
405+
{
406+
processedArg = string.Format("Symbol({0})", arg.ToString());
407+
}
408+
else if (arg.IsObject || arg.IsArray)
409+
{
410+
processedArg = OriginalJsonObject.Stringify(arg);
411+
}
412+
else
413+
{
414+
processedArg = arg.ToString();
415+
}
416+
}
417+
418+
processedArgs[argIndex] = processedArg;
419+
}
420+
421+
_consoleCallback?.Invoke(type, processedArgs);
422+
}
423+
348424
#endregion
349425

350426
/// <summary>
@@ -688,6 +764,12 @@ public override void Dispose()
688764
{
689765
if (_jsContext != null)
690766
{
767+
if (_consoleCallback != null)
768+
{
769+
_jsContext.ConsoleEvent -= OnConsoleWrite;
770+
_consoleCallback = null;
771+
}
772+
691773
_jsContext.Dispose();
692774
_jsContext = null;
693775
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using OriginalDebugger = YantraJS.Debugger.JSDebugger;
2+
using OriginalV8Debugger = YantraJS.Core.Debugger.V8Debugger;
3+
4+
namespace JavaScriptEngineSwitcher.Yantra
5+
{
6+
/// <summary>
7+
/// Settings of the Yantra JS engine
8+
/// </summary>
9+
public sealed class YantraSettings
10+
{
11+
/// <summary>
12+
/// Gets or sets a JS debugging console callback
13+
/// </summary>
14+
public YantraJsConsoleCallback ConsoleCallback
15+
{
16+
get;
17+
set;
18+
}
19+
20+
/// <summary>
21+
/// Gets or sets an instance of JS debugger (for example, the <see cref="OriginalV8Debugger"/>)
22+
/// </summary>
23+
public OriginalDebugger Debugger
24+
{
25+
get;
26+
set;
27+
}
28+
29+
30+
/// <summary>
31+
/// Constructs an instance of the Yantra settings
32+
/// </summary>
33+
public YantraSettings()
34+
{
35+
ConsoleCallback = null;
36+
Debugger = null;
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)