Поделиться через


Взаимодействие кода JavaScript и C++ в примере Bing Maps Trip Optimizer

Приложение Bing Maps Trip Optimizer использует JavaScript, чтобы определить пользовательский интерфейс, и C++ для оптимизации маршрута. В этом документе рассматривается взаимодействие частей JavaScript и C++ в примере приложения Bing Maps Trip Optimizer. В нем описывается, как компонент JavaScript инициализирует компонент C++ и отправляет в него данные и как компонент C++ отправляет данные обратно в компонент JavaScript. Более подробно отдельные компоненты JavaScript и C++ описаны в документах Использование JavaScript в примере Bing Maps Trip Optimizer и Использование C++ в примере Bing Maps Trip Optimizer.

Примечание

Не забудьте, что файлы default.html, default.css и default.js называются локальным контекстом, поскольку они могут ссылаться на Среда выполнения Windows (в том числе на пользовательский компонент Среда выполнения Windows C++), но им запрещен доступ к Интернету. Файлы web.html, web.css и web.js называются веб-контекстом, поскольку они могут получать доступ к Интернету, но им не предоставлен доступ к Среда выполнения Windows. Веб-контекст также определяет пользовательский интерфейс.

Примечание

Пример кода, соответствующий этому документу, включен в пример приложения Bing Maps Trip Optimizer.

Содержание этой статьи

  • Инициализация компонента C++ из JavaScript

  • Отправка данных в компонент C++

  • Получение данных из компонента C++

  • Переход с версии ActiveX

  • Следующие шаги

Инициализация компонента C++ из JavaScript

Локальный контекст объявляет переменные, которые представляют компонент C++ и текущую операцию оптимизации маршрута.

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

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

Функция optimizerLoad, которая вызывается во время инициализации приложения, создает объект TripOptimizer.

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

Среда выполнения Windows может найти и загрузить объект TripOptimizer, поскольку проект JavaScript в Visual Studio содержит ссылку на проект C++.

[Наверх]

Отправка данных в компонент C++

Взаимодействие локального и веб-контекста описано в документе Использование JavaScript в примере Bing Maps Trip Optimizer. Когда пользователь нажимает кнопку Get Directions (Получить направления) или Cancel (Отмена), веб-контекст отправляет сообщение в локальный контекст для вызова соответствующего метода TripOptimizer в компоненте C++. Например, если пользователь нажимает кнопку Get Directions (Получить направления), веб-контекст отправляет строку "optimizeTrip" как часть сообщения в локальный контекст. Если пользователь нажимает кнопку Cancel (Отмена), веб-контекст отправляет строку "cancel". В следующем примере кода показано, как локальный контекст получает эти сообщения от веб-контекста.

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();
    }
}

Функция optimizerOptimizeTrip перенаправляет параметры из веб-контекста в компонент 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);

В этом примере также задается переменная asyncOperation. Эта переменная задается таким образом, чтобы можно было отменить операцию, когда пользователь нажимает кнопку Cancel (Отмена).

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

Примечание

Метод TripOptimizer::OptimizerTripAsync компонента C++ представляется компоненту JavaScript в качестве метода TripOptimizer.optimizerTripAsync (первая буква заменена на строчную для соответствия стандартным соглашениям об именовании JavaScript).

[Наверх]

Получение данных из компонента C++

Метод TripOptimizer::OptimizerTripAsync компонента C++ работает асинхронно. Поэтому компонент JavaScript приложения должен иметь возможность обрабатывать данные, как только они становятся доступными. Часть JavaScript использует обещания, чтобы реагировать на завершение асинхронных операций, создает ошибку или сообщает о ходе выполнения. В следующем примере показано, как функция optimizerOptimizeTrip определяет обратные вызовы завершения, ошибки и хода выполнения для вызова метода 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);
        }
        );
}

Обратите внимание, что, когда пользователь нажимает кнопку Cancel (Отмена), компонент C++ отменяет текущую операцию. Среда выполнения вызывает обработчик ошибок для операции. Она устанавливает в поле ошибки description значение "Canceled", указывающее, что результат появился вследствие отмены. Дополнительные сведения о работе с асинхронными операциями на языке JavaScript см. в разделе Asynchronous programming.

Если локальный контекст получает сведения о ходе выполнения или результат асинхронной операции, он перенаправляет данные события в веб-контекст, чтобы веб-контекст смог обновить пользовательский интерфейс. Например, функция progressCallback отправляет строку "progressCallback" как часть сообщения, отправляемого в веб-контекст.

// 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), "*");
}

В следующем примере показана функция receiveMessage для веб-контекста. Эта функция получает сообщения из локального контекста.

// 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);
    }
}

Получив сообщение "progressCallback", веб-контекст вызывает функцию progressCallback, которая обновляет пользовательский интерфейс для отображения сообщения о ходе выполнения.

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

[Наверх]

Переход с версии ActiveX

Сведения о переходе с версии ActiveX приложения Bing Maps Trip Optimizer к приложению Магазин Windows см. в разделе Перенос существующего кода в примере Bing Maps Trip Optimizer.

[Наверх]

Следующие шаги

В этой статье объясняется, как использовать JavaScript и C++ для создания полного приложения Магазин Windows. Попробуйте использовать компонент C++ вместе с приложением JavaScript для использования кода, который вы уже написали и протестировали, и повышения производительности.

[Наверх]