Compartir a través de


Interoperar entre JavaScript y C++ en el ejemplo de Bing Maps Trip Optimizer

Optimizador de recorridos de Mapas de Bing utiliza JavaScript para definir la interfaz de usuario y C++ para realizar la optimización de recorrido. Este documento describe cómo interactúan las partes de JavaScript y C++ del ejemplo de Optimizador de recorridos de Mapas de Bing. Describe cómo el componente de JavaScript inicializa el componente de C++y le envía datos, y cómo el componente de C++ devuelve datos al componente de JavaScript. Los componentes individuales de JavaScript y C++ se describen con mayor detalle en los documentos Usar JavaScript en el ejemplo de Bing Maps Trip Optimizer y Usar C++ en el ejemplo de Bing Maps Trip Optimizer.

NotaNota

Recuerde que hacemos referencia a default.html, default.css y default.js como contexto local porque estos archivos pueden hacer referencia a Windows en tiempo de ejecución (esto incluye el componente de Windows en tiempo de ejecución en C++ personalizado) pero no pueden tener acceso a la Web. Hacemos referencia a web.html, web.css y web.js como contexto web porque estos archivos pueden tener acceso a la Web, pero no pueden tener acceso a Windows en tiempo de ejecución. El contexto web también define la interfaz de usuario.

NotaNota

El código de ejemplo que corresponde a este documento se encuentra en el Ejemplo de Optimizador de recorridos de Mapas de Bing.

En este artículo

  • Inicializar el componente de C++ desde JavaScript

  • Enviar datos al componente de C++

  • Recibir datos del componente de C++

  • Migración de ActiveX

  • Pasos siguientes

Inicializar el componente de C++ desde JavaScript

El contexto local declara variables que representan el componente de C++ y la operación de optimización de recorrido actual.

// The C++ component.
var tripOptimizer = null;

// The current asynchronous trip optimization.
var asyncOperation = null;

La función optimizerLoad, que se invoca durante la inicialización de la aplicación, crea el objeto TripOptimizer.

function optimizerLoad() {
    "use strict";
    tripOptimizer = new TripOptimizerComponent.TripOptimizer();
}

Windows en tiempo de ejecución puede buscar y cargar el objeto TripOptimizer porque el proyecto de Visual Studio de JavaScript contiene una referencia al proyecto de C++.

[Principio]

Enviar datos al componente de C++

El documento Usar JavaScript en el ejemplo de Bing Maps Trip Optimizer describe cómo se comunican los contextos local y de web. Cuando el usuario selecciona el botón Obtener direcciones o Cancelar, el contexto web envía un mensaje al contexto local para llamar al método TripOptimizer adecuado en el componente de C++. Por ejemplo, si el usuario elige Obtener direcciones, el contexto web envía la cadena “optimizeTrip” como parte del mensaje al contexto local. Cuando el usuario elige Cancelar, el contexto web envía la cadena “cancel”. En el código siguiente se muestra cómo el contexto local recibe estos mensajes del contexto web.

function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx-web://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "load") {
        optimizerLoad();
    } else if (data.invoke === "optimizeTrip") {
        optimizerOptimizeTrip(
            data.locations,
            data.travelMode,
            data.optimize,
            data.bingMapsKey,
            data.alpha,
            data.beta,
            data.rho,
            data.iterations,
            data.parallel);
    } else if (data.invoke === "cancel") {
        optimizerCancel();
    } else if (data.invoke === "alert") {
            // Show message dialog.            
            new Windows.UI.Popups.MessageDialog(data.message).showAsync().then();
    }
}

La función optimizerOptimizeTrip reenvía los parámetros del contexto web al componente de C++.

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

En este ejemplo también establece la variable asyncOperation. Establecemos esta variable para poder cancelar la operación cuando el usuario elija Cancelar.

function optimizerCancel() {
    "use strict";
    if (asyncOperation !== null) {
        asyncOperation.cancel();
    }
}
NotaNota

El método TripOptimizer::OptimizerTripAsync en el componente de C++ se expone a JavaScript como TripOptimizer.optimizerTripAsync (la primera letra se cambia a minúsculas para ajustarse a las convenciones de nomenclatura de JavaScript estándar).

