119 lines
4.5 KiB
C++
119 lines
4.5 KiB
C++
/* Copyright 2017 The MathWorks, Inc. */
|
|
|
|
#ifndef ENGINE_FACTORY_IMPL_HPP
|
|
#define ENGINE_FACTORY_IMPL_HPP
|
|
|
|
#include <algorithm>
|
|
#include <ratio>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <future>
|
|
#include "../cpp_engine_api.hpp"
|
|
#include "../matlab_engine.hpp"
|
|
#include "../engine_factory.hpp"
|
|
#include "../engine_future.hpp"
|
|
#include "../engine_exception.hpp"
|
|
|
|
|
|
namespace {
|
|
void initSession() {
|
|
cpp_engine_create_session();
|
|
}
|
|
|
|
bool cancelFind(uintptr_t, bool allowInterrupt) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
namespace matlab {
|
|
namespace engine {
|
|
using namespace matlab::execution;
|
|
|
|
inline std::unique_ptr<MATLABEngine> startMATLAB(const std::vector<std::u16string>& options) {
|
|
return startMATLABAsync(options).get();
|
|
}
|
|
|
|
inline FutureResult<std::unique_ptr<MATLABEngine>> startMATLABAsync(const std::vector<std::u16string>& options) {
|
|
initSession();
|
|
auto startMATLABType = [options]() {
|
|
std::vector<char16_t*> options_v(options.size());
|
|
std::transform(options.begin(), options.end(), options_v.begin(), [](const std::u16string& option){ return const_cast<char16_t*>(option.c_str()); });
|
|
bool errFlag = false;
|
|
uint64_t matlab = cpp_engine_create_out_of_process_matlab(options_v.data(), options_v.size(), &errFlag);
|
|
if (errFlag) {
|
|
throw EngineException("MATLAB process cannot be created.");
|
|
}
|
|
return std::unique_ptr<MATLABEngine>(new MATLABEngine(matlab));
|
|
};
|
|
std::future<std::unique_ptr<MATLABEngine>> stdF = std::async(std::launch::async, startMATLABType);
|
|
FutureResult<std::unique_ptr<MATLABEngine>> future(std::move(stdF));
|
|
return future;
|
|
}
|
|
|
|
inline std::vector<std::u16string> findMATLAB() {
|
|
initSession();
|
|
char16_t** names;
|
|
size_t size = cpp_engine_find_shared_matlab(&names);
|
|
std::vector<std::u16string> names_v(size);
|
|
for (size_t i = 0; i < size; i++) {
|
|
names_v[i] = names[i];
|
|
}
|
|
cpp_engine_destroy_names(names, size);
|
|
return names_v;
|
|
}
|
|
|
|
inline FutureResult<std::vector<std::u16string>> findMATLABAsync() {
|
|
std::future<std::vector<std::u16string> > stdFuture = std::async(std::launch::async, findMATLAB);
|
|
FutureResult<std::vector<std::u16string>> future(std::move(stdFuture), std::make_shared<TaskReference>(&cancelFind));
|
|
return future;
|
|
}
|
|
|
|
inline std::unique_ptr<MATLABEngine> connectMATLAB() {
|
|
return connectMATLABAsync().get();
|
|
}
|
|
|
|
inline std::unique_ptr<MATLABEngine> connectMATLAB(const std::u16string& name) {
|
|
return connectMATLABAsync(name).get();
|
|
}
|
|
|
|
inline FutureResult<std::unique_ptr<MATLABEngine> > connectMATLABAsync() {
|
|
std::vector<std::u16string> engines = findMATLAB();
|
|
if (!engines.empty()) {
|
|
return connectMATLABAsync(engines[0]);
|
|
}
|
|
else {
|
|
std::vector<std::u16string> options;
|
|
std::u16string option1 = convertUTF8StringToUTF16String("-r");
|
|
std::u16string option2 = convertUTF8StringToUTF16String("matlab.engine.shareEngine");
|
|
options.push_back(option1);
|
|
options.push_back(option2);
|
|
return startMATLABAsync(options);
|
|
}
|
|
}
|
|
|
|
inline FutureResult<std::unique_ptr<MATLABEngine>> connectMATLABAsync(const std::u16string& name) {
|
|
initSession();
|
|
auto connectMATLABType = [name]() {
|
|
bool errFlag = false;
|
|
uint64_t matlab = cpp_engine_attach_shared_matlab(name.c_str(), &errFlag);
|
|
if (errFlag) {
|
|
throw EngineException("MATLAB session cannot be connected.");
|
|
}
|
|
return std::unique_ptr<MATLABEngine>(new MATLABEngine(matlab));
|
|
};
|
|
std::future<std::unique_ptr<MATLABEngine>> stdF = std::async(std::launch::async, connectMATLABType);
|
|
FutureResult<std::unique_ptr<MATLABEngine>> future(std::move(stdF));
|
|
return future;
|
|
}
|
|
|
|
inline void terminateEngineClient() {
|
|
//initialize the session and load the library so the call to engine_terminate_session will not crash.
|
|
initSession();
|
|
cpp_engine_terminate_session();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#endif //ENGINE_FACTORY_IMPL_HPP
|