Quantcast
Are you the publisher? Claim or contact us about this channel


Embed this content in your HTML

Search

Report adult content:

click to rate:

Account: (login)

More Channels


Showcase


Channel Catalog



Channel Description:

ClearScript is a library that makes it easy to add scripting to your .NET applications. It currently supports JavaScript (via V8 and JScript) and VBScript.

older | 1 | .... | 59 | 60 | (Page 61) | 62 | 63 | .... | 115 | newer

    0 0

    Is there a way to ensure collection of this reference without calling CollectGarbage? can I dispose that individual reference perhaps?

    0 0

    Hi krisoye,

    How about something like this:
    publicclass Map : DynamicObject, IEnumerable {
        privatereadonly IDictionary<string, object> dict = new Dictionary<string, object>();
        private IList list;
        publicvoid Add(string key, object value) {
            dict.Add(key, value);
            list = null;
        }
        publicoverride IEnumerable<string> GetDynamicMemberNames() {
            foreach (var name in dict.Keys) {
                yieldreturn name;
            }
            foreach (var index in Enumerable.Range(0, dict.Count())) {
                yieldreturn index.ToString(CultureInfo.InvariantCulture);
            }
        }
        publicoverridebool TryGetMember(GetMemberBinder binder, outobject result) {
            var name = binder.Name;
            var found = dict.TryGetValue(name, out result);
            if (!found) {
                int index;
                if (int.TryParse(name, out index) && (index >= 0) && (index < dict.Count())) {
                    if (list == null) {
                        list = dict.ToList();
                    }
                    result = list[index];
                    found = true;
                }
            }
            return found;
        }
        public IEnumerator GetEnumerator() {
            return dict.GetEnumerator();
        }
    }
    Here's a usage sample:
    engine.Script.map = new Map { { "foo", 123 }, { "bar", 456 }, { "baz", 789 } };
    engine.AddHostType("Console", typeof(Console));
    engine.Execute(@"
        Console.WriteLine(map[0].Key);  // foo
        Console.WriteLine(map[1].Key);  // bar
        Console.WriteLine(map[2].Key);  // baz
        Console.WriteLine(map['foo']);  // 123
        Console.WriteLine(map['bar']);  // 456
        Console.WriteLine(map['baz']);  // 789
    ");
    The trick is to expose the indices as property names.

    Good luck!

    0 0

    Oh facepalm I swore I tried something like that. Thank you so much! Works great! Go-go Micorsoft ClearScript! I have now successfully loaded jQuery into my fledgling browser! Woot!

    0 0

    Sorry, are you asking about ensuring collection of a managed object that you've passed into the script engine?

    0 0

    Correct,

    I am basically wanting to perform my original code sample without leaking code and without having to take the hit of calling CollectGarbage(true) on every call like so:

    loop { // this loop runs many times
     var items = new List<int>(); // This list grows over time.
    _engine.Script.foo(items);
    _engine.CollectGarbage(true);
    }


    That works but it does not perform the best.



    Thanks

    0 0

    Hi Stefan,

    A few thoughts:

    • Calling CollectGarbage() every time is almost certainly overkill. Yes, it causes the script engine to release managed objects it's no longer holding, but those objects will stick around until the managed garbage collector kicks in, and that's very unlikely to happen at the end of each loop iteration unless you invoke it explicitly, especially if we're talking about a tight loop. Instead, consider calling CollectGarbage() periodically, or based on a schedule that makes sense for your application - possibly something as simple as calling it once for every n loop iterations.
    • Be aware also that unmanaged proxies will pile up within the script engine unless you call CollectGarbage() at some point; that's unavoidable. V8 will clean them up eventually, but we've found that when it comes to garbage collection, V8 is lazy enough to get itself into trouble - a sort of "garbage thrashing" state that kills performance.
    • If you really need the script engine to release an individual managed object that you've passed into it - something that makes sense for very large objects, for example - then consider exposing it indirectly. In this case, instead of passing a large list, pass a tiny forwarding wrapper that implements the same IList<int> interface. When you're done, reset the wrapper's internal reference and the large list is ready to be collected. The script engine never touches it at all.
    Cheers!

    0 0

    dictionary returns undefined but the item exist
    public class Get : Dictionary<string, string>
    ...
    var b = _GET["blub"];
    thanks for help

    0 0

    Hi furesoft,

    For standard .NET dictionaries, the following should work:
    var b = _GET.Item.get('blub'); // _GET.Item('blub') also works but is not preferred
    _GET.Item.set('blub', foo);
    Another possibility is to use the provided PropertyBag class instead of a standard dictionary. That'll enable simplified JavaScript-like syntax for looking up and storing values, but other members (e.g., methods such as TryGetValue) will not be accessible from script code.

    Good luck!

    0 0

    but another problem is, the get class is in another assembly than the scripting assembly, the assemblys cannot be referenced, because its a plugin

    and i replaced the dictionary with property bag but same: [undefined]

    0 0

    In our testing, the following works as expected:
    var bag = new PropertyBag();
    bag["blub"] = 123.456;
    engine.AddHostObject("bag", bag);
    Debug.Assert(engine.Evaluate("bag['blub']").Equals(123.456));
    If you're doing something different, please provide more information.

    0 0

    im parsing the query of the requesting url, and add the Get class instance to the engine

    0 0

    Can you provide any details? We can't help if we can't reproduce the problem. Possibly useful might be the relevant parts of the Get class you're using and the code that populates it and exposes it to the script engine. Thanks!

    0 0

    Rated 5 Stars (out of 5) - Nice improvements, appears to work well with all my existing tests.

    0 0

    engine.Add("_GET", Get.Create(p));
     public static PropertyBag Create(HttpProcessor p)
            {
                var props = new PropertyBag();
    
                var uri = new Uri("htt://localhost" + p.http_url);
                var q = uri.Query;
                foreach (var qi in q.Split(new[] { '&', '?' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    var s = qi.Split('=');
                    props.Add(s[0], s[1]);
                }
    
                return props;
            }

    0 0

    ive fixed, i have used the map class from another discussion

    0 0

    Glad to hear it furesoft, but PropertyBag really should be sufficient for this purpose.

    We don't have your HttpProcessor class, but if we modify the Create method as follows:
    publicstatic PropertyBag Create(string url) {
        var props = new PropertyBag();
        var q = new Uri("htt://localhost/" + url).Query;
        foreach (var qi in q.Split(new[] { '&', '?' }, StringSplitOptions.RemoveEmptyEntries)) {
            var s = qi.Split('=');
            props.Add(s[0], s[1]);
        }
        return props;
    }
    Then this test code works as expected:
    engine.AddHostObject("_GET", Create("qux.html?foo=123&bar=456&baz=789"));
    engine.AddHostType("Console", typeof(Console));
    engine.Execute(@"
        Console.WriteLine(_GET['foo']); // prints '123'
        Console.WriteLine(_GET['bar']); // prints '456'
        Console.WriteLine(_GET['baz']); // prints '789'
    ");
    Good luck!

    0 0

    the base implantation of DynamicMetaObject just returns an empty string array.

    advise using doing something like what dynamic object does


    ```
    public override IEnumerable<string> GetDynamicMemberNames()
    {
    return scriptItem.GetDynamicMemberNames();
    }
    ```


    test
    ```
    var objWithcolor = engine.Evaluate("x={color:'red'};");
    var dynamicProvider = (IDynamicMetaObjectProvider)objWithcolor;
    var metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
    var propNames = metaObject.GetDynamicMemberNames();
    Assert.IsTrue(propNames.Any(name => name == "color"));
    ```

    0 0

    the base implantation of DynamicMetaObject just returns an empty string array.

    advise using doing something like what dynamic object does


    ```
    public override IEnumerable<string> GetDynamicMemberNames()
    {
    return scriptItem.GetDynamicMemberNames();
    }
    ```


    test
    ```
    var objWithcolor = engine.Evaluate("x={color:'red'};");
    var dynamicProvider = (IDynamicMetaObjectProvider)objWithcolor;
    var metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
    var propNames = metaObject.GetDynamicMemberNames();
    Assert.IsTrue(propNames.Any(name => name == "color"));
    ```

    0 0

    the base implantation of DynamicMetaObject just returns an empty string array.

    advise using doing something like what dynamic object does


    ```
    public override IEnumerable<string> GetDynamicMemberNames()
    {
    return scriptItem.GetDynamicMemberNames();
    }
    ```


    test
    ```
    var objWithcolor = engine.Evaluate("x={color:'red'};");
    var dynamicProvider = (IDynamicMetaObjectProvider)objWithcolor;
    var metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider));
    var propNames = metaObject.GetDynamicMemberNames();
    Assert.IsTrue(propNames.Any(name => name == "color"));
    ```
    Comments: Wow, great catch! We'll fix this in the next point release. Thank you!

    0 0

    hi

    I want to use ClearScript to implement a small JavaScript plugin environment. Now I would like to implement a JavaScript library layer which has access to security relevant host functionality while the actual plugin code I am going to execute has not. Plugin code should only have access to the library layer.
    My first idea was to expose the necessary host objects only as local variables in functions of the library layer. However, I have not found a way to do this.
    Is there any way to achieve this "elevated" library layer?

older | 1 | .... | 59 | 60 | (Page 61) | 62 | 63 | .... | 115 | newer