зеркало из https://github.com/microsoft/napajs.git
Merged PR 277951: Remove legacy object-transporter.
Remove legacy object-transporter.
This commit is contained in:
Родитель
7cc3a722bc
Коммит
f8551f93b0
|
@ -5,7 +5,6 @@
|
|||
<ProjectFile Include="async-number\dirs.proj" />
|
||||
<ProjectFile Include="hello-world\dirs.proj" />
|
||||
<ProjectFile Include="plus-number\dirs.proj" />
|
||||
<ProjectFile Include="plus-number-transporter\dirs.proj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(ExtendedTargetsPath)\Traversal.targets" />
|
||||
|
|
|
@ -1,204 +0,0 @@
|
|||
# Plus Number Transporter
|
||||
|
||||
This example shows how to pass the object instance to a module. It serializes/deserializes object's pointer and passes to
|
||||
a module. This is useful when a host application needs to pass a native object to a module and
|
||||
serialization/deserialization cost is too expensive. Napa provides helper APIs to serialize and deserialize an existing
|
||||
object or new object. The important thing is that applicaiton owner is responsible for making an object alive until Napa
|
||||
finishes processing a request containing a passing object. Napa helps type check, but not lifetime management.
|
||||
|
||||
## Serialization APIs
|
||||
These APIs creates an object holder instance and its pointer value to pass to a module.
|
||||
|
||||
### Serialize existing object
|
||||
```cpp
|
||||
template <typename T>
|
||||
static std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> ObjectTransporter::Serialize(T* object)
|
||||
```
|
||||
Since a module doesn't know about object's lifetime, this API is good for a global object. *ObjectTransporter* instance
|
||||
must survive during request processing.
|
||||
|
||||
### Serialize new object
|
||||
```cpp
|
||||
template <typename T>
|
||||
static std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> ObjectTransporter::Serialize(std::shared_ptr<T> object)
|
||||
```
|
||||
*ObjectTransporter* instance must survive during request processing.
|
||||
|
||||
## Deserialization APIs
|
||||
```cpp
|
||||
template <typename T>
|
||||
static std::shared_ptr<T> ObjectTransporter::Deserialize(uintptr_t pointer)
|
||||
```
|
||||
It returns a passing object instance after deserializing a pointer value to object holder.
|
||||
|
||||
## Create new class
|
||||
When you creates new class to be serializable, inherit from this class.
|
||||
```cpp
|
||||
template <typename T>
|
||||
class TransportableObject
|
||||
```
|
||||
This provides *Serialize()* method as follows,
|
||||
```cpp
|
||||
std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> Serialize()
|
||||
```
|
||||
|
||||
## Passing class
|
||||
|
||||
*plus-number-transporter.h* declares ths class with one constructor and one method, *Add()*. It's the subclass of
|
||||
*TransportableObject<PlusNumberTransporter>* to enable serialization.
|
||||
|
||||
```h
|
||||
#include <napa/object-transportable.h>
|
||||
|
||||
namespace napa {
|
||||
namespace demo {
|
||||
|
||||
/// <summary> Example class to show how to pass object pointer to a module. </summary>
|
||||
class PlusNumberTransporter : public module::TransportableObject<PlusNumberTransporter> {
|
||||
public:
|
||||
|
||||
/// <summary> Constructor with initial value. </summary>
|
||||
PlusNumberTransporter(double value = 0.0);
|
||||
|
||||
/// <summary> Add the given value and return the result. </summary>
|
||||
double Add(double value);
|
||||
|
||||
private:
|
||||
|
||||
double _value;
|
||||
};
|
||||
|
||||
} // napespace demo
|
||||
} // namespace napa
|
||||
```
|
||||
|
||||
## Module
|
||||
|
||||
*addon.cpp* defines a module, which has two methods *createPlusNumberTransporter* and *add*.
|
||||
|
||||
```cpp
|
||||
#include <napa-module.h>
|
||||
#include <napa/object-transport-v8-helpers.h>
|
||||
#include <plus-number-transporter.h>
|
||||
|
||||
namespace napa {
|
||||
namespace demo {
|
||||
|
||||
using namespace v8;
|
||||
|
||||
// Since there is no host to store ObjectTransporter instance, make it globally for test.
|
||||
std::unique_ptr<module::ObjectTransporter> _objectTransporter;
|
||||
|
||||
void CreatePlusNumberTransporter(const FunctionCallbackInfo<Value>& args) {
|
||||
auto isolate = args.GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
CHECK_ARG(isolate,
|
||||
args.Length() == 0 || args.Length() == 1,
|
||||
"Only one or no argument is allowed.");
|
||||
|
||||
if (args.Length() == 1) {
|
||||
CHECK_ARG(isolate,
|
||||
args[0]->IsNumber(),
|
||||
"The first argument must be a number.");
|
||||
}
|
||||
|
||||
double value = args[0]->IsUndefined() ? 0.0 : args[0]->NumberValue();
|
||||
auto plusNumberTransporter = std::make_shared<PlusNumberTransporter>(value);
|
||||
|
||||
auto transporter = plusNumberTransporter->Serialize();
|
||||
_objectTransporter.swap(transporter.second);
|
||||
|
||||
auto result = module::object_transport::UintptrToV8Uint32Array(isolate, transporter.first);
|
||||
args.GetReturnValue().Set(result);
|
||||
}
|
||||
|
||||
void Add(const FunctionCallbackInfo<Value>& args) {
|
||||
auto isolate = args.GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
CHECK_ARG(isolate,
|
||||
args.Length() == 1 || args.Length() == 2,
|
||||
"Only one or two arguments are allowed.");
|
||||
|
||||
auto transporter = module::object_transport::V8Uint32ArrayToUintptr(isolate, args[0]);
|
||||
CHECK_ARG(isolate,
|
||||
transporter.second,
|
||||
"The first argument must be a uint32 array.");
|
||||
|
||||
if (args.Length() == 2) {
|
||||
CHECK_ARG(isolate,
|
||||
args[1]->IsNumber(),
|
||||
"The second argument must be a number.");
|
||||
}
|
||||
double value = args[1]->IsUndefined() ? 0.0 : args[1]->NumberValue();
|
||||
|
||||
auto object = module::ObjectTransporter::Deserialize<PlusNumberTransporter>(transporter.first);
|
||||
CHECK_ARG(isolate,
|
||||
object != nullptr,
|
||||
"Can't deserialize ObjectTransporter containing PlusNumberTransporter instance");
|
||||
|
||||
auto result = object->Add(value);
|
||||
args.GetReturnValue().Set(Number::New(isolate, result));
|
||||
}
|
||||
|
||||
void InitAll(Local<Object> exports) {
|
||||
NAPA_SET_METHOD(exports, "createPlusNumberTransporter", CreatePlusNumberTransporter);
|
||||
NAPA_SET_METHOD(exports, "add", Add);
|
||||
}
|
||||
|
||||
NAPA_MODULE(addon, InitAll);
|
||||
|
||||
} // namespace demo
|
||||
} // namespace napa
|
||||
```
|
||||
* *createPlusNumberTransporter()* returns the uint32 V8 array representation of pointer value to object holder.
|
||||
* *add()* has two parameters. The first one is the uint32 V8 array pointing to object holder, which is the return value
|
||||
of *createPlusNumberTransporter()* in this example. The second one is an addend. This function deserializes and
|
||||
restores a passing object and calls its *Add()* method.
|
||||
|
||||
### Napa helper APIs
|
||||
```h
|
||||
std::pair<uintptr_t, bool> napa::module::object_transport::V8Uint32ArrayToUintptr(v8::Isolate* isolate, const v8::Local<v8::Value>& source)
|
||||
```
|
||||
It converts a uint32 V8 array to uintptr. Return the pair of *{0, false}* if conversion fails.</summary>
|
||||
|
||||
```h
|
||||
v8::Local<v8::Array> napa::module::object_transport::UintptrToV8Uint32Array(v8::Isolate* isolate, uintptr_t source)
|
||||
```
|
||||
It converts a uintptr to a uint32 V8 array. </summary>
|
||||
|
||||
## Typescript
|
||||
It's recommended that typescript or typescript definition is provided to let the user know the APIs without
|
||||
the source codes and develop Typescript project easily.
|
||||
### plus-number-transporter.ts
|
||||
```ts
|
||||
var addon = require('../bin/addon');
|
||||
|
||||
export function createPlusNumberTransporter(value: number): any {
|
||||
return addon.createPlusNumberTransporter(value);
|
||||
}
|
||||
|
||||
export function add(transporter: any, value: number): number {
|
||||
return addon.add(transporter, value);
|
||||
}
|
||||
```
|
||||
### plus-number.d.ts
|
||||
```d.ts
|
||||
export declare function createPlusNumberTransporter(value: number): any;
|
||||
export declare function add(transporter: any, value: number): number;
|
||||
```
|
||||
|
||||
## Mocha test
|
||||
```js
|
||||
var assert = require('assert');
|
||||
var plusNumberTransporter = require('plus-number-transporter');
|
||||
|
||||
describe('Test suite for plus-number-transporter', function() {
|
||||
it('adds a given value', function() {
|
||||
var transporter: any = plusNumberTransporter.createPlusNumberTransporter(3);
|
||||
var result: number = plusNumberTransporter.add(transporter, 4);
|
||||
assert.equal(result, 7);
|
||||
});
|
||||
})
|
||||
```
|
|
@ -1,13 +0,0 @@
|
|||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectFile Include="napa\addon.vcxproj" />
|
||||
<ProjectFile Include="node\addon.vcxproj" />
|
||||
<ProjectFile Include="script\script.proj" />
|
||||
<ProjectFile Include="src\plus-number-transporter.vcxproj" />
|
||||
<ProjectFile Include="test\dirs.proj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(ExtendedTargetsPath)\Traversal.targets" />
|
||||
</Project>
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <napa/module/object-transport.h>
|
||||
|
||||
namespace napa {
|
||||
namespace demo {
|
||||
|
||||
/// <summary> Example class to show how to pass object pointer to a module. </summary>
|
||||
class PlusNumberTransporter : public module::TransportableObject<PlusNumberTransporter> {
|
||||
public:
|
||||
|
||||
/// <summary> Constructor with initial value. </summary>
|
||||
explicit PlusNumberTransporter(double value = 0.0);
|
||||
|
||||
/// <summary> Add the given value and return the result. </summary>
|
||||
double Add(double value);
|
||||
|
||||
private:
|
||||
|
||||
double _value;
|
||||
};
|
||||
|
||||
} // napespace demo
|
||||
} // namespace napa
|
|
@ -1,6 +0,0 @@
|
|||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<AddonType>Napa</AddonType>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\node\addon.vcxproj" />
|
||||
</Project>
|
|
@ -1,78 +0,0 @@
|
|||
#include <napa-module.h>
|
||||
#include <napa/module/object-transport-v8-helpers.h>
|
||||
#include <plus-number-transporter.h>
|
||||
|
||||
namespace napa {
|
||||
namespace demo {
|
||||
|
||||
using namespace v8;
|
||||
|
||||
// Since there is no host to store ObjectTransporter instance, make it globally for test.
|
||||
std::unique_ptr<module::ObjectTransporter> _objectTransporter;
|
||||
|
||||
void CreatePlusNumberTransporter(const FunctionCallbackInfo<Value>& args) {
|
||||
auto isolate = args.GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
CHECK_ARG(isolate,
|
||||
args.Length() == 0 || args.Length() == 1,
|
||||
"Only one or no argument is allowed.");
|
||||
|
||||
if (args.Length() == 1) {
|
||||
CHECK_ARG(isolate,
|
||||
args[0]->IsNumber(),
|
||||
"The first argument must be a number.");
|
||||
}
|
||||
|
||||
double value = args[0]->IsUndefined() ? 0.0 : args[0]->NumberValue();
|
||||
auto plusNumberTransporter = std::make_shared<PlusNumberTransporter>(value);
|
||||
|
||||
auto transporter = plusNumberTransporter->Serialize();
|
||||
_objectTransporter.swap(transporter.second);
|
||||
|
||||
auto result = module::object_transport::UintptrToV8Uint32Array(isolate, transporter.first);
|
||||
args.GetReturnValue().Set(result);
|
||||
}
|
||||
|
||||
void Add(const FunctionCallbackInfo<Value>& args) {
|
||||
auto isolate = args.GetIsolate();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
CHECK_ARG(isolate,
|
||||
args.Length() == 1 || args.Length() == 2,
|
||||
"Only one or two arguments are allowed.");
|
||||
|
||||
CHECK_ARG(isolate,
|
||||
args[0]->IsArray(),
|
||||
"The first argument must be an array");
|
||||
|
||||
auto transporter = module::object_transport::V8Uint32ArrayToUintptr(isolate, Local<Array>::Cast(args[0]));
|
||||
CHECK_ARG(isolate,
|
||||
transporter.second,
|
||||
"The first argument has a wrong pointer representation.");
|
||||
|
||||
if (args.Length() == 2) {
|
||||
CHECK_ARG(isolate,
|
||||
args[1]->IsNumber(),
|
||||
"The second argument must be a number.");
|
||||
}
|
||||
double value = args[1]->IsUndefined() ? 0.0 : args[1]->NumberValue();
|
||||
|
||||
auto object = module::ObjectTransporter::Deserialize<PlusNumberTransporter>(transporter.first);
|
||||
CHECK_ARG(isolate,
|
||||
object != nullptr,
|
||||
"Can't deserialize ObjectTransporter containing PlusNumberTransporter instance");
|
||||
|
||||
auto result = object->Add(value);
|
||||
args.GetReturnValue().Set(Number::New(isolate, result));
|
||||
}
|
||||
|
||||
void InitAll(Local<Object> exports) {
|
||||
NAPA_SET_METHOD(exports, "createPlusNumberTransporter", CreatePlusNumberTransporter);
|
||||
NAPA_SET_METHOD(exports, "add", Add);
|
||||
}
|
||||
|
||||
NAPA_MODULE(addon, InitAll);
|
||||
|
||||
} // namespace demo
|
||||
} // namespace napa
|
|
@ -1,53 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AddonName>addon</AddonName>
|
||||
<TargetName Condition=" '$(AddonType)' != 'Napa' ">$(AddonName)</TargetName>
|
||||
<TargetName Condition=" '$(AddonType)' == 'Napa' ">$(AddonName)_napa</TargetName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions Condition=" '$(AddonType)' != 'Napa' ">BUILDING_NODE_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition=" '$(AddonType)' == 'Napa' ">BUILDING_NAPA_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\examples\modules\plus-number-transporter\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition=" '$(AddonType)' == 'Napa' ">$(PkgNapa_V8_Library)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies Condition=" '$(AddonType)' == 'Napa' ">$(NapaVanillaRoot)\src\$(IntermediateOutputPath)\napa.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(NapaVanillaRoot)\examples\modules\plus-number-transporter\src\plus-number-transporter.vcxproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)\addon.cpp" />
|
||||
</ItemGroup>
|
||||
<Target Name="ChangeExtention" AfterTargets="Build">
|
||||
<Move SourceFiles="$(OutputPath)\$(TargetFileName)" DestinationFiles="$(OutputPath)\$(AddonName).node" Condition=" '$(AddonType)' != 'Napa' " />
|
||||
<Move SourceFiles="$(OutputPath)\$(TargetFileName)" DestinationFiles="$(OutputPath)\$(AddonName).napa" Condition=" '$(AddonType)' == 'Napa' " />
|
||||
</Target>
|
||||
<Import Project="$(PACKAGESROOT)\NodeJs.Library\exports.props" Condition=" '$(AddonType)' != 'Napa' " />
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"name": "plus-number-transporter",
|
||||
"version": "0.0.1",
|
||||
"author": "napav",
|
||||
"description": "Example of a napa module passing an object by pointer.",
|
||||
"main": "./lib/plus-number-transporter.js",
|
||||
"types": "./types/plus-number-transporter.d.ts"
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
|
||||
<ItemGroup>
|
||||
<QCustomProjectReference Include="$(NapaVanillaRoot)\examples\modules\plus-number-transporter\napa\addon.vcxproj" />
|
||||
<QCustomProjectReference Include="$(NapaVanillaRoot)\examples\modules\plus-number-transporter\node\addon.vcxproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<QCustomInput Include="src\plus-number-transporter.ts" />
|
||||
<QCustomInput Include="$(NapaBuildRoot)\**\*" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="BuildScripts" AfterTargets="AfterBuild">
|
||||
<Message Text="Compile scripts." />
|
||||
<Exec Command="$(TSCompile) src\plus-number-transporter.ts --declaration --typeRoots $(TypesRoot) --outDir $(O)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateNpmPackage" DependsOnTargets="BuildScripts" AfterTargets="AfterBuild">
|
||||
<Message Text="Create NPM package." />
|
||||
<MakeDir Directories="$(O)\dist\bin" ContinueOnError="false" Condition="!Exists('$(O)\dist\bin')" />
|
||||
<MakeDir Directories="$(O)\dist\lib" ContinueOnError="false" Condition="!Exists('$(O)\dist\lib')" />
|
||||
<MakeDir Directories="$(O)\dist\types" ContinueOnError="false" Condition="!Exists('$(O)\dist\types')" />
|
||||
<Copy SourceFiles="..\node\$(O)\addon.node" DestinationFolder="$(O)\dist\bin" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="..\napa\$(O)\addon.napa" DestinationFolder="$(O)\dist\bin" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(NapaVanillaRoot)\src\$(O)\napa.dll" DestinationFolder="$(O)\dist\bin" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(O)\plus-number-transporter.js" DestinationFolder="$(O)\dist\lib" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="$(O)\plus-number-transporter.d.ts" DestinationFolder="$(O)\dist\types" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
<Copy SourceFiles="package.json" DestinationFolder="$(O)\dist" ContinueOnError="false" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<Import Project="$(ExtendedTargetsPath)\NoTarget.targets" />
|
||||
</Project>
|
|
@ -1,9 +0,0 @@
|
|||
var addon = require('../bin/addon');
|
||||
|
||||
export function createPlusNumberTransporter(value: number): any {
|
||||
return addon.createPlusNumberTransporter(value);
|
||||
}
|
||||
|
||||
export function add(transporter: any, value: number): number {
|
||||
return addon.add(transporter, value);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#include "plus-number-transporter.h"
|
||||
|
||||
using namespace napa::demo;
|
||||
|
||||
PlusNumberTransporter::PlusNumberTransporter(double value)
|
||||
: _value(value) {
|
||||
}
|
||||
|
||||
double PlusNumberTransporter::Add(double value) {
|
||||
return _value + value;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="plus-number-transporter.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
|
@ -1,10 +0,0 @@
|
|||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectFile Include="library-test\library-test.vcxproj" />
|
||||
<ProjectFile Include="module-test\plus-number-transporter-test.njsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(ExtendedTargetsPath)\Traversal.targets" />
|
||||
</Project>
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\examples\modules\plus-number-transporter\inc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(NapaVanillaRoot)\third-party;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(NapaVanillaRoot)\examples\modules\plus-number-transporter\src\plus-number-transporter.vcxproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(ExtendedTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
|
@ -1,13 +0,0 @@
|
|||
#include <plus-number-transporter.h>
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
using namespace napa::demo;
|
||||
|
||||
TEST_CASE("PlusNumberTransporter: add the given value", "[add]") {
|
||||
PlusNumberTransporter plusNumberTransporter(3);
|
||||
|
||||
REQUIRE(plusNumberTransporter.Add(2) == 5);
|
||||
REQUIRE(plusNumberTransporter.Add(3) != 7);
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
build/
|
||||
tsconfig.json
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(EnvironmentConfig)" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>plus-number-transporter-test</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Test files -->
|
||||
<!-- It's using the default tsconfig.json@Napa.DevTools -->
|
||||
<ItemGroup>
|
||||
<TypeScriptCompile Include="test.ts" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(PkgNapa_DevTools)\Napa.TestAdapter.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<Robocopy Include="..\..\script\$(IntermediateOutputPath)\dist">
|
||||
<DestinationFolder>$(QTestDirToDeploy)\app\node_modules\plus-number-transporter</DestinationFolder>
|
||||
</Robocopy>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,10 +0,0 @@
|
|||
var assert = require('assert');
|
||||
var plusNumberTransporter = require('plus-number-transporter');
|
||||
|
||||
describe('Test suite for plus-number-transporter', function() {
|
||||
it('adds a given value', function() {
|
||||
var transporter: any = plusNumberTransporter.createPlusNumberTransporter(3);
|
||||
var result: number = plusNumberTransporter.add(transporter, 4);
|
||||
assert.equal(result, 7);
|
||||
});
|
||||
})
|
|
@ -1,71 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "object-transport.h"
|
||||
|
||||
#include <v8.h>
|
||||
|
||||
namespace napa {
|
||||
namespace module {
|
||||
namespace object_transport {
|
||||
|
||||
/// <summary> Convert a V8 uint32 array to uintptr. </summary>
|
||||
/// <param name="isolate"> V8 Isolate instance. </summary>
|
||||
/// <param name="source"> V8 uint32 array holding pointer value. </summary>
|
||||
/// <returns> The pair of converted pointer value and success/failure. </returns>
|
||||
inline std::pair<uintptr_t, bool> V8Uint32ArrayToUintptr(v8::Isolate* isolate, const v8::Local<v8::Array>& source) {
|
||||
if (source->Length() != UINTPTR_SIZE_IN_UINT32) {
|
||||
return std::make_pair(0, false);
|
||||
}
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
uintptr_t result = 0;
|
||||
for (uint32_t i = 0; i < source->Length(); ++i) {
|
||||
auto value = source->Get(context, i).ToLocalChecked();
|
||||
if (!value->IsUint32()) {
|
||||
return std::make_pair(0, false);
|
||||
}
|
||||
result |= static_cast<uintptr_t>(value->Uint32Value()) << 32 * i;
|
||||
}
|
||||
|
||||
return std::make_pair(result, true);
|
||||
}
|
||||
|
||||
/// <summary> Convert a V8 uint32 array to void pointer. </summary>
|
||||
/// <param name="isolate"> V8 Isolate instance. </summary>
|
||||
/// <param name="source"> V8 uint32 array holding pointer value. </summary>
|
||||
/// <returns> The pair of success and converted void pointer. </returns>
|
||||
template <typename T = void>
|
||||
inline std::pair<T*, bool> V8Uint32ArrayToPtr(v8::Isolate* isolate, const v8::Local<v8::Array>& source) {
|
||||
auto result = V8Uint32ArrayToUintptr(isolate, source);
|
||||
return std::make_pair(static_cast<T*>(reinterpret_cast<void*>(result.first)), result.second);
|
||||
}
|
||||
|
||||
/// <summary> Convert a pointer value to V8 Uint32 array. </summary>
|
||||
/// <param name="isolate"> V8 Isolate instance. </summary>
|
||||
/// <param name="source"> Pointer value. </summary>
|
||||
/// <returns> V8 uint32 array </returns>
|
||||
inline v8::Local<v8::Array> UintptrToV8Uint32Array(v8::Isolate* isolate, uintptr_t source) {
|
||||
v8::EscapableHandleScope scope(isolate);
|
||||
|
||||
auto context = isolate->GetCurrentContext();
|
||||
auto target = v8::Array::New(isolate, UINTPTR_SIZE_IN_UINT32);
|
||||
for (uint32_t i = 0; i < UINTPTR_SIZE_IN_UINT32; ++i) {
|
||||
auto value = static_cast<uint32_t>(source);
|
||||
target->CreateDataProperty(context, i, v8::Integer::NewFromUnsigned(isolate, value));
|
||||
source >>= 32;
|
||||
}
|
||||
|
||||
return scope.Escape(target);
|
||||
}
|
||||
|
||||
/// <summary> Convert a void pointer to V8 Uint32 array. </summary>
|
||||
/// <param name="isolate"> V8 Isolate instance. </summary>
|
||||
/// <param name="source"> Void pointer. </summary>
|
||||
/// <returns> V8 uint32 array </returns>
|
||||
inline v8::Local<v8::Array> PtrToV8Uint32Array(v8::Isolate* isolate, void* pointer) {
|
||||
return UintptrToV8Uint32Array(isolate, reinterpret_cast<uintptr_t>(pointer));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
|
||||
namespace napa {
|
||||
namespace module {
|
||||
|
||||
/// <summary>
|
||||
/// It makes a module to be able to use a host's native object.
|
||||
/// It doesn't guarantee that object destruction is perfectly detected by a module.
|
||||
/// So, Host application should make ObjectTransporter instance returned by Serialized() alive until a request is processed.
|
||||
/// </summary>
|
||||
class ObjectTransporter final {
|
||||
public:
|
||||
|
||||
/// <summary> Constructor. </summary>
|
||||
/// <param name="object"> Shared pointer to object instance. </param>
|
||||
/// <param name="type"> Object type information. </param>
|
||||
/// <remarks> Serialize() plays a role of factory to create an instance. </remarks>
|
||||
ObjectTransporter(std::shared_ptr<void> object,
|
||||
std::type_index type)
|
||||
: _object(object)
|
||||
, _type(type) {}
|
||||
|
||||
/// <summary> Create an ObjectTransporter instance and its pointer value to pass to a module. </summary>
|
||||
/// <param name="object"> Object to be accessed by a module. </param>
|
||||
/// <returns> Pair of ObjectTransporter instance and pointer value. </returns>
|
||||
/// <remarks> Since a module doesn't know object's lifetime, this API is good to pass a global object. </remarks>
|
||||
template <typename T>
|
||||
static std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> Serialize(T* object) {
|
||||
return Serialize(std::shared_ptr<T>(object, [](T*) {}));
|
||||
}
|
||||
|
||||
/// <summary> Create an ObjectTransporter instance and its pointer value to pass to a module. </summary>
|
||||
/// <param name="object"> Shared pointer type of object to be accessed by a module. </param>
|
||||
/// <returns> Pair of ObjectTransporter instance and pointer value. </returns>
|
||||
template <typename T>
|
||||
static std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> Serialize(std::shared_ptr<T> object) {
|
||||
auto transporter = std::make_unique<ObjectTransporter>(
|
||||
std::static_pointer_cast<void>(std::move(object)),
|
||||
typeid(T));
|
||||
return std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>>(
|
||||
reinterpret_cast<uintptr_t>(transporter.get()),
|
||||
std::move(transporter));
|
||||
}
|
||||
|
||||
/// <summary> Get a passing object instance from pointer value of ObjectTransporter. </summary>
|
||||
/// <param name="pointer"> Pointer value of ObjectTransporter instance. </param>
|
||||
/// <returns> Passing object instance. </returns>
|
||||
template <typename T>
|
||||
static std::shared_ptr<T> Deserialize(uintptr_t pointer) {
|
||||
auto transporter = reinterpret_cast<ObjectTransporter*>(pointer);
|
||||
if (std::type_index(typeid(T)) != transporter->_type) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::static_pointer_cast<T>(transporter->_object);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// <summary> Pointer to passing object. </summary>
|
||||
std::shared_ptr<void> _object;
|
||||
|
||||
/// <summary> Type information of passing object. </summary>
|
||||
std::type_index _type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TransportableObject : public std::enable_shared_from_this<TransportableObject<T>> {
|
||||
public:
|
||||
|
||||
std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>> Serialize() {
|
||||
auto transporter = std::make_unique<ObjectTransporter>(
|
||||
std::static_pointer_cast<void>(shared_from_this()),
|
||||
typeid(T));
|
||||
return std::pair<uintptr_t, std::unique_ptr<ObjectTransporter>>(
|
||||
reinterpret_cast<uintptr_t>(transporter.get()),
|
||||
std::move(transporter));
|
||||
}
|
||||
};
|
||||
|
||||
static const uint32_t UINTPTR_SIZE_IN_UINT32 = static_cast<uint32_t>(sizeof(uintptr_t) / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
namespace module {
|
||||
namespace object_transport {
|
||||
|
||||
/// <summary> Convert a pointer value to uint32 array. </summary>
|
||||
/// <param name="source"> Pointer value. </summary>
|
||||
/// <returns> uint32 array. </returns>
|
||||
inline std::array<uint32_t, UINTPTR_SIZE_IN_UINT32> UintptrToUint32Array(uintptr_t source) {
|
||||
std::array<uint32_t, UINTPTR_SIZE_IN_UINT32> target = {};
|
||||
for (uint32_t i = 0; i < UINTPTR_SIZE_IN_UINT32; ++i, source >>= 32) {
|
||||
target[i] = static_cast<uint32_t>(source);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/// <summary> Convert a uint32 array to uintptr. </summary>
|
||||
/// <param name="source"> a uint32 array holding pointer value. </summary>
|
||||
/// <returns> Converted pointer value. </returns>
|
||||
inline uintptr_t Uint32ArrayToUintptr(const std::array<uint32_t, UINTPTR_SIZE_IN_UINT32>& source) {
|
||||
uintptr_t result = 0;
|
||||
for (uint32_t i = 0; i < UINTPTR_SIZE_IN_UINT32; ++i) {
|
||||
result |= static_cast<uintptr_t>(source[i]) << 32 * i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -84,7 +84,6 @@
|
|||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)\worker-tests.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)\tasks-tests.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)\object-transport-v8-helpers-tests.cpp" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Test artifacts binplace -->
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#include <catch.hpp>
|
||||
#include <napa/module/object-transport-v8-helpers.h>
|
||||
|
||||
using namespace napa::module;
|
||||
|
||||
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
||||
public:
|
||||
|
||||
virtual void* Allocate(size_t length) override {
|
||||
void* data = AllocateUninitialized(length);
|
||||
return memset(data, 0, length);
|
||||
}
|
||||
|
||||
virtual void* AllocateUninitialized(size_t length) override {
|
||||
return malloc(length);
|
||||
}
|
||||
|
||||
virtual void Free(void* data, size_t length) override {
|
||||
free(data);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("v8-helpers works as expected", "[v8-helpers]") {
|
||||
ArrayBufferAllocator allocator;
|
||||
v8::Isolate::CreateParams createParams;
|
||||
createParams.array_buffer_allocator = &allocator;
|
||||
auto isolate = v8::Isolate::New(createParams);
|
||||
|
||||
{
|
||||
v8::Locker locker(isolate);
|
||||
|
||||
v8::Isolate::Scope isolateScope(isolate);
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate);
|
||||
v8::Context::Scope contextScope(context);
|
||||
|
||||
SECTION("pointer value is serialized/deserialized correctly", "[v8-helpers]") {
|
||||
auto source = reinterpret_cast<uintptr_t>(isolate);
|
||||
auto v8array = object_transport::UintptrToV8Uint32Array(isolate, source);
|
||||
auto target = object_transport::V8Uint32ArrayToUintptr(isolate, v8array);
|
||||
REQUIRE(target.second == true);
|
||||
REQUIRE(target.first == source);
|
||||
}
|
||||
|
||||
SECTION("pointer is serialized/deserialized correctly", "[v8-helpers]") {
|
||||
auto v8array = object_transport::PtrToV8Uint32Array(isolate, isolate);
|
||||
auto target = object_transport::V8Uint32ArrayToPtr(isolate, v8array);
|
||||
REQUIRE(target.second == true);
|
||||
REQUIRE(target.first == isolate);
|
||||
}
|
||||
}
|
||||
|
||||
isolate->Dispose();
|
||||
}
|
|
@ -116,7 +116,7 @@ TEST_CASE("tasks", "[tasks]") {
|
|||
request.arguments = { NAPA_STRING_REF("3"), NAPA_STRING_REF("5") };
|
||||
|
||||
ExecuteResponse response;
|
||||
TimeoutTaskDecorator<ExecuteTask>(30ms, request, [&](ExecuteResponse res) {
|
||||
TimeoutTaskDecorator<ExecuteTask>(100ms, request, [&](ExecuteResponse res) {
|
||||
response = std::move(res);
|
||||
}).Execute();
|
||||
|
||||
|
@ -159,7 +159,7 @@ TEST_CASE("tasks", "[tasks]") {
|
|||
request2.arguments = { NAPA_STRING_REF("3"), NAPA_STRING_REF("5") };
|
||||
|
||||
ExecuteResponse response2;
|
||||
TimeoutTaskDecorator<ExecuteTask>(30ms, request2, [&](ExecuteResponse res) {
|
||||
TimeoutTaskDecorator<ExecuteTask>(100ms, request2, [&](ExecuteResponse res) {
|
||||
response2 = std::move(res);
|
||||
}).Execute();
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ TEST_CASE("worker notifies idle condition", "[scheduler-worker]") {
|
|||
worker->Schedule(std::make_shared<TestTask>());
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
bool idleNotificationReceived = (cv.wait_for(lock, std::chrono::milliseconds(500)) == std::cv_status::no_timeout);
|
||||
bool idleNotificationReceived = (cv.wait_for(lock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout);
|
||||
|
||||
REQUIRE(idleNotificationReceived == true);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="module\file-system-helpers-tests.cpp" />
|
||||
<ClCompile Include="module\module-resolver-tests.cpp" />
|
||||
<ClCompile Include="object-transport\object-transport-tests.cpp" />
|
||||
<ClCompile Include="scheduler\scheduler-tests.cpp" />
|
||||
<ClCompile Include="scheduler\timeout-service-tests.cpp" />
|
||||
<ClCompile Include="settings\parser-tests.cpp" />
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
#include <catch.hpp>
|
||||
|
||||
#include <napa/module/object-transport.h>
|
||||
|
||||
using namespace napa;
|
||||
using namespace napa::module;
|
||||
|
||||
class Vehicle {};
|
||||
class Car : public Vehicle {};
|
||||
class Sky {};
|
||||
|
||||
TEST_CASE("object-transporter serializes and deserializes a stack object correctly.", "[object-transporter]") {
|
||||
Car car;
|
||||
auto transporter = ObjectTransporter::Serialize<Car>(&car);
|
||||
|
||||
SECTION("object-transporter deserializes an object correctly.") {
|
||||
auto object = ObjectTransporter::Deserialize<Car>(transporter.first);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(object.get() == &car);
|
||||
}
|
||||
|
||||
SECTION("object-transporter failes on a parent object.") {
|
||||
auto object = ObjectTransporter::Deserialize<Vehicle>(transporter.first);
|
||||
REQUIRE(object == nullptr);
|
||||
}
|
||||
|
||||
SECTION("object-transporter failes on different type of object.") {
|
||||
auto object = ObjectTransporter::Deserialize<Sky>(transporter.first);
|
||||
REQUIRE(object == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("object-transporter serializes and deserializes an heap object correctly.", "[object-transporter]") {
|
||||
auto vehicle = std::make_shared<Vehicle>();
|
||||
auto transporter = ObjectTransporter::Serialize<Vehicle>(vehicle);
|
||||
|
||||
SECTION("object-transporter deserializes an object correctly.") {
|
||||
auto object = ObjectTransporter::Deserialize<Vehicle>(transporter.first);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(object.get() == vehicle.get());
|
||||
}
|
||||
|
||||
SECTION("object-transporter failes on a child object.") {
|
||||
auto object = ObjectTransporter::Deserialize<Car>(transporter.first);
|
||||
REQUIRE(object == nullptr);
|
||||
}
|
||||
|
||||
SECTION("object-transporter failes on different type of object.") {
|
||||
auto object = ObjectTransporter::Deserialize<Sky>(transporter.first);
|
||||
REQUIRE(object == nullptr);
|
||||
}
|
||||
|
||||
SECTION("object-transporter deserializes correctly after Vehicle instance is destroyed.") {
|
||||
auto pointer = vehicle.get();
|
||||
vehicle.reset();
|
||||
auto object = ObjectTransporter::Deserialize<Vehicle>(transporter.first);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(object.get() == pointer);
|
||||
}
|
||||
}
|
||||
|
||||
class Portable : public TransportableObject<Portable> {};
|
||||
|
||||
TEST_CASE("object-transporter serializes and deserializes an TransportableObject object correctly.", "[object-transporter]") {
|
||||
auto portable = std::make_shared<Portable>();
|
||||
auto transporter = portable->Serialize();
|
||||
|
||||
SECTION("object-transporter deserializes an object correctly.") {
|
||||
auto object = ObjectTransporter::Deserialize<Portable>(transporter.first);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(object.get() == portable.get());
|
||||
}
|
||||
|
||||
SECTION("object-transporter failes on different type of object.") {
|
||||
auto object = ObjectTransporter::Deserialize<Car>(transporter.first);
|
||||
REQUIRE(object == nullptr);
|
||||
}
|
||||
|
||||
SECTION("object-transporter deserializes correctly after Car instance is destroyed.") {
|
||||
auto pointer = portable.get();
|
||||
portable.reset();
|
||||
auto object = ObjectTransporter::Deserialize<Portable>(transporter.first);
|
||||
REQUIRE(object != nullptr);
|
||||
REQUIRE(object.get() == pointer);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("object-transport converts correctly between pointer value and array.", "[object-transporter]") {
|
||||
auto car = std::make_unique<Car>();
|
||||
|
||||
auto source = object_transport::UintptrToUint32Array(reinterpret_cast<uintptr_t>(car.get()));
|
||||
auto target = object_transport::Uint32ArrayToUintptr(source);
|
||||
|
||||
REQUIRE(car.get() == reinterpret_cast<Car*>(target));
|
||||
}
|
Загрузка…
Ссылка в новой задаче