[Principio]

Recibir datos del componente de C++

El método TripOptimizer::OptimizerTripAsync en el componente de C++ se comporta de forma asincrónica. Por consiguiente, la parte JavaScript de la aplicación debe poder procesar los datos cuando esté disponible. La parte de JavaScript utiliza compromisos para reaccionar cuando una operación asincrónica se completa, produce un error o notifica el progreso. En el ejemplo siguiente se muestra cómo la función optimizerOptimizeTrip define la finalización, el error y las devoluciones de llamada de progreso para la llamada a TripOptimizer::OptimizeTripAsync.

function optimizerOptimizeTrip(locations, travelMode, optimize, bingMapsKey, alpha, beta, rho, iterations, parallel) {
    "use strict";
    asyncOperation = tripOptimizer.optimizeTripAsync(locations, travelMode, optimize, bingMapsKey,
        alpha, beta, rho, iterations, parallel);

    asyncOperation.then(
        function (result) {
            if (result !== null) {
                // If the result contains certain keys, then we know that the results contain
                // the optimize route.
                if (result.size === 2 && result.hasKey("locations") && result.hasKey("displayNames")) {
                    routeCallback(result);
                }
                    // Otherwise, we know that the component is asking us to resolve ambiguous locations.
                else {
                    locationsCallback(result);
                }
            }
            else {
                canceledCallback();
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

Observa que cuando el usuario elige Cancelar, el componente de C++ cancela la operación actual. El runtime llama al controlador de errores para la operación. Establece el campo description del error en “Cancelado” para indicar que el resultado es producto de la cancelación. Para obtener más información sobre cómo trabajar con operaciones asincrónicas en JavaScript, consulta Asynchronous programming.

Cuando el contexto local recibe el progreso o el resultado de una operación asincrónica, reenvía los datos de evento al contexto web para que el contexto web pueda actualizar la interfaz de usuario. Por ejemplo, la función progressCallback envía la cadena “progressCallback” como parte del mensaje que envía al contexto web.

// Event handler for progress notifications from the Windows Runtime component.
function progressCallback(info) {
    "use strict";
    var message = { "invoke": "progressCallback", "message": info };
    window.parent.frames.mapFrame.postMessage(JSON.stringify(message), "*");
}

En el ejemplo siguiente se muestra la función receiveMessage para el contexto web. Esta función recibe mensajes del contexto local.

// Receives a message from the local context.
function receiveMessage(message) {
    "use strict";
    // Verify event origin.
    if (message.origin !== "ms-appx://microsoft.sdksamples.tripoptimizer.js") {
        return;
    }

    var data = JSON.parse(message.data);
    if (data.invoke === "progressCallback") {
        progressCallback(data.message);
    } else if (data.invoke === "locationsCallback") {
        locationsCallback(JSON.parse(data.locationOptions));
    } else if (data.invoke === "routeCallback") {
        routeCallback(data.locations, data.displayNames);
    } else if (data.invoke === "canceledCallback") {
        canceledCallback();
    } else if (data.invoke === "errorCallback") {
        errorCallback(data.message);
    }
}

Para el mensaje “progressCallback”, el contexto web llama a la función progressCallback, que actualiza la interfaz de usuario para mostrar el mensaje de progreso.

// Event handler for progress notifications from the control.
function progressCallback(message) {
    "use strict";
    // Set message.
    progressMessageText.innerHTML = message;
}

[Principio]

Migración de ActiveX

Para obtener información sobre cómo migramos de la versión ActiveX de Optimizador de recorridos de Mapas de Bing a una aplicación de la Tienda Windows, consulta Migrar código existente en el ejemplo de Bing Maps Trip Optimizer.

[Principio]

Pasos siguientes

En este artículo se explica cómo usamos JavaScript y C++ para crear una aplicación de la Tienda Windows completa. Considere la posibilidad de usar un componente de C++ junto con tu aplicación JavaScript para aprovechar el código que ya has escrito y probado, y para mejorar el rendimiento.

[Principio]