Compartilhar via


Interoperação entre JavaScript e C++ no exemplo de otimizador de viagem do Mapas Bing

O Bing Maps Trip Optimizer usa JavaScript para definir a interface do usuário e C++ para executar a otimização da viagem. Este documento descreve como as partes de JavaScript e C++ do exemplo do Bing Maps Trip Optimizer interoperam. Ele descreve como o componente JavaScript inicializa o componente C++ e envia dados para ele e como o componente C++ envia dados de volta para o componente JavaScript. Os componentes JavaScript e C++ individuais são descritos em mais detalhes nos documentos Usando JavaScript no exemplo de otimizador de viagem do Mapas Bing e Usando C++ no exemplo de otimizador de viagem do Mapas Bing.

Dica

Lembre-se que chamamos os arquivos default.html, default.css e default.js de contexto local porque eles podem fazer referência ao Tempo de Execução do Windows - isso inclui o componente C++ personalizado do Tempo de Execução do Windows - mas não podem acessar a Web. Chamamos os arquivos web.html, web.css e web.js de contexto da Web porque eles podem acessar a Web, mas não podem acessar o Tempo de Execução do Windows. O contexto da Web também define a interface do usuário.

Dica

O código de exemplo que corresponde a este documento está localizado no Exemplo do Bing Maps Trip Optimizer.

Neste artigo

  • Inicializando o componente C++ a partir de JavaScript

  • Enviando dados para o componente C++

  • Recebendo dados do componente C++

  • Migração do ActiveX

  • Próximas etapas

Inicializando o componente C++ a partir de JavaScript

O contexto local declara variáveis que representam o componente C++ e a operação atual de otimização da viagem.

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

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

A função optimizerLoad, que é chamada durante a inicialização do aplicativo, cria o objeto TripOptimizer.

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

O Tempo de Execução do Windows pode localizar e carregar o objeto TripOptimizer porque o projeto do JavaScript Visual Studio contém uma referência ao projeto C++.

[Superior]

Enviando dados para o componente C++

O documento Usando JavaScript no exemplo de otimizador de viagem do Mapas Bing descreve como os contextos local e da Web se comunicam. Quando o usuário seleciona o botão Obter Instruções ou Cancelar, o contexto da Web envia uma mensagem ao contexto local para chamar o método TripOptimizer apropriado no componente C++. Por exemplo, quando o usuário escolhe Obter Instruções, o contexto da Web envia a cadeia de caracteres “optimizeTrip” como parte da mensagem ao contexto local. Quando o usuário escolhe Cancelar, o contexto da Web envia a cadeia de caracteres “cancel”. O código a seguir mostra como o contexto local recebe essas mensagens do contexto da 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();
    }
}

A função optimizerOptimizeTrip encaminha os parâmetros do contexto da Web para o componente 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);

Este exemplo também define a variável asyncOperation. Definimos essa variável de modo que possamos cancelar a operação quando o usuário escolhe Cancelar.

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

Dica

O método TripOptimizer::OptimizerTripAsync no componente C++ é exposta ao JavaScript como TripOptimizer.optimizerTripAsync (a primeira letra é alterada para minúscula para corresponder às convenções de nomenclatura de JavaScript padrão).

[Superior]

Recebendo dados do componente C++

O método TripOptimizer::OptimizerTripAsync no componente C++ se comporta de forma assíncrona. Portanto, a parte de JavaScript do aplicativo deve ser capaz de processar os dados quando se tornam disponíveis. A parte de JavaScript usa promessas de reagir quando uma operação assíncrona é concluída, lança um erro ou relata o andamento. O exemplo a seguir mostra como a função optimizerOptimizeTrip define as chamadas de retorno de conclusão, erro e andamento da chamada para 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);
                }
            }
            asyncOperation = null;
        },
        function (error) {
            if (error.description === "Canceled") {
                canceledCallback();
            }
            else {
                errorCallback("Error: " + error.message);
            }
            asyncOperation = null;
        },
        function (progress) {
            progressCallback(progress);
        }
        );
}

Observe que quando o usuário escolha Cancelar, o componente C++ cancela a operação atual. O tempo de execução chama o manipulador de erros da operação. Ele define o campo description do erro como "Cancelado" para indicar que o resultado se deve ao cancelamento. Para obter mais informações sobre como trabalhar com operações assíncronas em JavaScript, consulte Asynchronous programming.

Quando o contexto local recebe o andamento ou o resultado de uma operação assíncrona, ele encaminha os dados de evento para o contexto da Web para que este possa atualizar a interface do usuário. Por exemplo, a função progressCallback envia a cadeia de caracteres “progressCallback” como parte da mensagem enviada ao contexto da 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), "*");
}

O exemplo a seguir mostra a função receiveMessage para o contexto da Web. Essa função recebe mensagens do 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 a mensagem "progressCallback", o contexto da Web chama a função progressCallback, que atualiza a interface de usuário para exibir a mensagem de andamento.

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

[Superior]

Migração do ActiveX

Para obter informações sobre como migramos da versão ActiveX do Bing Maps Trip Optimizer para um aplicativo Windows Store, consulte Migrando o código existente no exemplo de otimizador de viagens do Mapas Bing.

[Superior]

Próximas etapas

Este artigo explicou como usamos JavaScript e C++ para criar um aplicativo Windows Store completo. Considere usar um componente C++ juntamente com o seu aplicativo JavaScript para aproveitar o código já gravado e testado e para melhorar o desempenho.

[Superior]