tjanczuk / edge

Run .NET and Node.js code in-process on Windows, MacOS, and Linux
http://tjanczuk.github.io/edge
Other
5.41k stars 640 forks source link

How to create and reuse an instance variable with using Edge? #388

Open jamiedejong opened 8 years ago

jamiedejong commented 8 years ago

Hello,

What is my issue? When I say "Blink green" the drone will do exactly what I want. That works great.

When I say "Blink green" again, it will execute the code, but the drone doesn't give a response. The drone gives only a response in the first time. So every time I have to restart the program to make it work. Annoying...

What happens the second time? It will do exactly the same, it's executing the code as well, but the drone doesn't give a response.

Here's the code:

    private static void _speechRecognitionEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
        switch (e.Result.Text)
        {
            case "Blink green":
                Task.Run((Action)blinkGreen);
                break;
        }
    }

    // ONLY WORKS THE FIRST TIME
    // WHEN I SAY "BLINK GREEN" AGAIN, IT'S WILL EXECUTE THE 
    // CODE BUT THE DRONE DOESN'T GIVE A RESPONSE. ONLY THE 
    // FIRST TIME (SO I HAVE TO RESTART THE PROGRAM)
    public static async void blinkGreen()
    {
        var func = Edge.Func(@"
            var arDrone = require('ar-drone');
            var client = arDrone.createClient(); 

            return function(data, callback){
                client.animateLeds('blinkGreen',5,2);
                callback(null, data);
            }
        ");
        Console.WriteLine(await func("BLINK EXECUTED!"));
    }

I think there is something going on with:

var arDrone = require('ar-drone');
var client = arDrone.createClient(); 

I am allowed to create one client I guess. I have to create and reuse the client instance, so I can use the same client which would solve the problem. But I have no idea how to do that with the Edge.js module...

I hope someone could help me out with this problem.

Thanks,

Jamie

tjanczuk commented 8 years ago

@jamiedejong I don't know anything about ar-drone library, but if your hypothesis about being able to create a single client per process is correct, you may want to try moving the Edge.Func call to global scope in your C# program (i.e. execute it once), and then invoke the resulting func instance multiple times.

jamiedejong commented 8 years ago

@tjanczuk Thanks for your reply.

I have something like that right now, but how can I invoke the JavaScript using a global variable in C#?

  1. I have created one boolean to check if there's already one client and one variable to save the client.

    static bool clientCreated = false;
    static object currentClient;
  2. In the beginning of the program I've created a check to get an existing or new client

       // First check to get an existing or new client
       currentClient = GetOrCreateClient();
  3. I've created a method to return an existing or new client

    public static object GetOrCreateClient()
    {
       // If there is already a client
       if (clientCreated)
       {
           Console.WriteLine("There's already a client!");
       }
       // If there is no client
       else
       {
           // Set boolean
           clientCreated = true;
    
           // Create a client
           var newClient = Edge.Func(@"
               var arDrone = require('ar-drone');
               var client = arDrone.createClient();
    
               return function(data, callback){
                   callback(null, data);
               }
           ");
    
           Console.WriteLine("Client created!");
    
           // Return new client
           return newClient;
       }
       // Return current client
       return currentClient;
    }
  4. And the functionality method to do an action (animation of the drone) which should use the same client

    public static async void blinkGreen()
    {
       // Get an existing or new client
       var client = GetOrCreateClient();
    
       // Execute the functionality
       var func = Edge.Func(@"             
           var arDrone = require('ar-drone'); // ACTUALLY THIS ONE IS ALREADY DEFINED IN THE METHOD GetOrCreateClient()
           var client = I WANT HERE THE CLIENT, BUT HOW?
    
           return function(data, callback){
               client.animateLeds('blinkGreen',5,2);
               callback(null, data);
           }
       ");
       Console.WriteLine(await func("BLINK EXECUTED!"));
    }

Now I am stuck on a few things, because is that the right way to save the client globally in an object? Because the method GetOrCreateClient() returns the following object:

`System.Func`2[System.Object,System.Threading.Tasks.Task`1[System.Object]]`

So my next question would be, how can I use the client object into the functionality?

The var client = GetOrCreateClient();

variable should placed into:

        var func = Edge.Func(@"             
            var arDrone = require('ar-drone'); // ACTUALLY THIS ONE IS ALREADY DEFINED IN THE METHOD GetOrCreateClient()
            var client = I WANT HERE THE CLIENT, BUT HOW?