mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-05-06 04:02:57 +00:00
1.3
This commit is contained in:
parent
7971c836b7
commit
737397da11
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@ -9,6 +9,14 @@
|
||||
"program": "test/main.dart",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"program": "test/template_test/.dart_tool/build/entrypoint/build.dart",
|
||||
"name": "template_test",
|
||||
"cwd": "template_test",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"args": ["serve"],
|
||||
}
|
||||
]
|
||||
}
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Esi Ur
|
||||
Copyright (c) 2019-2021 Esiur Foundation, Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
41
bin/esiur.dart
Normal file
41
bin/esiur.dart
Normal file
@ -0,0 +1,41 @@
|
||||
import 'package:args/args.dart';
|
||||
|
||||
void main(List<String> arguments) {
|
||||
if (arguments.length == 0) {
|
||||
// print help
|
||||
print("Esiur package command line");
|
||||
print("");
|
||||
print("Usage: <command> [arguments]");
|
||||
print("");
|
||||
print("Available commands:");
|
||||
print("\tget-template\tGet a template from an IIP link.");
|
||||
print("\tversion: print esiur version.");
|
||||
print("");
|
||||
print("Global options:");
|
||||
print("\t-u, --username\tAuthentication username");
|
||||
print("\t-p, --password\tAuthentication password");
|
||||
}
|
||||
|
||||
var cmd = arguments[0];
|
||||
|
||||
if (cmd == "get-template") {
|
||||
if (arguments.length < 2) {
|
||||
print("Please provide an IIP link");
|
||||
return;
|
||||
}
|
||||
|
||||
var link = arguments[1];
|
||||
|
||||
final parser = ArgParser()
|
||||
..addFlag('username', abbr: 'u')
|
||||
..addFlag('password', abbr: 'p');
|
||||
|
||||
var results = parser.parse(arguments.skip(2));
|
||||
|
||||
var username = results['username'];
|
||||
var password = results['password'];
|
||||
|
||||
// make template
|
||||
|
||||
}
|
||||
}
|
7
build.yaml
Normal file
7
build.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
builders:
|
||||
services:
|
||||
import: "package:esiur/builder.dart"
|
||||
builder_factories: ["iipService"]
|
||||
build_extensions: {".iip.yaml": [".iip.dart"]}
|
||||
auto_apply: dependents
|
||||
build_to: source
|
47
lib/builder.dart
Normal file
47
lib/builder.dart
Normal file
@ -0,0 +1,47 @@
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
import 'package:build/build.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
Builder iipService(BuilderOptions options) {
|
||||
return LibraryBuilder(TemplateGenerator(), generatedExtension: '.info.dart');
|
||||
}
|
||||
|
||||
class TemplateBuilder implements Builder {
|
||||
//BuilderOptions options;
|
||||
String _fileName;
|
||||
TemplateBuilder([BuilderOptions options]) : _fileName = _get_dest(options);
|
||||
|
||||
@override
|
||||
Future build(BuildStep buildStep) async {
|
||||
final id = AssetId(buildStep.inputId.package, _fileName);
|
||||
|
||||
// generate
|
||||
var content = "Testing";
|
||||
|
||||
await buildStep.writeAsString(id, content);
|
||||
}
|
||||
|
||||
static String _get_dest(BuilderOptions options) {
|
||||
const defaultDestination = 'lib/src/iip_template.dart';
|
||||
if (options == null) return defaultDestination;
|
||||
if (options.config == null) return defaultDestination;
|
||||
return options.config['destination_file'] as String ?? defaultDestination;
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, List<String>> get buildExtensions {
|
||||
return {
|
||||
'.iip.yaml': [".iip.dart"]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class TemplateGenerator extends Generator {
|
||||
@override
|
||||
String generate(LibraryReader library, BuildStep buildStep) {
|
||||
return '''
|
||||
// Source library: ${library.element.source.uri}
|
||||
const Testinggggg = 3;
|
||||
''';
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ export 'src/Resource/Template/MemberTemplate.dart';
|
||||
export 'src/Resource/Template/MemberType.dart';
|
||||
export 'src/Resource/Template/PropertyPermission.dart';
|
||||
export 'src/Resource/Template/PropertyTemplate.dart';
|
||||
export 'src/Resource/Template/ResourceTemplate.dart';
|
||||
export 'src/Resource/Template/TypeTemplate.dart';
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Core
|
||||
@ -44,7 +44,8 @@ export 'src/Data/Structure.dart';
|
||||
export 'src/Data/StructureComparisonResult.dart';
|
||||
export 'src/Data/StructureMetadata.dart';
|
||||
export 'src/Data/ValueObject.dart';
|
||||
|
||||
export 'src/Data/IRecord.dart';
|
||||
export 'src/Data/Record.dart';
|
||||
// -----------------------------------------------------------------
|
||||
// Net
|
||||
export 'src/Net/NetworkBuffer.dart';
|
||||
|
@ -1,63 +1,50 @@
|
||||
import 'AsyncReply.dart';
|
||||
|
||||
class AsyncBag<T> extends AsyncReply<List<T>>
|
||||
{
|
||||
|
||||
class AsyncBag<T> extends AsyncReply<List<T>> {
|
||||
List<AsyncReply<T>> _replies = new List<AsyncReply<T>>();
|
||||
List<T> _results = new List<T>();
|
||||
List<T> _results = <T>[];
|
||||
|
||||
int _count = 0;
|
||||
bool _sealedBag = false;
|
||||
|
||||
seal()
|
||||
{
|
||||
Type arrayType;
|
||||
|
||||
seal() {
|
||||
//print("SEALED");
|
||||
|
||||
if (_sealedBag)
|
||||
return;
|
||||
if (_sealedBag) return;
|
||||
|
||||
_sealedBag = true;
|
||||
|
||||
if (_results.length == 0)
|
||||
trigger(new List<T>());
|
||||
if (_results.length == 0) trigger(new List<T>());
|
||||
|
||||
for (var i = 0; i < _results.length; i++)
|
||||
{
|
||||
for (var i = 0; i < _results.length; i++) {
|
||||
var k = _replies[i];
|
||||
var index = i;
|
||||
|
||||
k.then<dynamic>((r)
|
||||
{
|
||||
k.then<dynamic>((r) {
|
||||
_results[index] = r;
|
||||
_count++;
|
||||
//print("Seal ${_count}/${_results.length}");
|
||||
if (_count == _results.length)
|
||||
trigger(_results);
|
||||
if (_count == _results.length) trigger(_results);
|
||||
}).error((ex) {
|
||||
triggerError(ex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
add(AsyncReply<T> reply)
|
||||
{
|
||||
if (!_sealedBag)
|
||||
{
|
||||
add(AsyncReply<T> reply) {
|
||||
if (!_sealedBag) {
|
||||
_results.add(null);
|
||||
_replies.add(reply);
|
||||
}
|
||||
}
|
||||
|
||||
addBag(AsyncBag<T> bag)
|
||||
{
|
||||
addBag(AsyncBag<T> bag) {
|
||||
bag._replies.forEach((r) {
|
||||
add(r);
|
||||
});
|
||||
}
|
||||
|
||||
AsyncBag()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AsyncBag() {}
|
||||
}
|
||||
|
@ -26,78 +26,58 @@ import 'dart:core';
|
||||
import 'AsyncException.dart';
|
||||
import 'ProgressType.dart';
|
||||
|
||||
class AsyncReply<T> implements Future<T>
|
||||
{
|
||||
|
||||
class AsyncReply<T> implements Future<T> {
|
||||
List<Function(T)> _callbacks = new List<Function(T)>();
|
||||
|
||||
T _result;
|
||||
|
||||
List<Function(AsyncException)> _errorCallbacks = new List<Function(AsyncException)>();
|
||||
List<Function(AsyncException)> _errorCallbacks =
|
||||
new List<Function(AsyncException)>();
|
||||
|
||||
List<Function(ProgressType, int, int)> _progressCallbacks = new List<Function(ProgressType, int, int)>();
|
||||
List<Function(ProgressType, int, int)> _progressCallbacks =
|
||||
new List<Function(ProgressType, int, int)>();
|
||||
|
||||
List<Function(T)> _chunkCallbacks = new List<Function(T)>();
|
||||
|
||||
|
||||
|
||||
bool _resultReady = false;
|
||||
AsyncException _exception;
|
||||
|
||||
|
||||
bool get ready
|
||||
{
|
||||
bool get ready {
|
||||
return _resultReady;
|
||||
}
|
||||
|
||||
set ready(value)
|
||||
{
|
||||
set ready(value) {
|
||||
_resultReady = value;
|
||||
}
|
||||
|
||||
T get result
|
||||
{
|
||||
T get result {
|
||||
return _result;
|
||||
}
|
||||
|
||||
setResultReady(bool val)
|
||||
{
|
||||
setResultReady(bool val) {
|
||||
_resultReady = val;
|
||||
}
|
||||
|
||||
|
||||
AsyncReply<T> next(Function(T) callback)
|
||||
{
|
||||
AsyncReply<T> next(Function(T) callback) {
|
||||
then(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
AsyncReply<R> then<R>(FutureOr<R> onValue(T value), {Function onError})
|
||||
{
|
||||
AsyncReply<R> then<R>(FutureOr<R> onValue(T value), {Function onError}) {
|
||||
_callbacks.add(onValue);
|
||||
if (onError != null)
|
||||
{
|
||||
if (onError is Function(dynamic, dynamic))
|
||||
{
|
||||
if (onError != null) {
|
||||
if (onError is Function(dynamic, dynamic)) {
|
||||
_errorCallbacks.add((ex) => onError(ex, null));
|
||||
}
|
||||
else if (onError is Function(dynamic))
|
||||
{
|
||||
} else if (onError is Function(dynamic)) {
|
||||
_errorCallbacks.add(onError);
|
||||
}
|
||||
else if (onError is Function())
|
||||
{
|
||||
} else if (onError is Function()) {
|
||||
_errorCallbacks.add((ex) => onError());
|
||||
}
|
||||
else if (onError is Function(Object, StackTrace))
|
||||
{
|
||||
} else if (onError is Function(Object, StackTrace)) {
|
||||
_errorCallbacks.add((ex) => onError(ex, null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_resultReady)
|
||||
onValue(result);
|
||||
if (_resultReady) onValue(result);
|
||||
|
||||
if (R == Null)
|
||||
return null;
|
||||
@ -105,57 +85,43 @@ class AsyncReply<T> implements Future<T>
|
||||
return this as AsyncReply<R>;
|
||||
}
|
||||
|
||||
AsyncReply<T> whenComplete(FutureOr action())
|
||||
{
|
||||
AsyncReply<T> whenComplete(FutureOr action()) {
|
||||
return this;
|
||||
//_callbacks.add(action);
|
||||
}
|
||||
|
||||
Stream<T> asStream()
|
||||
{
|
||||
Stream<T> asStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
AsyncReply<T> catchError(Function onError, {bool test(Object error)})
|
||||
{
|
||||
AsyncReply<T> catchError(Function onError, {bool test(Object error)}) {
|
||||
return this.error(onError);
|
||||
}
|
||||
|
||||
AsyncReply<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()})
|
||||
{
|
||||
AsyncReply<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()}) {
|
||||
return this;
|
||||
}
|
||||
|
||||
AsyncReply<T> error(Function(dynamic) callback)
|
||||
{
|
||||
AsyncReply<T> error(Function(dynamic) callback) {
|
||||
_errorCallbacks.add(callback);
|
||||
|
||||
if (_exception != null)
|
||||
callback(_exception);
|
||||
if (_exception != null) callback(_exception);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
AsyncReply<T> progress(Function(ProgressType, int, int) callback)
|
||||
{
|
||||
AsyncReply<T> progress(Function(ProgressType, int, int) callback) {
|
||||
_progressCallbacks.add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
AsyncReply<T> chunk(Function(T) callback)
|
||||
{
|
||||
AsyncReply<T> chunk(Function(T) callback) {
|
||||
_chunkCallbacks.add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
void trigger(T result)
|
||||
{
|
||||
|
||||
// lock (callbacksLock)
|
||||
// {
|
||||
if (_resultReady)
|
||||
return;
|
||||
AsyncReply<T> trigger(T result) {
|
||||
if (_resultReady) return this;
|
||||
|
||||
_result = result;
|
||||
_resultReady = true;
|
||||
@ -164,14 +130,11 @@ class AsyncReply<T> implements Future<T>
|
||||
x(result);
|
||||
});
|
||||
|
||||
// }
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
triggerError(Exception exception)
|
||||
{
|
||||
if (_resultReady)
|
||||
return;
|
||||
AsyncReply<T> triggerError(Exception exception) {
|
||||
if (_resultReady) return this;
|
||||
|
||||
if (exception is AsyncException)
|
||||
_exception = exception;
|
||||
@ -189,33 +152,29 @@ class AsyncReply<T> implements Future<T>
|
||||
});
|
||||
//}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
triggerProgress(ProgressType type, int value, int max)
|
||||
{
|
||||
AsyncReply<T> triggerProgress(ProgressType type, int value, int max) {
|
||||
_progressCallbacks.forEach((x) {
|
||||
x(type, value, max);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
triggerChunk(T value)
|
||||
{
|
||||
AsyncReply<T> triggerChunk(T value) {
|
||||
_chunkCallbacks.forEach((x) {
|
||||
x(value);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
AsyncReply.ready(T result)
|
||||
{
|
||||
AsyncReply.ready(T result) {
|
||||
_resultReady = true;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
AsyncReply()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AsyncReply() {}
|
||||
}
|
@ -31,5 +31,9 @@ enum ExceptionCode
|
||||
SetPropertyDenied,
|
||||
ReadOnlyProperty,
|
||||
GeneralFailure,
|
||||
AddToStoreFailed
|
||||
AddToStoreFailed,
|
||||
NotAttached,
|
||||
AlreadyListened,
|
||||
AlreadyUnlistened,
|
||||
NotListenable
|
||||
}
|
@ -32,7 +32,7 @@ import 'Guid.dart';
|
||||
|
||||
class BinaryList
|
||||
{
|
||||
var _list = new List<int>();
|
||||
var _list = <int>[];
|
||||
|
||||
int get length => _list.length;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,42 +30,35 @@ import 'Guid.dart';
|
||||
* Created by Ahmed Zamil on 6/10/2019.
|
||||
*/
|
||||
|
||||
|
||||
const UNIX_EPOCH = 621355968000000000;
|
||||
const TWO_PWR_32 = (1 << 16) * (1 << 16);
|
||||
|
||||
class DC with IterableMixin<int>
|
||||
{
|
||||
|
||||
class DC with IterableMixin<int> {
|
||||
Uint8List _data;
|
||||
ByteData _dv;
|
||||
|
||||
DC(int length)
|
||||
{
|
||||
DC(int length) {
|
||||
_data = new Uint8List(length);
|
||||
_dv = ByteData.view(_data.buffer);
|
||||
}
|
||||
|
||||
DC.fromUint8Array(Uint8List array)
|
||||
{
|
||||
DC.fromUint8Array(Uint8List array) {
|
||||
_data = array;
|
||||
_dv = ByteData.view(_data.buffer);
|
||||
}
|
||||
|
||||
DC.fromList(List<int> list)
|
||||
{
|
||||
DC.fromList(List<int> list) {
|
||||
_data = Uint8List.fromList(list);
|
||||
_dv = ByteData.view(_data.buffer);
|
||||
}
|
||||
|
||||
operator [](index) => _data[index];
|
||||
operator []=(index,value) => _data[index] = value;
|
||||
int operator [](int index) => _data[index];
|
||||
operator []=(int index, int value) => _data[index] = value;
|
||||
int get length => _data.length;
|
||||
|
||||
Iterator<int> get iterator => _data.iterator;
|
||||
|
||||
static DC hexToBytes(String value)
|
||||
{
|
||||
static DC hexToBytes(String value) {
|
||||
// convert hex to Uint8Array
|
||||
var rt = new DC(value.length ~/ 2);
|
||||
for (var i = 0; i < rt.length; i++)
|
||||
@ -73,235 +66,184 @@ class DC with IterableMixin<int>
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC boolToBytes(value)
|
||||
{
|
||||
static DC boolToBytes(value) {
|
||||
var rt = new DC(1);
|
||||
rt.setBoolean(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
static DC guidToBytes(Guid value)
|
||||
{
|
||||
static DC guidToBytes(Guid value) {
|
||||
var rt = new DC(16);
|
||||
rt.setGuid(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC guidArrayToBytes(List<Guid> value)
|
||||
{
|
||||
static DC guidArrayToBytes(List<Guid> value) {
|
||||
var rt = new DC(value.length * 16);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setGuid(i * 16, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setGuid(i * 16, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC boolArrayToBytes(List<bool> value)
|
||||
{
|
||||
static DC boolArrayToBytes(List<bool> value) {
|
||||
var rt = new DC(value.length);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt[i] = value[i] ? 1 : 0;
|
||||
for (var i = 0; i < value.length; i++) rt[i] = value[i] ? 1 : 0;
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int8ToBytes(value)
|
||||
{
|
||||
static DC int8ToBytes(value) {
|
||||
var rt = new DC(1);
|
||||
rt.setInt8(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int8ArrayToBytes(Int8List value)
|
||||
{
|
||||
static DC int8ArrayToBytes(Int8List value) {
|
||||
var rt = new DC(value.length);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setInt8(i, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setInt8(i, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static DC uint8ToBytes(value)
|
||||
{
|
||||
static DC uint8ToBytes(value) {
|
||||
var rt = new DC(1);
|
||||
rt.setUint8(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint8ArrayToBytes(Uint8List value)
|
||||
{
|
||||
static DC uint8ArrayToBytes(Uint8List value) {
|
||||
var rt = new DC(value.length);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setUint8(i, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setUint8(i, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC charToBytes(int value)
|
||||
{
|
||||
static DC charToBytes(int value) {
|
||||
var rt = new DC(2);
|
||||
rt.setChar(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC charArrayToBytes(Uint16List value)
|
||||
{
|
||||
static DC charArrayToBytes(Uint16List value) {
|
||||
var rt = new DC(value.length * 2);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setChar(i*2, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setChar(i * 2, value[i]);
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int16ToBytes(int value)
|
||||
{
|
||||
static DC int16ToBytes(int value) {
|
||||
var rt = new DC(2);
|
||||
rt.setInt16(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int16ArrayToBytes(List<int> value)
|
||||
{
|
||||
static DC int16ArrayToBytes(List<int> value) {
|
||||
var rt = new DC(value.length * 2);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setInt16(i*2, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setInt16(i * 2, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint16ToBytes(int value)
|
||||
{
|
||||
static DC uint16ToBytes(int value) {
|
||||
var rt = new DC(2);
|
||||
rt.setUint16(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint16ArrayToBytes(Uint16List value)
|
||||
{
|
||||
static DC uint16ArrayToBytes(Uint16List value) {
|
||||
var rt = new DC(value.length * 2);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setUint16(i*2, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setUint16(i * 2, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int32ToBytes(int value)
|
||||
{
|
||||
static DC int32ToBytes(int value) {
|
||||
var rt = new DC(4);
|
||||
rt.setInt32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int32ArrayToBytes(Int32List value)
|
||||
{
|
||||
static DC int32ArrayToBytes(Int32List value) {
|
||||
var rt = new DC(value.length * 4);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setInt32(i*4, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setInt32(i * 4, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint32ToBytes(int value)
|
||||
{
|
||||
static DC uint32ToBytes(int value) {
|
||||
var rt = new DC(4);
|
||||
rt.setUint32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint32ArrayToBytes(Uint32List value)
|
||||
{
|
||||
static DC uint32ArrayToBytes(Uint32List value) {
|
||||
var rt = new DC(value.length * 4);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setUint32(i*4, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setUint32(i * 4, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC float32ToBytes(double value)
|
||||
{
|
||||
static DC float32ToBytes(double value) {
|
||||
var rt = new DC(4);
|
||||
rt.setFloat32(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC float32ArrayToBytes(Float32List value)
|
||||
{
|
||||
static DC float32ArrayToBytes(Float32List value) {
|
||||
var rt = new DC(value.length * 4);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setFloat32(i*4, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setFloat32(i * 4, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int64ToBytes(int value)
|
||||
{
|
||||
static DC int64ToBytes(int value) {
|
||||
var rt = new DC(8);
|
||||
rt.setInt64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC int64ArrayToBytes(Int64List value)
|
||||
{
|
||||
static DC int64ArrayToBytes(Int64List value) {
|
||||
var rt = new DC(value.length * 8);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setInt64(i*8, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setInt64(i * 8, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint64ToBytes(int value)
|
||||
{
|
||||
static DC uint64ToBytes(int value) {
|
||||
var rt = new DC(8);
|
||||
rt.setUint64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC uint64ArrayToBytes(Uint64List value)
|
||||
{
|
||||
static DC uint64ArrayToBytes(Uint64List value) {
|
||||
var rt = new DC(value.length * 8);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setUint64(i*8, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setUint64(i * 8, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC float64ToBytes(double value)
|
||||
{
|
||||
static DC float64ToBytes(double value) {
|
||||
var rt = new DC(8);
|
||||
rt.setFloat64(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC float64ArrayToBytes(Float64List value)
|
||||
{
|
||||
static DC float64ArrayToBytes(Float64List value) {
|
||||
var rt = new DC(value.length * 8);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setFloat64(i*8, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setFloat64(i * 8, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC dateTimeToBytes(DateTime value)
|
||||
{
|
||||
static DC dateTimeToBytes(DateTime value) {
|
||||
var rt = new DC(8);
|
||||
rt.setDateTime(0, value);
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static DC dateTimeArrayToBytes(List<DateTime> value)
|
||||
{
|
||||
static DC dateTimeArrayToBytes(List<DateTime> value) {
|
||||
var rt = new DC(value.length * 8);
|
||||
for(var i = 0; i < value.length; i++)
|
||||
rt.setDateTime(i*8, value[i]);
|
||||
for (var i = 0; i < value.length; i++) rt.setDateTime(i * 8, value[i]);
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
static DC stringToBytes(String value)
|
||||
{
|
||||
static DC stringToBytes(String value) {
|
||||
var bytes = utf8.encode(value);
|
||||
var rt = new DC.fromList(bytes);
|
||||
return rt;
|
||||
}
|
||||
|
||||
static DC stringArrayToBytes(List<String> value)
|
||||
{
|
||||
static DC stringArrayToBytes(List<String> value) {
|
||||
var list = new BinaryList();
|
||||
for(var i = 0; i < value.length; i++)
|
||||
{
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var s = DC.stringToBytes(value[i]);
|
||||
list.addUint32(s.length).addUint8Array(s.toArray());
|
||||
}
|
||||
@ -309,8 +251,7 @@ class DC with IterableMixin<int>
|
||||
return list.toDC();
|
||||
}
|
||||
|
||||
DC append(DC src, int offset, int length)
|
||||
{
|
||||
DC append(DC src, int offset, int length) {
|
||||
//if (!(src is DC))
|
||||
// src = new DC(src);
|
||||
|
||||
@ -325,205 +266,165 @@ class DC with IterableMixin<int>
|
||||
return this;
|
||||
}
|
||||
|
||||
set(DC dc, int offset)
|
||||
{
|
||||
set(DC dc, int offset) {
|
||||
_data.setRange(offset, offset + dc.length, dc._data);
|
||||
}
|
||||
|
||||
static combine(a, aOffset, aLength, b, bOffset, bLength)
|
||||
{
|
||||
if (!(a is DC))
|
||||
a = new DC(a);
|
||||
if (!(b is DC))
|
||||
b = new DC(b);
|
||||
static combine(a, aOffset, aLength, b, bOffset, bLength) {
|
||||
if (!(a is DC)) a = new DC(a);
|
||||
if (!(b is DC)) b = new DC(b);
|
||||
|
||||
a = a.clip(aOffset, aLength);
|
||||
b = b.clip(bOffset, bLength);
|
||||
|
||||
var rt = new DC(a.length + b.length);
|
||||
|
||||
|
||||
rt.set(a, 0);
|
||||
rt.set(b, a.length);
|
||||
return rt;
|
||||
}
|
||||
|
||||
DC clip(offset, length)
|
||||
{
|
||||
return DC.fromUint8Array(Uint8List.fromList(_data.getRange(offset, offset + length).toList()));
|
||||
DC clip(offset, length) {
|
||||
return DC.fromUint8Array(
|
||||
Uint8List.fromList(_data.getRange(offset, offset + length).toList()));
|
||||
}
|
||||
|
||||
getInt8(int offset)
|
||||
{
|
||||
getInt8(int offset) {
|
||||
return _dv.getInt8(offset);
|
||||
}
|
||||
|
||||
getUint8(int offset)
|
||||
{
|
||||
getUint8(int offset) {
|
||||
return _data[offset]; // this.dv.getUint8(offset);
|
||||
}
|
||||
|
||||
getInt16(int offset)
|
||||
{
|
||||
getInt16(int offset) {
|
||||
return _dv.getInt16(offset);
|
||||
}
|
||||
|
||||
getUint16(int offset)
|
||||
{
|
||||
getUint16(int offset) {
|
||||
return _dv.getUint16(offset);
|
||||
}
|
||||
|
||||
getInt32(int offset)
|
||||
{
|
||||
getInt32(int offset) {
|
||||
return _dv.getInt32(offset);
|
||||
}
|
||||
|
||||
getUint32(int offset)
|
||||
{
|
||||
getUint32(int offset) {
|
||||
return _dv.getUint32(offset);
|
||||
}
|
||||
|
||||
getFloat32(int offset)
|
||||
{
|
||||
getFloat32(int offset) {
|
||||
return _dv.getFloat32(offset);
|
||||
}
|
||||
|
||||
getFloat64(int offset)
|
||||
{
|
||||
getFloat64(int offset) {
|
||||
return _dv.getFloat64(offset);
|
||||
}
|
||||
|
||||
setInt8(int offset, int value)
|
||||
{
|
||||
setInt8(int offset, int value) {
|
||||
return _dv.setInt8(offset, value);
|
||||
}
|
||||
|
||||
setUint8(int offset, int value)
|
||||
{
|
||||
setUint8(int offset, int value) {
|
||||
return _dv.setUint8(offset, value);
|
||||
}
|
||||
|
||||
setInt16(int offset, int value)
|
||||
{
|
||||
setInt16(int offset, int value) {
|
||||
return _dv.setInt16(offset, value);
|
||||
}
|
||||
|
||||
setUint16(int offset, int value)
|
||||
{
|
||||
setUint16(int offset, int value) {
|
||||
return _dv.setUint16(offset, value);
|
||||
}
|
||||
|
||||
setInt32(int offset, int value)
|
||||
{
|
||||
setInt32(int offset, int value) {
|
||||
return _dv.setInt32(offset, value);
|
||||
}
|
||||
|
||||
setUint32(int offset, int value)
|
||||
{
|
||||
setUint32(int offset, int value) {
|
||||
return _dv.setUint32(offset, value);
|
||||
}
|
||||
|
||||
setFloat32(int offset, double value)
|
||||
{
|
||||
setFloat32(int offset, double value) {
|
||||
return _dv.setFloat32(offset, value);
|
||||
}
|
||||
|
||||
setFloat64(int offset, double value)
|
||||
{
|
||||
setFloat64(int offset, double value) {
|
||||
return _dv.setFloat64(offset, value);
|
||||
}
|
||||
|
||||
Int8List getInt8Array(int offset, int length)
|
||||
{
|
||||
Int8List getInt8Array(int offset, int length) {
|
||||
return _data.buffer.asInt8List(offset, length);
|
||||
}
|
||||
|
||||
Uint8List getUint8Array(int offset, int length)
|
||||
{
|
||||
Uint8List getUint8Array(int offset, int length) {
|
||||
return _data.buffer.asUint8List(offset, length);
|
||||
}
|
||||
|
||||
Int16List getInt16Array(int offset, int length)
|
||||
{
|
||||
Int16List getInt16Array(int offset, int length) {
|
||||
return _data.buffer.asInt16List(offset, length);
|
||||
}
|
||||
|
||||
Uint16List getUint16Array(int offset, int length)
|
||||
{
|
||||
Uint16List getUint16Array(int offset, int length) {
|
||||
return _data.buffer.asUint16List(offset, length);
|
||||
}
|
||||
|
||||
Int32List getInt32Array(int offset, int length)
|
||||
{
|
||||
Int32List getInt32Array(int offset, int length) {
|
||||
return _data.buffer.asInt32List(offset, length);
|
||||
}
|
||||
|
||||
Uint32List getUint32Array(int offset, int length)
|
||||
{
|
||||
Uint32List getUint32Array(int offset, int length) {
|
||||
return _data.buffer.asUint32List(offset, length);
|
||||
}
|
||||
|
||||
Float32List getFloat32Array(int offset, int length)
|
||||
{
|
||||
Float32List getFloat32Array(int offset, int length) {
|
||||
return _data.buffer.asFloat32List(offset, length);
|
||||
}
|
||||
|
||||
Float64List getFloat64Array(int offset, int length)
|
||||
{
|
||||
Float64List getFloat64Array(int offset, int length) {
|
||||
return _data.buffer.asFloat64List(offset, length);
|
||||
}
|
||||
|
||||
Int64List getInt64Array(int offset, int length)
|
||||
{
|
||||
Int64List getInt64Array(int offset, int length) {
|
||||
return _data.buffer.asInt64List(offset, length);
|
||||
}
|
||||
|
||||
Uint64List getUint64Array(int offset, int length)
|
||||
{
|
||||
Uint64List getUint64Array(int offset, int length) {
|
||||
return _data.buffer.asUint64List(offset, length);
|
||||
}
|
||||
|
||||
bool getBoolean(int offset)
|
||||
{
|
||||
bool getBoolean(int offset) {
|
||||
return this.getUint8(offset) > 0;
|
||||
}
|
||||
|
||||
setBoolean(int offset, bool value)
|
||||
{
|
||||
setBoolean(int offset, bool value) {
|
||||
this.setUint8(offset, value ? 1 : 0);
|
||||
}
|
||||
|
||||
List<bool> getBooleanArray(int offset, int length)
|
||||
{
|
||||
var rt = new List<bool>();
|
||||
for(var i = 0; i < length; i++)
|
||||
rt.add(this.getBoolean(offset+i));
|
||||
List<bool> getBooleanArray(int offset, int length) {
|
||||
List<bool> rt = [];
|
||||
for (var i = 0; i < length; i++) rt.add(this.getBoolean(offset + i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
String getChar(int offset)
|
||||
{
|
||||
String getChar(int offset) {
|
||||
return String.fromCharCode(this.getUint16(offset));
|
||||
}
|
||||
|
||||
setChar(int offset, int value)
|
||||
{
|
||||
setChar(int offset, int value) {
|
||||
this.setUint16(offset, value); //value.codeUnitAt(0));
|
||||
}
|
||||
|
||||
List<String> getCharArray(int offset, int length)
|
||||
{
|
||||
var rt = new List<String>();
|
||||
for(var i = 0; i < length; i+=2)
|
||||
rt.add(this.getChar(offset+i));
|
||||
List<String> getCharArray(int offset, int length) {
|
||||
List<String> rt = [];
|
||||
for (var i = 0; i < length; i += 2) rt.add(this.getChar(offset + i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
String getHex(offset, length)
|
||||
{
|
||||
String getHex(offset, length) {
|
||||
var rt = "";
|
||||
for (var i = offset; i < offset + length; i++) {
|
||||
var h = this[i].toString(16);
|
||||
var h = _data[i].toRadixString(16);
|
||||
rt += h.length == 1 ? "0" + h : h;
|
||||
}
|
||||
|
||||
@ -539,24 +440,19 @@ class DC with IterableMixin<int>
|
||||
return rt;
|
||||
}*/
|
||||
|
||||
|
||||
Uint8List toArray() => _data;
|
||||
|
||||
|
||||
String getString(offset, length)
|
||||
{
|
||||
String getString(offset, length) {
|
||||
var bytes = clip(offset, length)._data; // toList(offset, length);
|
||||
var str = utf8.decode(bytes);
|
||||
return str;
|
||||
}
|
||||
|
||||
List<String> getStringArray(offset, length)
|
||||
{
|
||||
var rt = List<String>();
|
||||
List<String> getStringArray(offset, length) {
|
||||
List<String> rt = [];
|
||||
var i = 0;
|
||||
|
||||
while (i < length)
|
||||
{
|
||||
while (i < length) {
|
||||
var cl = this.getUint32(offset + i);
|
||||
i += 4;
|
||||
rt.add(this.getString(offset + i, cl));
|
||||
@ -566,76 +462,59 @@ class DC with IterableMixin<int>
|
||||
return rt;
|
||||
}
|
||||
|
||||
getInt64(offset)
|
||||
{
|
||||
getInt64(offset) {
|
||||
return _dv.getUint64(offset);
|
||||
}
|
||||
|
||||
getUint64(offset)
|
||||
{
|
||||
getUint64(offset) {
|
||||
return _dv.getInt64(offset);
|
||||
}
|
||||
|
||||
void setInt64(offset, value)
|
||||
{
|
||||
void setInt64(offset, value) {
|
||||
_dv.setInt64(offset, value);
|
||||
}
|
||||
|
||||
void setUint64(offset, value)
|
||||
{
|
||||
|
||||
void setUint64(offset, value) {
|
||||
_dv.setUint64(offset, value);
|
||||
}
|
||||
|
||||
setDateTime(offset, DateTime value)
|
||||
{
|
||||
setDateTime(offset, DateTime value) {
|
||||
// Unix Epoch
|
||||
var ticks = UNIX_EPOCH + (value.millisecondsSinceEpoch * 10000);
|
||||
this.setUint64(offset, ticks);
|
||||
}
|
||||
|
||||
DateTime getDateTime(int offset)
|
||||
{
|
||||
DateTime getDateTime(int offset) {
|
||||
var ticks = this.getUint64(offset);
|
||||
// there are 10,000 ticks in a millisecond
|
||||
return DateTime.fromMillisecondsSinceEpoch((ticks - UNIX_EPOCH) ~/ 10000);
|
||||
}
|
||||
|
||||
List<DateTime> getDateTimeArray(int offset, int length)
|
||||
{
|
||||
var rt = new List<DateTime>();
|
||||
for(var i = 0; i < length; i+=8)
|
||||
rt.add(this.getDateTime(offset+i));
|
||||
List<DateTime> getDateTimeArray(int offset, int length) {
|
||||
List<DateTime> rt = [];
|
||||
for (var i = 0; i < length; i += 8) rt.add(this.getDateTime(offset + i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
Guid getGuid(int offset)
|
||||
{
|
||||
Guid getGuid(int offset) {
|
||||
return new Guid(this.clip(offset, 16));
|
||||
}
|
||||
|
||||
setGuid(int offset, Guid guid)
|
||||
{
|
||||
setGuid(int offset, Guid guid) {
|
||||
set(guid.value, offset);
|
||||
}
|
||||
|
||||
List<Guid> getGuidArray(int offset, int length)
|
||||
{
|
||||
var rt = [];
|
||||
for(var i = 0; i < length; i+=16)
|
||||
rt.add(this.getGuid(offset+i));
|
||||
List<Guid> getGuidArray(int offset, int length) {
|
||||
List<Guid> rt = [];
|
||||
for (var i = 0; i < length; i += 16) rt.add(this.getGuid(offset + i));
|
||||
return rt;
|
||||
}
|
||||
|
||||
bool sequenceEqual(ar)
|
||||
{
|
||||
bool sequenceEqual(ar) {
|
||||
if (ar.length != this.length)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
for(var i = 0; i < this.length; i++)
|
||||
if (ar[i] != this[i])
|
||||
return false;
|
||||
else {
|
||||
for (var i = 0; i < this.length; i++) if (ar[i] != this[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -44,6 +44,7 @@ class DataType
|
||||
ResourceLink = 0x11,
|
||||
String = 0x12,
|
||||
Structure = 0x13,
|
||||
Record = 0x14,
|
||||
//Stream,
|
||||
//Array = 0x80,
|
||||
VarArray = 0x80,
|
||||
@ -66,6 +67,7 @@ class DataType
|
||||
ResourceLinkArray = 0x91,
|
||||
StringArray = 0x92,
|
||||
StructureArray = 0x93,
|
||||
RecordArray = 0x94,
|
||||
NotModified = 0x7F,
|
||||
Unspecified = 0xFF;
|
||||
|
||||
|
@ -1,16 +1,21 @@
|
||||
import 'DC.dart';
|
||||
|
||||
class Guid
|
||||
{
|
||||
class Guid {
|
||||
DC _data;
|
||||
|
||||
Guid(DC data)
|
||||
{
|
||||
Guid(DC data) {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
DC get value => _data;
|
||||
|
||||
bool operator ==(Object other) {
|
||||
if (other is Guid)
|
||||
return _data.sequenceEqual(other._data);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _data.getString(0, _data.length);
|
||||
|
32
lib/src/Data/IRecord.dart
Normal file
32
lib/src/Data/IRecord.dart
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
import '../Resource/Template/TemplateDescriber.dart';
|
||||
|
||||
|
||||
abstract class IRecord {
|
||||
Map<String, dynamic> serialize();
|
||||
void deserialize(Map<String, dynamic> value);
|
||||
TemplateDescriber get template;
|
||||
}
|
6
lib/src/Data/ParseResult.dart
Normal file
6
lib/src/Data/ParseResult.dart
Normal file
@ -0,0 +1,6 @@
|
||||
class ParseResult<T> {
|
||||
int size;
|
||||
T value;
|
||||
|
||||
ParseResult(this.size, this.value);
|
||||
}
|
25
lib/src/Data/Record.dart
Normal file
25
lib/src/Data/Record.dart
Normal file
@ -0,0 +1,25 @@
|
||||
import 'package:esiur/src/Resource/Template/TemplateDescriber.dart';
|
||||
|
||||
import 'IRecord.dart';
|
||||
import 'KeyList.dart';
|
||||
|
||||
class Record extends KeyList with IRecord {
|
||||
Map<String, dynamic> _props;
|
||||
|
||||
@override
|
||||
Map<String, dynamic> serialize() {
|
||||
return _props;
|
||||
}
|
||||
|
||||
@override
|
||||
deserialize(Map<String, dynamic> value) {
|
||||
_props = value;
|
||||
}
|
||||
|
||||
operator [](index) => _props[index];
|
||||
operator []=(index, value) => _props[index] = value;
|
||||
|
||||
@override
|
||||
// TODO: implement template
|
||||
TemplateDescriber get template => throw UnimplementedError();
|
||||
}
|
6
lib/src/Data/RecordComparisonResult.dart
Normal file
6
lib/src/Data/RecordComparisonResult.dart
Normal file
@ -0,0 +1,6 @@
|
||||
class RecordComparisonResult {
|
||||
static const Null = 0;
|
||||
static const Record = 1;
|
||||
static const RecordSameType = 2;
|
||||
static const Same = 3;
|
||||
}
|
5
lib/src/Data/ResourceArrayType.dart
Normal file
5
lib/src/Data/ResourceArrayType.dart
Normal file
@ -0,0 +1,5 @@
|
||||
class ResourceArrayType {
|
||||
static const int Dynamic = 0x0;
|
||||
static const int Static = 0x10;
|
||||
static const Wrapper = 0x20;
|
||||
}
|
13
lib/src/Misc/Global.dart
Normal file
13
lib/src/Misc/Global.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import 'dart:math';
|
||||
|
||||
class Global {
|
||||
static String generateCode(
|
||||
[int length = 16,
|
||||
chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"]) {
|
||||
var rand = Random();
|
||||
|
||||
return String.fromCharCodes(Iterable.generate(
|
||||
length, (_) => chars.codeUnitAt(rand.nextInt(chars.length))));
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -41,11 +41,12 @@ class DistributedResource extends IResource {
|
||||
//bool _isReady = false;
|
||||
|
||||
String _link;
|
||||
int _age;
|
||||
|
||||
List _properties;
|
||||
bool _destroyed = false;
|
||||
|
||||
List<KeyValuePair<int, dynamic>> _queued_updates =
|
||||
List<KeyValuePair<int, dynamic>>();
|
||||
List<KeyValuePair<int, dynamic>> _queued_updates = [];
|
||||
|
||||
/// <summary>
|
||||
/// Connection responsible for the distributed resource.
|
||||
@ -111,6 +112,15 @@ class DistributedResource extends IResource {
|
||||
this._link = link;
|
||||
this._connection = connection;
|
||||
this._instanceId = instanceId;
|
||||
this._age = age;
|
||||
}
|
||||
|
||||
void init(
|
||||
DistributedConnection connection, int instanceId, int age, String link) {
|
||||
this._link = link;
|
||||
this._connection = connection;
|
||||
this._instanceId = instanceId;
|
||||
this._age = age;
|
||||
}
|
||||
|
||||
//void _ready()
|
||||
@ -165,6 +175,38 @@ class DistributedResource extends IResource {
|
||||
return true;
|
||||
}
|
||||
|
||||
AsyncReply<dynamic> listen(event) {
|
||||
EventTemplate et = event is EventTemplate
|
||||
? event
|
||||
: instance.template.getEventTemplateByName(event);
|
||||
|
||||
if (et == null)
|
||||
return AsyncReply<dynamic>().triggerError(new AsyncException(
|
||||
ErrorType.Management, ExceptionCode.MethodNotFound.index, ""));
|
||||
|
||||
if (!et.listenable)
|
||||
return AsyncReply().triggerError(new AsyncException(
|
||||
ErrorType.Management, ExceptionCode.NotListenable.index, ""));
|
||||
|
||||
return _connection.sendListenRequest(_instanceId, et.index);
|
||||
}
|
||||
|
||||
AsyncReply<dynamic> unlisten(event) {
|
||||
EventTemplate et = event is EventTemplate
|
||||
? event
|
||||
: instance.template.getEventTemplateByName(event);
|
||||
|
||||
if (et == null)
|
||||
return AsyncReply().triggerError(new AsyncException(
|
||||
ErrorType.Management, ExceptionCode.MethodNotFound.index, ""));
|
||||
|
||||
if (!et.listenable)
|
||||
return AsyncReply().triggerError(new AsyncException(
|
||||
ErrorType.Management, ExceptionCode.NotListenable.index, ""));
|
||||
|
||||
return connection.sendUnlistenRequest(_instanceId, et.index);
|
||||
}
|
||||
|
||||
void emitEventByIndex(int index, dynamic args) {
|
||||
// neglect events when the object is not yet attached
|
||||
if (!_attached) return;
|
||||
|
35
lib/src/Net/IIP/DistributedServer.dart
Normal file
35
lib/src/Net/IIP/DistributedServer.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import 'package:esiur/src/Resource/Template/TemplateDescriber.dart';
|
||||
|
||||
import '../../Resource/IResource.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
import '../../Resource/ResourceTrigger.dart';
|
||||
|
||||
import './EntryPoint.dart';
|
||||
|
||||
class DistributedServer extends IResource {
|
||||
@override
|
||||
void destroy() {
|
||||
this.emitArgs("destroy", []);
|
||||
}
|
||||
|
||||
@override
|
||||
AsyncReply<bool> trigger(ResourceTrigger trigger) {
|
||||
return AsyncReply.ready(true);
|
||||
}
|
||||
|
||||
EntryPoint entryPoint;
|
||||
|
||||
@override
|
||||
getProperty(String name) => null;
|
||||
|
||||
@override
|
||||
invoke(String name, List arguments) => null;
|
||||
|
||||
@override
|
||||
setProperty(String name, value) => true;
|
||||
|
||||
@override
|
||||
TemplateDescriber get template =>
|
||||
TemplateDescriber("Esiur.Net.IIP.DistributedServer");
|
||||
|
||||
}
|
12
lib/src/Net/IIP/EntryPoint.dart
Normal file
12
lib/src/Net/IIP/EntryPoint.dart
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
import '../../Resource/IResource.dart';
|
||||
import './DistributedConnection.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
|
||||
abstract class EntryPoint extends IResource
|
||||
{
|
||||
|
||||
AsyncReply<List<IResource>> query(String path, DistributedConnection sender);
|
||||
bool create();
|
||||
}
|
9
lib/src/Net/INetworkReceiver.dart
Normal file
9
lib/src/Net/INetworkReceiver.dart
Normal file
@ -0,0 +1,9 @@
|
||||
import 'NetworkBuffer.dart';
|
||||
|
||||
abstract class INetworkReceiver<T>
|
||||
{
|
||||
void networkClose(T sender);
|
||||
void networkReceive(T sender, NetworkBuffer buffer);
|
||||
//void NetworkError(T sender);
|
||||
void networkConnect(T sender);
|
||||
}
|
@ -22,6 +22,8 @@ SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
import 'INetworkReceiver.dart';
|
||||
|
||||
import '../Core/IDestructible.dart';
|
||||
import 'Sockets/ISocket.dart';
|
||||
import 'Sockets/SocketState.dart';
|
||||
@ -29,8 +31,7 @@ import 'NetworkBuffer.dart';
|
||||
import '../Data/DC.dart';
|
||||
import 'Sockets/IPEndPoint.dart';
|
||||
|
||||
class NetworkConnection extends IDestructible
|
||||
{
|
||||
class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> {
|
||||
ISocket _sock;
|
||||
|
||||
DateTime _lastAction;
|
||||
@ -48,124 +49,61 @@ class NetworkConnection extends IDestructible
|
||||
bool _processing = false;
|
||||
|
||||
|
||||
// to be overridden
|
||||
void connectionClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
void destroy() {
|
||||
// if (connected)
|
||||
close();
|
||||
//emitArgs("close", [this]);
|
||||
//OnDestroy?.Invoke(this);
|
||||
}
|
||||
|
||||
NetworkConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
NetworkConnection() {}
|
||||
|
||||
ISocket get socket => _sock;
|
||||
|
||||
void assign(ISocket socket)
|
||||
{
|
||||
void assign(ISocket socket) {
|
||||
_lastAction = DateTime.now();
|
||||
_sock = socket;
|
||||
|
||||
socket.on("receive", socket_OnReceive);
|
||||
socket.on("close", socket_OnClose);
|
||||
socket.on("connect", socket_OnConnect);
|
||||
socket.receiver = this;
|
||||
|
||||
//socket.on("receive", socket_OnReceive);
|
||||
//socket.on("close", socket_OnClose);
|
||||
//socket.on("connect", socket_OnConnect);
|
||||
}
|
||||
|
||||
|
||||
void socket_OnConnect()
|
||||
{
|
||||
emitArgs("connect", [this]);
|
||||
}
|
||||
|
||||
void socket_OnClose()
|
||||
{
|
||||
connectionClosed();
|
||||
emitArgs("close", [this]);
|
||||
}
|
||||
|
||||
void socket_OnReceive(NetworkBuffer buffer)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
// Unassigned ?
|
||||
if (_sock == null)
|
||||
return;
|
||||
|
||||
// Closed ?
|
||||
if (_sock.state == SocketState.Closed || _sock.state == SocketState.Terminated) // || !connected)
|
||||
return;
|
||||
|
||||
_lastAction = DateTime.now();
|
||||
|
||||
if (!_processing)
|
||||
{
|
||||
_processing = true;
|
||||
|
||||
try
|
||||
{
|
||||
while (buffer.available > 0 && !buffer.protected)
|
||||
dataReceived(buffer);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
_processing = false;
|
||||
}
|
||||
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
print(ex);
|
||||
//Global.Log("NetworkConnection", LogType.Warning, ex.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ISocket unassign()
|
||||
{
|
||||
if (_sock != null)
|
||||
{
|
||||
ISocket unassign() {
|
||||
if (_sock != null) {
|
||||
// connected = false;
|
||||
_sock.off("close", socket_OnClose);
|
||||
_sock.off("connect", socket_OnConnect);
|
||||
_sock.off("receive", socket_OnReceive);
|
||||
// _sock.off("close", socket_OnClose);
|
||||
// _sock.off("connect", socket_OnConnect);
|
||||
// _sock.off("receive", socket_OnReceive);
|
||||
|
||||
_sock.receiver = null;
|
||||
var rt = _sock;
|
||||
_sock = null;
|
||||
|
||||
return rt;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
void dataReceived(NetworkBuffer data)
|
||||
{
|
||||
// to be overridden
|
||||
void dataReceived(NetworkBuffer data) {
|
||||
emitArgs("dataReceived", [data]);
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_sock != null)
|
||||
_sock.close();
|
||||
void connected(){
|
||||
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
|
||||
void disconnected(){
|
||||
|
||||
}
|
||||
|
||||
void close() {
|
||||
try {
|
||||
if (_sock != null) _sock.close();
|
||||
} catch (ex) {
|
||||
//Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
|
||||
|
||||
}
|
||||
@ -173,34 +111,65 @@ class NetworkConnection extends IDestructible
|
||||
|
||||
DateTime get lastAction => _lastAction;
|
||||
|
||||
|
||||
IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint;
|
||||
|
||||
IPEndPoint get localEndPoint => _sock?.localEndPoint;
|
||||
|
||||
bool get connected => _sock.state == SocketState.Established;
|
||||
bool get isConnected => _sock.state == SocketState.Established;
|
||||
|
||||
|
||||
void send(DC msg)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (_sock != null)
|
||||
{
|
||||
void send(DC msg) {
|
||||
try {
|
||||
if (_sock != null) {
|
||||
_lastAction = DateTime.now();
|
||||
_sock.send(msg);
|
||||
}
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
} catch (ex) {
|
||||
//Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void sendString(String data)
|
||||
{
|
||||
void sendString(String data) {
|
||||
send(DC.stringToBytes(data));
|
||||
}
|
||||
|
||||
@override
|
||||
void networkClose(sender) {
|
||||
disconnected();
|
||||
emitArgs("close", [this]);
|
||||
}
|
||||
|
||||
@override
|
||||
void networkConnect(sender) {
|
||||
connected();
|
||||
emitArgs("connect", [this]);
|
||||
}
|
||||
|
||||
@override
|
||||
void networkReceive(sender, NetworkBuffer buffer) {
|
||||
try {
|
||||
// Unassigned ?
|
||||
if (_sock == null) return;
|
||||
|
||||
// Closed ?
|
||||
if (_sock.state == SocketState.Closed ||
|
||||
_sock.state == SocketState.Terminated) // || !connected)
|
||||
return;
|
||||
|
||||
_lastAction = DateTime.now();
|
||||
|
||||
if (!_processing) {
|
||||
_processing = true;
|
||||
|
||||
try {
|
||||
while (buffer.available > 0 && !buffer.protected)
|
||||
dataReceived(buffer);
|
||||
} catch (ex) {}
|
||||
|
||||
_processing = false;
|
||||
}
|
||||
} catch (ex) {
|
||||
print(ex);
|
||||
//Global.Log("NetworkConnection", LogType.Warning, ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@ -235,11 +235,14 @@ class IIPAuthPacket
|
||||
localMethod = AuthenticationMethod.values[ ((data[offset] >> 2) & 0x3)];
|
||||
var encrypt = ((data[offset++] & 0x2) == 0x2);
|
||||
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
|
||||
|
||||
if (remoteMethod == AuthenticationMethod.Credentials
|
||||
if (remoteMethod == AuthenticationMethod.None)
|
||||
{
|
||||
if (localMethod == AuthenticationMethod.None)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
else if (remoteMethod == AuthenticationMethod.Credentials
|
||||
|| remoteMethod == AuthenticationMethod.Token)
|
||||
{
|
||||
if (localMethod == AuthenticationMethod.None)
|
||||
|
@ -361,7 +361,8 @@ class IIPPacket
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
}
|
||||
else if (action == IIPPacketAction.QueryLink)
|
||||
else if (action == IIPPacketAction.QueryLink
|
||||
|| action == IIPPacketAction.LinkTemplates)
|
||||
{
|
||||
if (_notEnough(offset, ends, 2))
|
||||
return -_dataLengthNeeded;
|
||||
@ -420,7 +421,8 @@ class IIPPacket
|
||||
offset += cl;
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.GetProperty)
|
||||
else if (action == IIPPacketAction.Listen
|
||||
|| action == IIPPacketAction.Unlisten)
|
||||
{
|
||||
if (_notEnough(offset, ends, 5))
|
||||
return -_dataLengthNeeded;
|
||||
@ -429,22 +431,32 @@ class IIPPacket
|
||||
offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
|
||||
}
|
||||
else if (action == IIPPacketAction.GetPropertyIfModified)
|
||||
{
|
||||
if (_notEnough(offset, ends, 9))
|
||||
return -_dataLengthNeeded;
|
||||
// else if (action == IIPPacketAction.GetProperty)
|
||||
// {
|
||||
// if (_notEnough(offset, ends, 5))
|
||||
// return -_dataLengthNeeded;
|
||||
|
||||
resourceId = data.getUint32(offset);
|
||||
offset += 4;
|
||||
// resourceId = data.getUint32(offset);
|
||||
// offset += 4;
|
||||
|
||||
methodIndex = data[offset++];
|
||||
// methodIndex = data[offset++];
|
||||
|
||||
resourceAge = data.getUint64(offset);
|
||||
offset += 8;
|
||||
// }
|
||||
// else if (action == IIPPacketAction.GetPropertyIfModified)
|
||||
// {
|
||||
// if (_notEnough(offset, ends, 9))
|
||||
// return -_dataLengthNeeded;
|
||||
|
||||
}
|
||||
// resourceId = data.getUint32(offset);
|
||||
// offset += 4;
|
||||
|
||||
// methodIndex = data[offset++];
|
||||
|
||||
// resourceAge = data.getUint64(offset);
|
||||
// offset += 8;
|
||||
|
||||
// }
|
||||
else if (action == IIPPacketAction.SetProperty)
|
||||
{
|
||||
if (_notEnough(offset, ends, 6))
|
||||
@ -567,6 +579,7 @@ class IIPPacket
|
||||
|| action == IIPPacketAction.ResourceChildren
|
||||
|| action == IIPPacketAction.ResourceParents
|
||||
|| action == IIPPacketAction.ResourceHistory
|
||||
|| action == IIPPacketAction.LinkTemplates
|
||||
// Attribute
|
||||
|| action == IIPPacketAction.GetAllAttributes
|
||||
|| action == IIPPacketAction.GetAttributes)
|
||||
@ -584,9 +597,9 @@ class IIPPacket
|
||||
offset += cl;
|
||||
}
|
||||
else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|
||||
|| action == IIPPacketAction.InvokeFunctionNamedArguments
|
||||
|| action == IIPPacketAction.GetProperty
|
||||
|| action == IIPPacketAction.GetPropertyIfModified)
|
||||
|| action == IIPPacketAction.InvokeFunctionNamedArguments)
|
||||
//|| action == IIPPacketAction.GetProperty
|
||||
//|| action == IIPPacketAction.GetPropertyIfModified)
|
||||
{
|
||||
if (_notEnough(offset, ends, 1))
|
||||
return -_dataLengthNeeded;
|
||||
@ -617,7 +630,9 @@ class IIPPacket
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
else if (action == IIPPacketAction.SetProperty)
|
||||
else if (action == IIPPacketAction.SetProperty
|
||||
|| action == IIPPacketAction.Listen
|
||||
|| action == IIPPacketAction.Unlisten)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
class IIPPacketAction
|
||||
{
|
||||
class IIPPacketAction {
|
||||
// Request Manage
|
||||
static const int AttachResource = 0x0;
|
||||
static const int ReattachResource = 0x1;
|
||||
@ -18,13 +17,14 @@ class IIPPacketAction
|
||||
static const int ResourceHistory = 0xC;
|
||||
static const int ResourceChildren = 0xD;
|
||||
static const int ResourceParents = 0xE;
|
||||
static const int LinkTemplates = 0xF;
|
||||
|
||||
// Request Invoke
|
||||
static const int InvokeFunctionArrayArguments = 0x10;
|
||||
static const int GetProperty = 0x11;
|
||||
static const int GetPropertyIfModified = 0x12;
|
||||
static const int SetProperty = 0x13;
|
||||
static const int InvokeFunctionNamedArguments = 0x14;
|
||||
static const int InvokeFunctionNamedArguments = 0x11;
|
||||
static const int Listen = 0x12;
|
||||
static const int Unlisten = 0x13;
|
||||
static const int SetProperty = 0x14;
|
||||
|
||||
// Request Attribute
|
||||
static const int GetAllAttributes = 0x18;
|
||||
|
@ -23,12 +23,12 @@ SOFTWARE.
|
||||
*/
|
||||
import '../../Core/IDestructible.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../INetworkReceiver.dart';
|
||||
import 'IPEndPoint.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
import 'SocketState.dart';
|
||||
|
||||
abstract class ISocket extends IDestructible
|
||||
{
|
||||
abstract class ISocket extends IDestructible {
|
||||
SocketState get state; //{ get; }
|
||||
|
||||
//event ISocketReceiveEvent OnReceive;
|
||||
@ -36,6 +36,9 @@ abstract class ISocket extends IDestructible
|
||||
//event ISocketCloseEvent OnClose;
|
||||
|
||||
//void send(DC message);
|
||||
|
||||
INetworkReceiver<ISocket> receiver;
|
||||
|
||||
void send(DC message, [int offset, int size]);
|
||||
void close();
|
||||
AsyncReply<bool> connect(String hostname, int port);
|
||||
|
@ -32,8 +32,7 @@ import 'SocketState.dart';
|
||||
import 'IPEndPoint.dart';
|
||||
import '../../Core/AsyncReply.dart';
|
||||
|
||||
class TCPSocket extends ISocket
|
||||
{
|
||||
class TCPSocket extends ISocket {
|
||||
Socket sock;
|
||||
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
|
||||
|
||||
@ -60,10 +59,8 @@ class TCPSocket extends ISocket
|
||||
|
||||
IPEndPoint _localEP, _remoteEP;
|
||||
|
||||
bool begin()
|
||||
{
|
||||
if (began)
|
||||
return false;
|
||||
bool begin() {
|
||||
if (began) return false;
|
||||
|
||||
began = true;
|
||||
|
||||
@ -75,28 +72,23 @@ class TCPSocket extends ISocket
|
||||
void dataHandler(List<int> data) {
|
||||
//print(new String.fromCharCodes(data).trim());
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
if (_state == SocketState.Closed || _state == SocketState.Terminated)
|
||||
return;
|
||||
|
||||
|
||||
var dc = new DC.fromList(data);
|
||||
receiveNetworkBuffer.write(dc, 0, dc.length);
|
||||
emitArgs("receive", [receiveNetworkBuffer]);
|
||||
receiver.networkReceive(this, receiveNetworkBuffer);
|
||||
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
//emitArgs("receive", [receiveNetworkBuffer]);
|
||||
|
||||
} catch (ex) {
|
||||
if (_state != SocketState.Closed) // && !sock.connected)
|
||||
{
|
||||
_state = SocketState.Terminated;
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void errorHandler(error, StackTrace trace) {
|
||||
@ -108,91 +100,72 @@ class TCPSocket extends ISocket
|
||||
sock.destroy();
|
||||
}
|
||||
|
||||
AsyncReply<bool> connect(String hostname, int port)
|
||||
{
|
||||
AsyncReply<bool> connect(String hostname, int port) {
|
||||
var rt = new AsyncReply<bool>();
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
_state = SocketState.Connecting;
|
||||
|
||||
Socket.connect(hostname, port).then((s) {
|
||||
sock = s;
|
||||
s.listen(dataHandler,
|
||||
onError: errorHandler,
|
||||
onDone: doneHandler,
|
||||
cancelOnError: false);
|
||||
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
|
||||
_state = SocketState.Established;
|
||||
emitArgs("connect", []);
|
||||
|
||||
//emitArgs("connect", []);
|
||||
receiver?.networkConnect(this);
|
||||
|
||||
begin();
|
||||
rt.trigger(true);
|
||||
|
||||
}).catchError((ex) {
|
||||
close();
|
||||
rt.triggerError(AsyncException(ErrorType.Management, ExceptionCode.HostNotReachable.index, ex.toString()));
|
||||
rt.triggerError(AsyncException(ErrorType.Management,
|
||||
ExceptionCode.HostNotReachable.index, ex.toString()));
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
rt.triggerError(AsyncException(ErrorType.Management, ExceptionCode.HostNotReachable.index, ex.toString()));
|
||||
} catch (ex) {
|
||||
rt.triggerError(AsyncException(ErrorType.Management,
|
||||
ExceptionCode.HostNotReachable.index, ex.toString()));
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
IPEndPoint get localEndPoint => _localEP;
|
||||
IPEndPoint get remoteEndPoint => _remoteEP;
|
||||
|
||||
|
||||
SocketState get state => _state;
|
||||
|
||||
|
||||
TCPSocket.fromSocket(Socket socket)
|
||||
{
|
||||
TCPSocket.fromSocket(Socket socket) {
|
||||
sock = socket;
|
||||
//if (socket.)
|
||||
// _state = SocketState.Established;
|
||||
}
|
||||
|
||||
TCPSocket()
|
||||
{
|
||||
TCPSocket() {
|
||||
// default constructor
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
void close() {
|
||||
if (state != SocketState.Closed && state != SocketState.Terminated)
|
||||
_state = SocketState.Closed;
|
||||
|
||||
sock?.close();
|
||||
|
||||
emitArgs("close", []);
|
||||
receiver?.networkClose(this);
|
||||
|
||||
//emitArgs("close", []);
|
||||
}
|
||||
|
||||
|
||||
void send(DC message, [int offset, int size])
|
||||
{
|
||||
if (state == SocketState.Established)
|
||||
sock.add(message.toList());
|
||||
void send(DC message, [int offset, int size]) {
|
||||
if (state == SocketState.Established) sock.add(message.toList());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void destroy()
|
||||
{
|
||||
void destroy() {
|
||||
close();
|
||||
emitArgs("destroy", [this]);
|
||||
}
|
||||
|
||||
AsyncReply<ISocket> accept()
|
||||
{
|
||||
|
||||
|
||||
AsyncReply<ISocket> accept() {
|
||||
var reply = new AsyncReply<ISocket>();
|
||||
return reply;
|
||||
|
||||
|
306
lib/src/Proxy/TemplateGenerator.dart
Normal file
306
lib/src/Proxy/TemplateGenerator.dart
Normal file
@ -0,0 +1,306 @@
|
||||
import 'dart:io';
|
||||
|
||||
import '../Data/DataType.dart';
|
||||
import '../Net/IIP/DistributedConnection.dart';
|
||||
import '../Resource/Template/TemplateType.dart';
|
||||
import '../Resource/Warehouse.dart';
|
||||
|
||||
import '../Resource/Template/TemplateDataType.dart';
|
||||
|
||||
import '../Resource/Template/TypeTemplate.dart';
|
||||
|
||||
class TemplateGenerator {
|
||||
// static RegExp urlRegex = new RegExp("^(?:([\S]*)://([^/]*)/?)");
|
||||
static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))');
|
||||
|
||||
static String generateRecord(
|
||||
TypeTemplate template, List<TypeTemplate> templates) {
|
||||
var className = template.className.split('.').last;
|
||||
var rt = new StringBuffer();
|
||||
|
||||
rt.writeln("class ${className} extends IRecord {");
|
||||
|
||||
template.properties.forEach((p) {
|
||||
var ptTypeName = getTypeName(template, p.valueType, templates);
|
||||
rt.writeln("${ptTypeName} ${p.name};");
|
||||
rt.writeln();
|
||||
});
|
||||
|
||||
rt.writeln();
|
||||
|
||||
rt.writeln("@override");
|
||||
rt.writeln("void deserialize(Map<String, dynamic> value) {");
|
||||
|
||||
template.properties.forEach((p) {
|
||||
rt.writeln("${p.name} = value['${p.name}'];");
|
||||
});
|
||||
|
||||
rt.writeln("}");
|
||||
rt.writeln();
|
||||
|
||||
rt.writeln("@override");
|
||||
rt.writeln("Map<String, dynamic> serialize() {");
|
||||
rt.writeln("var rt = Map<String, dynamic>();");
|
||||
|
||||
template.properties.forEach((p) {
|
||||
rt.writeln("rt['${p.name}'] = ${p.name};");
|
||||
});
|
||||
|
||||
rt.writeln("return rt;");
|
||||
rt.writeln("}");
|
||||
rt.writeln("\r\n}");
|
||||
|
||||
return rt.toString();
|
||||
}
|
||||
|
||||
static String getTypeName(TypeTemplate forTemplate,
|
||||
TemplateDataType templateDataType, List<TypeTemplate> templates) {
|
||||
if (templateDataType.type == DataType.Resource) {
|
||||
if (templateDataType.typeGuid == forTemplate.classId)
|
||||
return forTemplate.className.split('.').last;
|
||||
else {
|
||||
var tmp =
|
||||
templates.firstWhere((x) => x.classId == templateDataType.typeGuid);
|
||||
|
||||
if (tmp == null) return "dynamic"; // something went wrong
|
||||
|
||||
var cls = tmp.className.split('.');
|
||||
var nameSpace = cls.take(cls.length - 1).join('_');
|
||||
|
||||
return "$nameSpace.${cls.last}";
|
||||
}
|
||||
} else if (templateDataType.type == DataType.ResourceArray) {
|
||||
if (templateDataType.typeGuid == forTemplate.classId)
|
||||
return "List<${forTemplate.className.split('.').last}>";
|
||||
else {
|
||||
var tmp =
|
||||
templates.firstWhere((x) => x.classId == templateDataType.typeGuid);
|
||||
|
||||
if (tmp == null) return "dynamic"; // something went wrong
|
||||
|
||||
var cls = tmp.className.split('.');
|
||||
var nameSpace = cls.take(cls.length - 1).join('_');
|
||||
|
||||
return "List<$nameSpace.${cls.last}>";
|
||||
}
|
||||
}
|
||||
|
||||
var name = ((x) {
|
||||
switch (x) {
|
||||
case DataType.Bool:
|
||||
return "bool";
|
||||
case DataType.BoolArray:
|
||||
return "List<bool>";
|
||||
case DataType.Char:
|
||||
return "String";
|
||||
case DataType.CharArray:
|
||||
return "List<String>";
|
||||
case DataType.DateTime:
|
||||
return "DateTime";
|
||||
case DataType.DateTimeArray:
|
||||
return "List<DateTime>";
|
||||
case DataType.Decimal:
|
||||
return "double";
|
||||
case DataType.DecimalArray:
|
||||
return "List<double>";
|
||||
case DataType.Float32:
|
||||
return "List<double>";
|
||||
case DataType.Float32Array:
|
||||
return "List<double>";
|
||||
case DataType.Float64:
|
||||
return "double";
|
||||
case DataType.Float64Array:
|
||||
return "List<double>";
|
||||
case DataType.Int16:
|
||||
return "int";
|
||||
case DataType.Int16Array:
|
||||
return "List<int>";
|
||||
case DataType.Int32:
|
||||
return "int";
|
||||
case DataType.Int32Array:
|
||||
return "List<int>";
|
||||
case DataType.Int64:
|
||||
return "int";
|
||||
case DataType.Int64Array:
|
||||
return "List<int>";
|
||||
case DataType.Int8:
|
||||
return "int";
|
||||
case DataType.Int8Array:
|
||||
return "List<int>";
|
||||
case DataType.String:
|
||||
return "String";
|
||||
case DataType.StringArray:
|
||||
return "List<String>";
|
||||
case DataType.Structure:
|
||||
return "Structure";
|
||||
case DataType.StructureArray:
|
||||
return "List<Structure>";
|
||||
case DataType.UInt16:
|
||||
return "int";
|
||||
case DataType.UInt16Array:
|
||||
return "List<int>";
|
||||
case DataType.UInt32:
|
||||
return "int";
|
||||
case DataType.UInt32Array:
|
||||
return "List<int>";
|
||||
case DataType.UInt64:
|
||||
return "int";
|
||||
case DataType.UInt64Array:
|
||||
return "List<int>";
|
||||
case DataType.UInt8:
|
||||
return "int";
|
||||
case DataType.UInt8Array:
|
||||
return "List<int>";
|
||||
case DataType.VarArray:
|
||||
return "List<dynamic>";
|
||||
case DataType.Void:
|
||||
return "dynamic";
|
||||
default:
|
||||
return "dynamic";
|
||||
}
|
||||
})(templateDataType.type);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static isNullOrEmpty(v) {
|
||||
return v == null || v == "";
|
||||
}
|
||||
|
||||
static Future<String> getTemplate(String url,
|
||||
[String dir = null,
|
||||
String username = null,
|
||||
String password = null]) async {
|
||||
try {
|
||||
if (!_urlRegex.hasMatch(url)) throw new Exception("Invalid IIP URL");
|
||||
|
||||
var path = _urlRegex.allMatches(url).first;
|
||||
var con = await Warehouse.get<DistributedConnection>(
|
||||
path[1] + "://" + path[2],
|
||||
!isNullOrEmpty(username) && !isNullOrEmpty(password)
|
||||
? {username: username, password: password}
|
||||
: null);
|
||||
|
||||
if (con == null) throw new Exception("Can't connect to server");
|
||||
|
||||
if (isNullOrEmpty(dir)) dir = path[2].replaceAll(":", "_");
|
||||
|
||||
var templates = await con.getLinkTemplates(path[3]);
|
||||
|
||||
var dstDir = Directory("lib/$dir");
|
||||
|
||||
if (!dstDir.existsSync()) dstDir.createSync();
|
||||
|
||||
//Map<String, String> namesMap = Map<String, String>();
|
||||
|
||||
var makeImports = (TypeTemplate skipTemplate) {
|
||||
var imports = StringBuffer();
|
||||
imports.writeln("import 'dart:async';");
|
||||
imports.writeln("import 'package:esiur/esiur.dart';");
|
||||
// make import names
|
||||
templates.forEach((tmp) {
|
||||
if (tmp != skipTemplate) {
|
||||
var cls = tmp.className.split('.');
|
||||
var nameSpace = cls.take(cls.length - 1).join('_');
|
||||
imports.writeln(
|
||||
"import '${tmp.className}.Generated.dart' as $nameSpace;");
|
||||
}
|
||||
});
|
||||
|
||||
imports.writeln();
|
||||
return imports.toString();
|
||||
};
|
||||
|
||||
// make sources
|
||||
templates.forEach((tmp) {
|
||||
if (tmp.type == TemplateType.Resource) {
|
||||
var source = makeImports(tmp) + generateClass(tmp, templates);
|
||||
var f = File("${dstDir.path}/${tmp.className}.Generated.dart");
|
||||
f.writeAsStringSync(source);
|
||||
} else if (tmp.type == TemplateType.Record) {
|
||||
var source = makeImports(tmp) + generateRecord(tmp, templates);
|
||||
var f = File("${dstDir.path}/${tmp.className}.Generated.dart");
|
||||
f.writeAsStringSync(source);
|
||||
}
|
||||
});
|
||||
|
||||
// generate info class
|
||||
var typesFile =
|
||||
"using System; \r\n namespace Esiur { public static class Generated { public static Type[] Resources {get;} = new Type[] { " +
|
||||
templates
|
||||
.where((x) => x.type == TemplateType.Resource)
|
||||
.map((x) => "typeof(${x.className})")
|
||||
.join(',') +
|
||||
" }; \r\n public static Type[] Records { get; } = new Type[] { " +
|
||||
templates
|
||||
.where((x) => x.type == TemplateType.Record)
|
||||
.map((x) => "typeof(${x.className})")
|
||||
.join(',') +
|
||||
" }; " +
|
||||
"\r\n } \r\n}";
|
||||
|
||||
var f = File("${dstDir.path}/Esiur.Generated.cs");
|
||||
f.writeAsStringSync(typesFile);
|
||||
|
||||
return dstDir.path;
|
||||
} catch (ex) {
|
||||
//File.WriteAllText("C:\\gen\\gettemplate.err", ex.ToString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
static String generateClass(
|
||||
TypeTemplate template, List<TypeTemplate> templates) {
|
||||
var className = template.className.split('.').last;
|
||||
|
||||
var rt = new StringBuffer();
|
||||
rt.writeln("class $className extends DistributedResource {");
|
||||
|
||||
rt.writeln(
|
||||
"$className(DistributedConnection connection, int instanceId, int age, String link) : super(connection, instanceId, age, link) {");
|
||||
|
||||
template.events.forEach((e) {
|
||||
rt.writeln("on('${e.name}', (x) => _${e.name}Controller.add(x));");
|
||||
});
|
||||
|
||||
rt.writeln("}");
|
||||
|
||||
template.functions.forEach((f) {
|
||||
var rtTypeName = getTypeName(template, f.returnType, templates);
|
||||
rt.write("AsyncReply<$rtTypeName> ${f.name}(");
|
||||
rt.write(f.arguments
|
||||
.map((x) => getTypeName(template, x.type, templates) + " " + x.name)
|
||||
.join(","));
|
||||
|
||||
rt.writeln(") {");
|
||||
rt.writeln("var rt = new AsyncReply<$rtTypeName>();");
|
||||
rt.writeln(
|
||||
"invokeByArrayArguments(${f.index}, [${f.arguments.map((x) => x.name).join(',')}])");
|
||||
rt.writeln(".then<dynamic>((x) => rt.trigger(x))");
|
||||
rt.writeln(".error((x) => rt.triggerError(x))");
|
||||
rt.writeln(".chunk((x) => rt.triggerChunk(x));");
|
||||
rt.writeln("return rt; }");
|
||||
});
|
||||
|
||||
template.properties.forEach((p) {
|
||||
var ptTypeName = getTypeName(template, p.valueType, templates);
|
||||
rt.writeln("${ptTypeName} get ${p.name} { return get(${p.index}); }");
|
||||
rt.writeln(
|
||||
"set ${p.name}(${ptTypeName} value) { set(${p.index}, value); }");
|
||||
});
|
||||
|
||||
template.events.forEach((e) {
|
||||
var etTypeName = getTypeName(template, e.argumentType, templates);
|
||||
|
||||
rt.writeln(
|
||||
"final _${e.name}Controller = StreamController<$etTypeName>();");
|
||||
rt.writeln("Stream<$etTypeName> get ${e.name} { ");
|
||||
rt.writeln("return _${e.name}Controller.stream;");
|
||||
rt.writeln("}");
|
||||
});
|
||||
|
||||
rt.writeln("\r\n}");
|
||||
|
||||
return rt.toString();
|
||||
}
|
||||
}
|
@ -22,25 +22,22 @@ SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
import 'package:esiur/src/Resource/Template/TemplateDescriber.dart';
|
||||
|
||||
import '../Resource/Template/TemplateDescriber.dart';
|
||||
import '../Core/IDestructible.dart';
|
||||
import 'ResourceTrigger.dart';
|
||||
import '../Core/AsyncReply.dart';
|
||||
import 'Instance.dart';
|
||||
|
||||
abstract class IResource extends IDestructible
|
||||
{
|
||||
|
||||
abstract class IResource extends IDestructible {
|
||||
AsyncReply<bool> trigger(ResourceTrigger trigger);
|
||||
/*
|
||||
{
|
||||
// do nothing
|
||||
return new AsyncReply.ready(true);
|
||||
}
|
||||
|
||||
destroy()
|
||||
{
|
||||
// Destroyed
|
||||
}
|
||||
*/
|
||||
Instance instance;
|
||||
|
||||
invoke(String name, List arguments);
|
||||
setProperty(String name, value);
|
||||
getProperty(String name);
|
||||
|
||||
TemplateDescriber get template;
|
||||
}
|
@ -11,7 +11,7 @@ import '../Core/IEventHandler.dart';
|
||||
import '../Security/Permissions/Ruling.dart';
|
||||
import '../Security/Permissions/IPermissionsManager.dart';
|
||||
import '../Security/Permissions/ActionType.dart';
|
||||
import './Template/ResourceTemplate.dart';
|
||||
import 'Template/TypeTemplate.dart';
|
||||
import './Template/PropertyTemplate.dart';
|
||||
import './Template/FunctionTemplate.dart';
|
||||
import './Template/EventTemplate.dart';
|
||||
@ -30,7 +30,7 @@ class Instance extends IEventHandler
|
||||
IStore _store;
|
||||
AutoList<IResource, Instance> _parents;
|
||||
//bool inherit;
|
||||
ResourceTemplate _template;
|
||||
TypeTemplate _template;
|
||||
|
||||
AutoList<IPermissionsManager, Instance> _managers;
|
||||
|
||||
@ -547,7 +547,7 @@ class Instance extends IEventHandler
|
||||
/// <summary>
|
||||
/// Resource template describes the properties, functions and events of the resource.
|
||||
/// </summary>
|
||||
ResourceTemplate get template => _template;
|
||||
TypeTemplate get template => _template;
|
||||
|
||||
/// <summary>
|
||||
/// Check for permission.
|
||||
@ -583,7 +583,7 @@ class Instance extends IEventHandler
|
||||
/// <param name="name">Name of the instance.</param>
|
||||
/// <param name="resource">Resource to manage.</param>
|
||||
/// <param name="store">Store responsible for the resource.</param>
|
||||
Instance(int id, String name, IResource resource, IStore store, [ResourceTemplate customTemplate = null, int age = 0])
|
||||
Instance(int id, String name, IResource resource, IStore store, [TypeTemplate customTemplate = null, int age = 0])
|
||||
{
|
||||
_store = store;
|
||||
_resource = resource;
|
||||
|
34
lib/src/Resource/Template/ArgumentTemplate.dart
Normal file
34
lib/src/Resource/Template/ArgumentTemplate.dart
Normal file
@ -0,0 +1,34 @@
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/BinaryList.dart';
|
||||
import "../../Data/ParseResult.dart";
|
||||
import './TemplateDataType.dart';
|
||||
|
||||
class ArgumentTemplate
|
||||
{
|
||||
String name;
|
||||
|
||||
TemplateDataType type;
|
||||
|
||||
static ParseResult<ArgumentTemplate> parse(DC data, int offset)
|
||||
{
|
||||
var cs = data[offset++];
|
||||
var name = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
var tdr = TemplateDataType.parse(data, offset);
|
||||
|
||||
return ParseResult<ArgumentTemplate>(cs + 1 + tdr.size, ArgumentTemplate(name, tdr.value));
|
||||
}
|
||||
|
||||
ArgumentTemplate(this.name, this.type);
|
||||
|
||||
DC compose()
|
||||
{
|
||||
var name = DC.stringToBytes(this.name);
|
||||
|
||||
return new BinaryList()
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(type.compose())
|
||||
.toDC();
|
||||
}
|
||||
}
|
@ -1,45 +1,39 @@
|
||||
|
||||
import 'MemberTemplate.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/BinaryList.dart';
|
||||
import 'ResourceTemplate.dart';
|
||||
import 'TypeTemplate.dart';
|
||||
import 'MemberType.dart';
|
||||
import 'TemplateDataType.dart';
|
||||
|
||||
class EventTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
class EventTemplate extends MemberTemplate {
|
||||
String expansion;
|
||||
bool listenable;
|
||||
TemplateDataType argumentType;
|
||||
|
||||
|
||||
DC compose()
|
||||
{
|
||||
DC compose() {
|
||||
var name = super.compose();
|
||||
|
||||
if (expansion != null)
|
||||
{
|
||||
if (expansion != null) {
|
||||
var exp = DC.stringToBytes(expansion);
|
||||
return new BinaryList()
|
||||
.addUint8(0x50)
|
||||
.addUint8(listenable ? 0x58 : 0x50)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(argumentType.compose())
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp)
|
||||
.toDC();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return new BinaryList()
|
||||
.addUint8(0x40)
|
||||
.addUint8(listenable ? 0x48 : 0x40)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(argumentType.compose())
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EventTemplate(ResourceTemplate template, int index, String name, String expansion)
|
||||
: super(template, MemberType.Property, index, name)
|
||||
{
|
||||
this.expansion = expansion;
|
||||
}
|
||||
EventTemplate(TypeTemplate template, int index, String name,
|
||||
this.argumentType, this.expansion, this.listenable)
|
||||
: super(template, MemberType.Property, index, name) {}
|
||||
}
|
||||
|
@ -1,41 +1,48 @@
|
||||
import 'MemberTemplate.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/BinaryList.dart';
|
||||
import 'ResourceTemplate.dart';
|
||||
import 'TypeTemplate.dart';
|
||||
import 'MemberType.dart';
|
||||
import 'ArgumentTemplate.dart';
|
||||
import 'TemplateDataType.dart';
|
||||
|
||||
class FunctionTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
class FunctionTemplate extends MemberTemplate {
|
||||
String expansion;
|
||||
bool isVoid;
|
||||
|
||||
TemplateDataType returnType;
|
||||
List<ArgumentTemplate> arguments;
|
||||
|
||||
DC compose() {
|
||||
|
||||
DC compose()
|
||||
{
|
||||
var name = super.compose();
|
||||
|
||||
var bl = new BinaryList()
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(returnType.compose())
|
||||
.addUint8(arguments.length);
|
||||
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
bl.addDC(arguments[i].compose());
|
||||
|
||||
|
||||
if (expansion != null)
|
||||
{
|
||||
var exp = DC.stringToBytes(expansion);
|
||||
return new BinaryList().addUint8((0x10 | (isVoid ? 0x8 : 0x0)))
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp)
|
||||
.toDC();
|
||||
bl.addInt32(exp.length)
|
||||
.addDC(exp);
|
||||
bl.insertUint8(0, 0x10);
|
||||
}
|
||||
else
|
||||
return new BinaryList().addUint8((isVoid ? 0x8 : 0x0))
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.toDC();
|
||||
bl.insertUint8(0, 0x0);
|
||||
|
||||
return bl.toDC();
|
||||
}
|
||||
|
||||
|
||||
FunctionTemplate(ResourceTemplate template, int index, String name, bool isVoid, String expansion)
|
||||
:super(template, MemberType.Property, index, name)
|
||||
{
|
||||
FunctionTemplate(TypeTemplate template, int index, String name,
|
||||
this.arguments, this.returnType, String expansion)
|
||||
: super(template, MemberType.Property, index, name) {
|
||||
this.isVoid = isVoid;
|
||||
this.expansion = expansion;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
import 'MemberType.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import './ResourceTemplate.dart';
|
||||
import 'TypeTemplate.dart';
|
||||
|
||||
class MemberTemplate
|
||||
{
|
||||
@ -10,14 +10,14 @@ class MemberTemplate
|
||||
String get name => _name;
|
||||
MemberType get type => _type;
|
||||
|
||||
ResourceTemplate _template;
|
||||
TypeTemplate _template;
|
||||
String _name;
|
||||
MemberType _type;
|
||||
int _index;
|
||||
|
||||
ResourceTemplate get template => _template;
|
||||
TypeTemplate get template => _template;
|
||||
|
||||
MemberTemplate(ResourceTemplate template, MemberType type, int index, String name)
|
||||
MemberTemplate(TypeTemplate template, MemberType type, int index, String name)
|
||||
{
|
||||
this._template = template;
|
||||
this._type = type;
|
||||
|
@ -1,80 +1,76 @@
|
||||
import 'TemplateDataType.dart';
|
||||
|
||||
import 'MemberTemplate.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/BinaryList.dart';
|
||||
import 'ResourceTemplate.dart';
|
||||
import 'TypeTemplate.dart';
|
||||
import 'MemberType.dart';
|
||||
import 'PropertyPermission.dart';
|
||||
import '../StorageMode.dart';
|
||||
|
||||
class PropertyTemplate extends MemberTemplate
|
||||
{
|
||||
|
||||
class PropertyTemplate extends MemberTemplate {
|
||||
TemplateDataType valueType;
|
||||
|
||||
int permission;
|
||||
|
||||
|
||||
int storage;
|
||||
|
||||
String readExpansion;
|
||||
|
||||
String writeExpansion;
|
||||
|
||||
DC compose()
|
||||
{
|
||||
DC compose() {
|
||||
var name = super.compose();
|
||||
var pv = ((permission) << 1) | (storage == StorageMode.Recordable ? 1 : 0);
|
||||
|
||||
if (writeExpansion != null && readExpansion != null)
|
||||
{
|
||||
if (writeExpansion != null && readExpansion != null) {
|
||||
var rexp = DC.stringToBytes(readExpansion);
|
||||
var wexp = DC.stringToBytes(writeExpansion);
|
||||
return new BinaryList()
|
||||
.addUint8(0x38 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(valueType.compose())
|
||||
.addInt32(wexp.length)
|
||||
.addDC(wexp)
|
||||
.addInt32(rexp.length)
|
||||
.addDC(rexp)
|
||||
.toDC();
|
||||
}
|
||||
else if (writeExpansion != null)
|
||||
{
|
||||
} else if (writeExpansion != null) {
|
||||
var wexp = DC.stringToBytes(writeExpansion);
|
||||
return new BinaryList()
|
||||
.addUint8(0x30 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(valueType.compose())
|
||||
.addInt32(wexp.length)
|
||||
.addDC(wexp)
|
||||
.toDC();
|
||||
}
|
||||
else if (readExpansion != null)
|
||||
{
|
||||
} else if (readExpansion != null) {
|
||||
var rexp = DC.stringToBytes(readExpansion);
|
||||
return new BinaryList()
|
||||
.addUint8(0x28 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(valueType.compose())
|
||||
.addInt32(rexp.length)
|
||||
.addDC(rexp)
|
||||
.toDC();
|
||||
}
|
||||
else
|
||||
} else
|
||||
return new BinaryList()
|
||||
.addUint8(0x20 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(valueType.compose())
|
||||
.toDC();
|
||||
}
|
||||
|
||||
PropertyTemplate(ResourceTemplate template, int index, String name, String read, String write, int storage)
|
||||
:super(template, MemberType.Property, index, name)
|
||||
{
|
||||
PropertyTemplate(TypeTemplate template, int index, String name,
|
||||
TemplateDataType valueType, String read, String write, int storage)
|
||||
: super(template, MemberType.Property, index, name) {
|
||||
//this.Recordable = recordable;
|
||||
this.storage = storage;
|
||||
this.readExpansion = read;
|
||||
this.writeExpansion = write;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
}
|
@ -1,330 +0,0 @@
|
||||
|
||||
import './MemberTemplate.dart';
|
||||
import '../../Data/Guid.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import './EventTemplate.dart';
|
||||
import './PropertyTemplate.dart';
|
||||
import './FunctionTemplate.dart';
|
||||
import '../StorageMode.dart';
|
||||
|
||||
class ResourceTemplate
|
||||
{
|
||||
Guid _classId;
|
||||
String _className;
|
||||
List<MemberTemplate> _members = new List<MemberTemplate>();
|
||||
List<FunctionTemplate> _functions = new List<FunctionTemplate>();
|
||||
List<EventTemplate> _events = new List<EventTemplate>();
|
||||
List<PropertyTemplate> _properties = new List<PropertyTemplate>();
|
||||
int _version;
|
||||
//bool isReady;
|
||||
|
||||
DC _content;
|
||||
|
||||
DC get content => _content;
|
||||
|
||||
/*
|
||||
MemberTemplate getMemberTemplate(MemberInfo member)
|
||||
{
|
||||
if (member is MethodInfo)
|
||||
return getFunctionTemplate(member.Name);
|
||||
else if (member is EventInfo)
|
||||
return getEventTemplate(member.Name);
|
||||
else if (member is PropertyInfo)
|
||||
return getPropertyTemplate(member.Name);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
EventTemplate getEventTemplateByName(String eventName)
|
||||
{
|
||||
for (var i in _events)
|
||||
if (i.name == eventName)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
EventTemplate getEventTemplateByIndex(int index)
|
||||
{
|
||||
for (var i in _events)
|
||||
if (i.index == index)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByName(String functionName)
|
||||
{
|
||||
for (var i in _functions)
|
||||
if (i.name == functionName)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByIndex(int index)
|
||||
{
|
||||
for (var i in _functions)
|
||||
if (i.index == index)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByIndex(int index)
|
||||
{
|
||||
for (var i in _properties)
|
||||
if (i.index == index)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByName(String propertyName)
|
||||
{
|
||||
for (var i in _properties)
|
||||
if (i.name == propertyName)
|
||||
return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
Guid get classId => _classId;
|
||||
|
||||
String get className => _className;
|
||||
|
||||
List<MemberTemplate> get methods => _members;
|
||||
|
||||
List<FunctionTemplate> get functions => _functions;
|
||||
|
||||
List<EventTemplate> get events => _events;
|
||||
|
||||
List<PropertyTemplate> get properties => _properties;
|
||||
|
||||
ResourceTemplate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
ResourceTemplate.fromType(Type type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
ResourceTemplate(Type type)
|
||||
{
|
||||
|
||||
type = ResourceProxy.GetBaseType(type);
|
||||
|
||||
// set guid
|
||||
|
||||
var typeName = Encoding.UTF8.GetBytes(type.FullName);
|
||||
var hash = SHA256.Create().ComputeHash(typeName).Clip(0, 16);
|
||||
|
||||
classId = new Guid(hash);
|
||||
className = type.FullName;
|
||||
|
||||
|
||||
#if NETSTANDARD1_5
|
||||
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
|
||||
#else
|
||||
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
|
||||
//byte currentIndex = 0;
|
||||
|
||||
byte i = 0;
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
{
|
||||
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
|
||||
if (ps.Length > 0)
|
||||
{
|
||||
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
|
||||
pt.Info = pi;
|
||||
properties.Add(pt);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
{
|
||||
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
if (es.Length > 0)
|
||||
{
|
||||
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
||||
events.Add(et);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
|
||||
if (fs.Length > 0)
|
||||
{
|
||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
||||
functions.Add(ft);
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (i = 0; i < events.Count; i++)
|
||||
members.Add(events[i]);
|
||||
// append slots
|
||||
for (i = 0; i < functions.Count; i++)
|
||||
members.Add(functions[i]);
|
||||
// append properties
|
||||
for (i = 0; i < properties.Count; i++)
|
||||
members.Add(properties[i]);
|
||||
|
||||
// bake it binarily
|
||||
var b = new BinaryList();
|
||||
b.AddGuid(classId)
|
||||
.AddUInt8((byte)className.Length)
|
||||
.AddString(className)
|
||||
.AddInt32(version)
|
||||
.AddUInt16((ushort)members.Count);
|
||||
|
||||
|
||||
foreach (var ft in functions)
|
||||
b.AddUInt8Array(ft.Compose());
|
||||
foreach (var pt in properties)
|
||||
b.AddUInt8Array(pt.Compose());
|
||||
foreach (var et in events)
|
||||
b.AddUInt8Array(et.Compose());
|
||||
|
||||
content = b.ToArray();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
ResourceTemplate.parse(DC data, [int offset = 0, int contentLength])
|
||||
{
|
||||
|
||||
// cool Dart feature
|
||||
contentLength ??= data.length;
|
||||
|
||||
|
||||
int ends = offset + contentLength;
|
||||
|
||||
int oOffset = offset;
|
||||
|
||||
// start parsing...
|
||||
|
||||
//var od = new ResourceTemplate();
|
||||
_content = data.clip(offset, contentLength);
|
||||
|
||||
_classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
_className = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
_version = data.getInt32(offset);
|
||||
offset += 4;
|
||||
|
||||
var methodsCount = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
var functionIndex = 0;
|
||||
var propertyIndex = 0;
|
||||
var eventIndex = 0;
|
||||
|
||||
for (int i = 0; i < methodsCount; i++)
|
||||
{
|
||||
var type = data[offset] >> 5;
|
||||
|
||||
if (type == 0) // function
|
||||
{
|
||||
String expansion = null;
|
||||
var hasExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
var isVoid = ((data[offset++] & 0x08) == 0x08);
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var ft = new FunctionTemplate(this, functionIndex++, name, isVoid, expansion);
|
||||
|
||||
_functions.add(ft);
|
||||
}
|
||||
else if (type == 1) // property
|
||||
{
|
||||
|
||||
String readExpansion = null, writeExpansion = null;
|
||||
|
||||
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
|
||||
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
var recordable = ((data[offset] & 1) == 1);
|
||||
var permission = (data[offset++] >> 1) & 0x3;
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
|
||||
offset += data[offset] + 1;
|
||||
|
||||
if (hasReadExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
readExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
if (hasWriteExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
writeExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var pt = new PropertyTemplate(this, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile);
|
||||
|
||||
_properties.add(pt);
|
||||
}
|
||||
else if (type == 2) // Event
|
||||
{
|
||||
|
||||
String expansion = null;
|
||||
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||
|
||||
var name = data.getString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var et = new EventTemplate(this, eventIndex++, name, expansion);
|
||||
|
||||
_events.add(et);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (int i = 0; i < _events.length; i++)
|
||||
_members.add(_events[i]);
|
||||
// append slots
|
||||
for (int i = 0; i < _functions.length; i++)
|
||||
_members.add(_functions[i]);
|
||||
// append properties
|
||||
for (int i = 0; i < _properties.length; i++)
|
||||
_members.add(_properties[i]);
|
||||
|
||||
}
|
||||
}
|
||||
|
120
lib/src/Resource/Template/TemplateDataType.dart
Normal file
120
lib/src/Resource/Template/TemplateDataType.dart
Normal file
@ -0,0 +1,120 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import '../../Data/IRecord.dart';
|
||||
import '../../Resource/IResource.dart';
|
||||
|
||||
import '../../Data/Structure.dart';
|
||||
|
||||
import '../../Data/ParseResult.dart';
|
||||
|
||||
import '../../Data/DataType.dart';
|
||||
import '../../Data/Guid.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import '../../Data/BinaryList.dart';
|
||||
import 'TypeTemplate.dart';
|
||||
import '../../Resource/Warehouse.dart';
|
||||
import 'TemplateType.dart';
|
||||
|
||||
class TemplateDataType {
|
||||
int type;
|
||||
TypeTemplate get typeTemplate =>
|
||||
typeGuid == null ? null : Warehouse.getTemplateByClassId(typeGuid);
|
||||
|
||||
Guid typeGuid;
|
||||
|
||||
// @TODO: implement fromType
|
||||
TemplateDataType.fromType(type, bool isArray) {
|
||||
int dt;
|
||||
|
||||
if (type == null)
|
||||
dt = DataType.Void;
|
||||
else if (type is int) {
|
||||
dt = type;
|
||||
} else if (type == bool)
|
||||
dt = DataType.Bool;
|
||||
else if (type == Uint8)
|
||||
dt = DataType.UInt8;
|
||||
else if (type == Int8)
|
||||
dt = DataType.Int8;
|
||||
else if (type == Uint16)
|
||||
dt = DataType.UInt16;
|
||||
else if (type == Int16)
|
||||
dt = DataType.Int16;
|
||||
else if (type == Uint32)
|
||||
dt = DataType.UInt32;
|
||||
else if (type == Int32)
|
||||
dt = DataType.Int32;
|
||||
else if (type == Uint64)
|
||||
dt = DataType.UInt64;
|
||||
else if (type == Int64 || type == int)
|
||||
dt = DataType.Int64;
|
||||
else if (type == Float)
|
||||
dt = DataType.Float32;
|
||||
else if (type == Double)
|
||||
dt = DataType.Float64;
|
||||
else if (type == String)
|
||||
dt = DataType.String;
|
||||
else if (type == DateTime)
|
||||
dt = DataType.DateTime;
|
||||
else if (type == Structure)
|
||||
dt = DataType.Structure;
|
||||
else if (type == IResource) // Dynamic resource (unspecified type)
|
||||
dt = DataType.Void;
|
||||
else if (type == IRecord) // Dynamic record (unspecified type)
|
||||
dt = DataType.Void;
|
||||
else {
|
||||
var template = Warehouse.getTemplateByType(type);
|
||||
|
||||
if (template != null) {
|
||||
typeGuid = template.classId;
|
||||
dt = template.type == TemplateType.Resource
|
||||
? DataType.Resource
|
||||
: DataType.Record;
|
||||
} else
|
||||
dt = DataType.Void;
|
||||
|
||||
// if (template)
|
||||
// try {
|
||||
// var ins = Warehouse.createInstance(type);
|
||||
// if (ins is IResource) {
|
||||
// typeGuid = TypeTemplate.getTypeGuid(ins.template.nameSpace);
|
||||
// } else if (ins is IRecord) {
|
||||
// typeGuid = TypeTemplate.getTypeGuid(ins.template.nameSpace);
|
||||
// } else {
|
||||
// dt = DataType.Void;
|
||||
// }
|
||||
// } catch (ex) {
|
||||
// dt = DataType.Void;
|
||||
// }
|
||||
}
|
||||
|
||||
if (isArray) dt = dt | 0x80;
|
||||
|
||||
this.type = dt;
|
||||
}
|
||||
|
||||
DC compose() {
|
||||
if (type == DataType.Resource ||
|
||||
type == DataType.ResourceArray ||
|
||||
type == DataType.Record ||
|
||||
type == DataType.RecordArray) {
|
||||
return BinaryList().addUint8(type).addDC(typeGuid.value).toDC();
|
||||
} else
|
||||
return DC.fromList([type]);
|
||||
}
|
||||
|
||||
TemplateDataType(this.type, this.typeGuid);
|
||||
|
||||
static ParseResult<TemplateDataType> parse(DC data, int offset) {
|
||||
var type = data[offset++];
|
||||
if (type == DataType.Resource ||
|
||||
type == DataType.ResourceArray ||
|
||||
type == DataType.Record ||
|
||||
type == DataType.RecordArray) {
|
||||
var guid = data.getGuid(offset);
|
||||
return ParseResult<TemplateDataType>(
|
||||
17, new TemplateDataType(type, guid));
|
||||
} else
|
||||
return ParseResult<TemplateDataType>(1, new TemplateDataType(type, null));
|
||||
}
|
||||
}
|
81
lib/src/Resource/Template/TemplateDescriber.dart
Normal file
81
lib/src/Resource/Template/TemplateDescriber.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import '../../Data/DataType.dart';
|
||||
|
||||
class TemplateDescriber {
|
||||
final List<Prop> properties;
|
||||
final List<Evt> events;
|
||||
final List<Func> functions;
|
||||
final String nameSpace;
|
||||
|
||||
TemplateDescriber(this.nameSpace,
|
||||
{this.properties, this.functions, this.events});
|
||||
}
|
||||
|
||||
// class Property<T> {
|
||||
// T _value;
|
||||
|
||||
// Function(T) _setter;
|
||||
// Function() _getter;
|
||||
// Function(Property) notifier;
|
||||
|
||||
// IResource resource;
|
||||
|
||||
// operator <<(other) {
|
||||
// set(other);
|
||||
// }
|
||||
|
||||
// void set(T value) {
|
||||
// if (_setter != null)
|
||||
// _setter(value);
|
||||
// else
|
||||
// _value = value;
|
||||
|
||||
// if (notifier != null) notifier.call(this);
|
||||
// }
|
||||
|
||||
// T get() {
|
||||
// if (_getter != null)
|
||||
// return _getter();
|
||||
// else
|
||||
// return _value;
|
||||
// }
|
||||
|
||||
// Property([Function() getter, Function(T) setter]) {}
|
||||
// }
|
||||
|
||||
class Prop {
|
||||
final String name;
|
||||
final Type type;
|
||||
final bool isArray;
|
||||
final String readAnnotation;
|
||||
final String writeAnnotation;
|
||||
Prop(this.name, this.type, this.isArray, [this.readAnnotation = null, this.writeAnnotation = null]);
|
||||
}
|
||||
|
||||
class Evt {
|
||||
final String name;
|
||||
final bool listenable;
|
||||
final Type type;
|
||||
final bool isArray;
|
||||
final String annotation;
|
||||
|
||||
Evt(this.name, this.type, this.isArray, [this.listenable = false, this.annotation]);
|
||||
}
|
||||
|
||||
class Func {
|
||||
final String name;
|
||||
final Type returnType;
|
||||
final List<Arg> argsType;
|
||||
final bool isArray;
|
||||
final String annotation;
|
||||
|
||||
Func(this.name, this.returnType, this.argsType, this.isArray,
|
||||
[this.annotation = null]);
|
||||
}
|
||||
|
||||
class Arg {
|
||||
final String name;
|
||||
final Type type;
|
||||
final bool isArray;
|
||||
|
||||
Arg(this.name, this.type, this.isArray);
|
||||
}
|
6
lib/src/Resource/Template/TemplateType.dart
Normal file
6
lib/src/Resource/Template/TemplateType.dart
Normal file
@ -0,0 +1,6 @@
|
||||
enum TemplateType {
|
||||
Unspecified,
|
||||
Resource,
|
||||
Record,
|
||||
Wrapper,
|
||||
}
|
550
lib/src/Resource/Template/TypeTemplate.dart
Normal file
550
lib/src/Resource/Template/TypeTemplate.dart
Normal file
@ -0,0 +1,550 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import '../../Data/BinaryList.dart';
|
||||
import '../../Security/Integrity/SHA256.dart';
|
||||
|
||||
import '../../Data/IRecord.dart';
|
||||
import '../IResource.dart';
|
||||
import '../Warehouse.dart';
|
||||
import './TemplateDescriber.dart';
|
||||
|
||||
import './MemberTemplate.dart';
|
||||
import '../../Data/Guid.dart';
|
||||
import '../../Data/DC.dart';
|
||||
import './EventTemplate.dart';
|
||||
import './PropertyTemplate.dart';
|
||||
import './FunctionTemplate.dart';
|
||||
import '../StorageMode.dart';
|
||||
import 'ArgumentTemplate.dart';
|
||||
import 'TemplateDataType.dart';
|
||||
import 'TemplateType.dart';
|
||||
|
||||
class TypeTemplate {
|
||||
Guid _classId;
|
||||
String _className;
|
||||
List<MemberTemplate> _members = [];
|
||||
List<FunctionTemplate> _functions = [];
|
||||
List<EventTemplate> _events = [];
|
||||
List<PropertyTemplate> _properties = [];
|
||||
int _version;
|
||||
//bool isReady;
|
||||
|
||||
TemplateType _templateType;
|
||||
|
||||
DC _content;
|
||||
|
||||
DC get content => _content;
|
||||
|
||||
TemplateType get type => _templateType;
|
||||
|
||||
Type _definedType;
|
||||
|
||||
Type get definedType => _definedType;
|
||||
/*
|
||||
MemberTemplate getMemberTemplate(MemberInfo member)
|
||||
{
|
||||
if (member is MethodInfo)
|
||||
return getFunctionTemplate(member.Name);
|
||||
else if (member is EventInfo)
|
||||
return getEventTemplate(member.Name);
|
||||
else if (member is PropertyInfo)
|
||||
return getPropertyTemplate(member.Name);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
//@TODO: implement
|
||||
static List<TypeTemplate> getDependencies(TypeTemplate template) =>
|
||||
[];
|
||||
|
||||
EventTemplate getEventTemplateByName(String eventName) {
|
||||
for (var i in _events) if (i.name == eventName) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
EventTemplate getEventTemplateByIndex(int index) {
|
||||
for (var i in _events) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByName(String functionName) {
|
||||
for (var i in _functions) if (i.name == functionName) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByIndex(int index) {
|
||||
for (var i in _functions) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByIndex(int index) {
|
||||
for (var i in _properties) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByName(String propertyName) {
|
||||
for (var i in _properties) if (i.name == propertyName) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
static Guid getTypeGuid(String typeName) {
|
||||
var tn = DC.stringToBytes(typeName);
|
||||
var hash = SHA256.compute(tn).clip(0, 16);
|
||||
return new Guid(hash);
|
||||
}
|
||||
|
||||
Guid get classId => _classId;
|
||||
|
||||
String get className => _className;
|
||||
|
||||
List<MemberTemplate> get methods => _members;
|
||||
|
||||
List<FunctionTemplate> get functions => _functions;
|
||||
|
||||
List<EventTemplate> get events => _events;
|
||||
|
||||
List<PropertyTemplate> get properties => _properties;
|
||||
|
||||
TypeTemplate.fromType(Type type, [bool addToWarehouse, bool isWrapper]) {
|
||||
var instance = Warehouse.createInstance(type);
|
||||
|
||||
if (instance is IRecord)
|
||||
_templateType = TemplateType.Record;
|
||||
else if (instance is IResource)
|
||||
_templateType = TemplateType.Resource;
|
||||
else
|
||||
throw new Exception("Type is neither a resource nor a record.");
|
||||
|
||||
TemplateDescriber describer = instance.template;
|
||||
|
||||
_definedType = type;
|
||||
|
||||
_className = describer.nameSpace;
|
||||
|
||||
// set guid
|
||||
_classId = getTypeGuid(_className);
|
||||
|
||||
if (addToWarehouse) Warehouse.putTemplate(this);
|
||||
// _templates.add(template.classId, template);
|
||||
|
||||
for (var i = 0; i < describer.properties.length; i++) {
|
||||
var pi = describer.properties[i];
|
||||
var pt = PropertyTemplate(
|
||||
this,
|
||||
i,
|
||||
pi.name,
|
||||
TemplateDataType.fromType(pi.type, pi.isArray),
|
||||
pi.readAnnotation,
|
||||
pi.writeAnnotation,
|
||||
0);
|
||||
properties.add(pt);
|
||||
}
|
||||
|
||||
for (var i = 0; i < describer.functions.length; i++) {
|
||||
var fi = describer.functions[i];
|
||||
|
||||
List<ArgumentTemplate> args = fi.argsType.map((arg) => ArgumentTemplate(
|
||||
arg.name, TemplateDataType.fromType(arg.type, arg.isArray)));
|
||||
|
||||
var ft = FunctionTemplate(this, i, fi.name, args,
|
||||
TemplateDataType.fromType(fi.returnType, fi.isArray), fi.annotation);
|
||||
|
||||
functions.add(ft);
|
||||
}
|
||||
|
||||
for (var i = 0; i < describer.events.length; i++) {
|
||||
var ei = describer.events[i];
|
||||
|
||||
var et = new EventTemplate(
|
||||
this,
|
||||
i,
|
||||
ei.name,
|
||||
TemplateDataType.fromType(ei.type, ei.isArray),
|
||||
ei.annotation,
|
||||
ei.listenable);
|
||||
|
||||
events.add(et);
|
||||
}
|
||||
|
||||
// append signals
|
||||
events.forEach(_members.add);
|
||||
// append slots
|
||||
functions.forEach(_members.add);
|
||||
// append properties
|
||||
properties.forEach(_members.add);
|
||||
|
||||
// bake it binarily
|
||||
var b = new BinaryList();
|
||||
b
|
||||
.addUint8(_templateType.index)
|
||||
.addGuid(classId)
|
||||
.addUint8(className.length)
|
||||
.addString(className)
|
||||
.addInt32(_version)
|
||||
.addUint16(_members.length);
|
||||
|
||||
functions.forEach((ft) => b.addDC(ft.compose()));
|
||||
properties.forEach((pt) => b.addDC(pt.compose()));
|
||||
events.forEach((et) => b.addDC(et.compose()));
|
||||
|
||||
_content = b.toDC();
|
||||
}
|
||||
|
||||
// static Guid getTypeGuid(Type type) => getTypeGuid(type.toString());
|
||||
|
||||
// static Guid getTypeGuid(String typeName)
|
||||
// {
|
||||
// var tn = Encoding.UTF8.GetBytes(typeName);
|
||||
// var hash = SHA256.Create().ComputeHash(tn).Clip(0, 16);
|
||||
|
||||
// return new Guid(hash);
|
||||
// }
|
||||
|
||||
// static Type GetElementType(Type type) => type switch
|
||||
// {
|
||||
// { IsArray: true } => type.GetElementType(),
|
||||
// { IsEnum: true } => type.GetEnumUnderlyingType(),
|
||||
// (_) => type
|
||||
// };
|
||||
|
||||
// static TypeTemplate[] GetRuntimeTypes(TypeTemplate template)
|
||||
// {
|
||||
|
||||
// List<TypeTemplate> list = [];
|
||||
|
||||
// list.add(template);
|
||||
|
||||
// var getRuntimeTypes = null;
|
||||
|
||||
// getRuntimeTypes = (TypeTemplate tmp, List<TypeTemplate> bag)
|
||||
// {
|
||||
// if (template.resourceType == null)
|
||||
// return;
|
||||
|
||||
// // functions
|
||||
// tmp.functions.foreach((f){
|
||||
|
||||
// var frtt = Warehouse.GetTemplate(getElementType(f.MethodInfo.ReturnType));
|
||||
// if (frtt != null)
|
||||
// {
|
||||
// if (!bag.Contains(frtt))
|
||||
// {
|
||||
// list.Add(frtt);
|
||||
// getRuntimeTypes(frtt, bag);
|
||||
// }
|
||||
// }
|
||||
|
||||
// var args = f.MethodInfo.GetParameters();
|
||||
|
||||
// for(var i = 0; i < args.Length - 1; i++)
|
||||
// {
|
||||
// var fpt = Warehouse.GetTemplate(GetElementType(args[i].ParameterType));
|
||||
// if (fpt != null)
|
||||
// {
|
||||
// if (!bag.Contains(fpt))
|
||||
// {
|
||||
// bag.Add(fpt);
|
||||
// getRuntimeTypes(fpt, bag);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // skip DistributedConnection argument
|
||||
// if (args.Length > 0)
|
||||
// {
|
||||
// var last = args.Last();
|
||||
// if (last.ParameterType != typeof(DistributedConnection))
|
||||
// {
|
||||
// var fpt = Warehouse.GetTemplate(GetElementType(last.ParameterType));
|
||||
// if (fpt != null)
|
||||
// {
|
||||
// if (!bag.Contains(fpt))
|
||||
// {
|
||||
// bag.Add(fpt);
|
||||
// getRuntimeTypes(fpt, bag);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// });
|
||||
|
||||
// // properties
|
||||
// foreach (var p in tmp.properties)
|
||||
// {
|
||||
// var pt = Warehouse.GetTemplate(GetElementType(p.PropertyInfo.PropertyType));
|
||||
// if (pt != null)
|
||||
// {
|
||||
// if (!bag.Contains(pt))
|
||||
// {
|
||||
// bag.Add(pt);
|
||||
// getRuntimeTypes(pt, bag);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // events
|
||||
// foreach (var e in tmp.events)
|
||||
// {
|
||||
// var et = Warehouse.GetTemplate(GetElementType(e.EventInfo.EventHandlerType.GenericTypeArguments[0]));
|
||||
|
||||
// if (et != null)
|
||||
// {
|
||||
// if (!bag.Contains(et))
|
||||
// {
|
||||
// bag.Add(et);
|
||||
// getRuntimeTypes(et, bag);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// getRuntimeTypes(template, list);
|
||||
// return list.ToArray();
|
||||
// }
|
||||
|
||||
// @TODO Create template from type
|
||||
// TypeTemplate.fromType(Type type) {
|
||||
|
||||
// }
|
||||
|
||||
/*
|
||||
TypeTemplate(Type type)
|
||||
{
|
||||
|
||||
type = ResourceProxy.GetBaseType(type);
|
||||
|
||||
// set guid
|
||||
|
||||
var typeName = Encoding.UTF8.GetBytes(type.FullName);
|
||||
var hash = SHA256.Create().ComputeHash(typeName).Clip(0, 16);
|
||||
|
||||
classId = new Guid(hash);
|
||||
className = type.FullName;
|
||||
|
||||
|
||||
#if NETSTANDARD1_5
|
||||
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
|
||||
#else
|
||||
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
|
||||
#endif
|
||||
|
||||
//byte currentIndex = 0;
|
||||
|
||||
byte i = 0;
|
||||
|
||||
foreach (var pi in propsInfo)
|
||||
{
|
||||
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
|
||||
if (ps.Length > 0)
|
||||
{
|
||||
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
|
||||
pt.Info = pi;
|
||||
properties.Add(pt);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
foreach (var ei in eventsInfo)
|
||||
{
|
||||
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
|
||||
if (es.Length > 0)
|
||||
{
|
||||
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
|
||||
events.Add(et);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
foreach (MethodInfo mi in methodsInfo)
|
||||
{
|
||||
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
|
||||
if (fs.Length > 0)
|
||||
{
|
||||
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
|
||||
functions.Add(ft);
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (i = 0; i < events.Count; i++)
|
||||
members.Add(events[i]);
|
||||
// append slots
|
||||
for (i = 0; i < functions.Count; i++)
|
||||
members.Add(functions[i]);
|
||||
// append properties
|
||||
for (i = 0; i < properties.Count; i++)
|
||||
members.Add(properties[i]);
|
||||
|
||||
// bake it binarily
|
||||
var b = new BinaryList();
|
||||
b.AddGuid(classId)
|
||||
.AddUInt8((byte)className.Length)
|
||||
.AddString(className)
|
||||
.AddInt32(version)
|
||||
.AddUInt16((ushort)members.Count);
|
||||
|
||||
|
||||
foreach (var ft in functions)
|
||||
b.AddUInt8Array(ft.Compose());
|
||||
foreach (var pt in properties)
|
||||
b.AddUInt8Array(pt.Compose());
|
||||
foreach (var et in events)
|
||||
b.AddUInt8Array(et.Compose());
|
||||
|
||||
content = b.ToArray();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
TypeTemplate.parse(DC data, [int offset = 0, int contentLength]) {
|
||||
// cool Dart feature
|
||||
contentLength ??= data.length;
|
||||
|
||||
int ends = offset + contentLength;
|
||||
|
||||
int oOffset = offset;
|
||||
|
||||
// start parsing...
|
||||
|
||||
//var od = new TypeTemplate();
|
||||
_content = data.clip(offset, contentLength);
|
||||
|
||||
_templateType = TemplateType.values[data.getUint8(offset++)];
|
||||
|
||||
_classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
_className = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
_version = data.getInt32(offset);
|
||||
offset += 4;
|
||||
|
||||
var methodsCount = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
var functionIndex = 0;
|
||||
var propertyIndex = 0;
|
||||
var eventIndex = 0;
|
||||
|
||||
for (int i = 0; i < methodsCount; i++) {
|
||||
var type = data[offset] >> 5;
|
||||
|
||||
if (type == 0) // function
|
||||
{
|
||||
String expansion = null;
|
||||
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
var dt = TemplateDataType.parse(data, offset);
|
||||
offset += dt.size;
|
||||
|
||||
// arguments count
|
||||
var argsCount = data[offset++];
|
||||
List<ArgumentTemplate> arguments = [];
|
||||
|
||||
for (var a = 0; a < argsCount; a++) {
|
||||
var art = ArgumentTemplate.parse(data, offset);
|
||||
arguments.add(art.value);
|
||||
offset += art.size;
|
||||
}
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var ft = new FunctionTemplate(
|
||||
this, functionIndex++, name, arguments, dt.value, expansion);
|
||||
|
||||
_functions.add(ft);
|
||||
} else if (type == 1) // property
|
||||
{
|
||||
String readExpansion = null, writeExpansion = null;
|
||||
|
||||
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
|
||||
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
var recordable = ((data[offset] & 1) == 1);
|
||||
var permission = (data[offset++] >> 1) & 0x3;
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
|
||||
offset += data[offset] + 1;
|
||||
|
||||
var dt = TemplateDataType.parse(data, offset);
|
||||
|
||||
offset += dt.size;
|
||||
|
||||
if (hasReadExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
readExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
if (hasWriteExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
writeExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var pt = new PropertyTemplate(
|
||||
this,
|
||||
propertyIndex++,
|
||||
name,
|
||||
dt.value,
|
||||
readExpansion,
|
||||
writeExpansion,
|
||||
recordable ? StorageMode.Recordable : StorageMode.Volatile);
|
||||
|
||||
_properties.add(pt);
|
||||
} else if (type == 2) // Event
|
||||
{
|
||||
String expansion = null;
|
||||
var hasExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
var listenable = ((data[offset++] & 0x8) == 0x8);
|
||||
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
var dt = TemplateDataType.parse(data, offset);
|
||||
|
||||
offset += dt.size;
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
var et = new EventTemplate(
|
||||
this, eventIndex++, name, dt.value, expansion, listenable);
|
||||
|
||||
_events.add(et);
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
for (int i = 0; i < _events.length; i++) _members.add(_events[i]);
|
||||
// append slots
|
||||
for (int i = 0; i < _functions.length; i++) _members.add(_functions[i]);
|
||||
// append properties
|
||||
for (int i = 0; i < _properties.length; i++) _members.add(_properties[i]);
|
||||
}
|
||||
}
|
@ -23,7 +23,8 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
import '../Data/AutoList.dart';
|
||||
import './Template/ResourceTemplate.dart';
|
||||
import 'Template/TemplateType.dart';
|
||||
import 'Template/TypeTemplate.dart';
|
||||
import '../Data/Guid.dart';
|
||||
import '../Data/KeyList.dart';
|
||||
import '../Data/Structure.dart';
|
||||
@ -44,20 +45,30 @@ class Warehouse {
|
||||
static Map<int, IResource> _resources = new Map<int, IResource>();
|
||||
static int resourceCounter = 0;
|
||||
|
||||
static KeyList<Guid, ResourceTemplate> _templates =
|
||||
new KeyList<Guid, ResourceTemplate>();
|
||||
|
||||
//public delegate void StoreConnectedEvent(IStore store, string name);
|
||||
//public delegate void StoreDisconnectedEvent(IStore store);
|
||||
static KeyList<TemplateType, KeyList<Guid, TypeTemplate>> _templates =
|
||||
_initTemplates(); //
|
||||
|
||||
//public static event StoreConnectedEvent StoreConnected;
|
||||
///public static event StoreDisconnectedEvent StoreDisconnected;
|
||||
static _initTemplates() {
|
||||
var rt = new KeyList<TemplateType, KeyList<Guid, TypeTemplate>>();
|
||||
|
||||
static bool _warehouseIsOpen = false;
|
||||
rt.add(TemplateType.Unspecified, new KeyList<Guid, TypeTemplate>());
|
||||
rt.add(TemplateType.Resource, new KeyList<Guid, TypeTemplate>());
|
||||
rt.add(TemplateType.Record, new KeyList<Guid, TypeTemplate>());
|
||||
rt.add(TemplateType.Wrapper, new KeyList<Guid, TypeTemplate>());
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
static KeyList<Type, Function()> _factory = _getBuiltInTypes();
|
||||
|
||||
static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
|
||||
protocols = _getSupportedProtocols();
|
||||
|
||||
|
||||
static bool _warehouseIsOpen = false;
|
||||
|
||||
static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))');
|
||||
|
||||
/// <summary>
|
||||
@ -162,7 +173,7 @@ class Warehouse {
|
||||
|
||||
static List<IResource> qureyIn(
|
||||
List<String> path, int index, AutoList<IResource, Instance> resources) {
|
||||
var rt = new List<IResource>();
|
||||
List<IResource> rt = [];
|
||||
|
||||
if (index == path.length - 1) {
|
||||
if (path[index] == "")
|
||||
@ -206,11 +217,11 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Resource instance.</returns>
|
||||
static AsyncReply<dynamic> get(String path,
|
||||
static AsyncReply<T> get<T extends IResource>(String path,
|
||||
[attributes = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null]) {
|
||||
var rt = AsyncReply<IResource>();
|
||||
var rt = AsyncReply<T>();
|
||||
|
||||
// Should we create a new store ?
|
||||
if (_urlRegex.hasMatch(path)) {
|
||||
@ -226,7 +237,7 @@ class Warehouse {
|
||||
rt.trigger(r);
|
||||
}).error((e) => rt.triggerError(e));
|
||||
else
|
||||
rt.trigger(store);
|
||||
rt.trigger(store as T);
|
||||
}).error((e) {
|
||||
rt.triggerError(e);
|
||||
//Warehouse.remove(store);
|
||||
@ -333,14 +344,74 @@ class Warehouse {
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
|
||||
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
||||
static AsyncReply<bool> put(IResource resource, String name,
|
||||
static AsyncReply<T> put<T extends IResource>(String name, T resource,
|
||||
[IStore store = null,
|
||||
IResource parent = null,
|
||||
ResourceTemplate customTemplate = null,
|
||||
TypeTemplate customTemplate = null,
|
||||
int age = 0,
|
||||
IPermissionsManager manager = null,
|
||||
attributes = null]) {
|
||||
var rt = AsyncReply<bool>();
|
||||
var rt = AsyncReply<T>();
|
||||
|
||||
if (resource.instance != null) {
|
||||
rt.triggerError(Exception("Resource has a store."));
|
||||
return rt;
|
||||
}
|
||||
|
||||
// @TODO: Trim left '/' char
|
||||
// var path = name.trimLeft().split("/");
|
||||
// if (path.length > 1)
|
||||
// {
|
||||
// if (parent != null)
|
||||
// rt.triggerError(Exception("Parent can't be set when using path in instance name"));
|
||||
|
||||
// Warehouse.get<IResource>(path.take(path.length - 1).join("/")).then((value){
|
||||
// if (value == null)
|
||||
// rt.triggerError(Exception("Can't find parent"));
|
||||
|
||||
// parent = value;
|
||||
|
||||
// store = store ?? parent.instance.store;
|
||||
|
||||
// var instanceName = path.last;
|
||||
|
||||
// if (store == null)
|
||||
// {
|
||||
// // assign parent as a store
|
||||
// if (parent is IStore)
|
||||
// {
|
||||
// store = (IStore)parent;
|
||||
// stores
|
||||
// List<WeakReference<IResource>> list;
|
||||
// if (stores.TryGetValue(store, out list))
|
||||
// lock (((ICollection)list).SyncRoot)
|
||||
// list.Add(resourceReference);
|
||||
// //stores[store].Add(resourceReference);
|
||||
// }
|
||||
// // assign parent's store as a store
|
||||
// else if (parent != null)
|
||||
// {
|
||||
// store = parent.instance.store;
|
||||
|
||||
// List<WeakReference<IResource>> list;
|
||||
// if (stores.TryGetValue(store, out list))
|
||||
// lock (((ICollection)list).SyncRoot)
|
||||
// list.Add(resourceReference);
|
||||
|
||||
// //stores[store].Add(resourceReference);
|
||||
// }
|
||||
// // assign self as a store (root store)
|
||||
// else if (resource is IStore)
|
||||
// {
|
||||
// store = resource;
|
||||
// }
|
||||
// else
|
||||
// throw new Exception("Can't find a store for the resource.");
|
||||
// }
|
||||
|
||||
// });
|
||||
|
||||
// }
|
||||
|
||||
resource.instance = new Instance(
|
||||
resourceCounter++, name, resource, store, customTemplate, age);
|
||||
@ -364,11 +435,17 @@ class Warehouse {
|
||||
resource.trigger(ResourceTrigger.Initialize).then<dynamic>((value) {
|
||||
if (resource is IStore)
|
||||
resource.trigger(ResourceTrigger.Open).then<dynamic>((value) {
|
||||
rt.trigger(value);
|
||||
}).error((ex) => rt.triggerError(ex));
|
||||
rt.trigger(resource);
|
||||
}).error((ex) {
|
||||
Warehouse.remove(resource);
|
||||
rt.triggerError(ex);
|
||||
});
|
||||
else
|
||||
rt.trigger(value);
|
||||
}).error((ex) => rt.triggerError(ex));
|
||||
rt.trigger(resource);
|
||||
}).error((ex) {
|
||||
Warehouse.remove(resource);
|
||||
rt.triggerError(ex);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -380,8 +457,11 @@ class Warehouse {
|
||||
if (value)
|
||||
initResource();
|
||||
else
|
||||
rt.trigger(false);
|
||||
}).error((ex) => rt.triggerError(ex));
|
||||
rt.trigger(null);
|
||||
}).error((ex) {
|
||||
Warehouse.remove(resource);
|
||||
rt.triggerError(ex);
|
||||
});
|
||||
}
|
||||
|
||||
// return new name
|
||||
@ -389,12 +469,18 @@ class Warehouse {
|
||||
return rt;
|
||||
}
|
||||
|
||||
static AsyncReply<T> New<T extends IResource>(T resource, String name,
|
||||
static T createInstance<T>(Type T) {
|
||||
return _factory[T].call();
|
||||
}
|
||||
|
||||
static AsyncReply<T> newResource<T extends IResource>(String name,
|
||||
[IStore store = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null,
|
||||
attributes = null,
|
||||
properties = null]) {
|
||||
var resource = _factory[T].call();
|
||||
|
||||
if (properties != null) {
|
||||
dynamic d = resource;
|
||||
|
||||
@ -405,9 +491,9 @@ class Warehouse {
|
||||
|
||||
var rt = AsyncReply<T>();
|
||||
|
||||
put(resource, name, store, parent, null, 0, manager, attributes)
|
||||
.then<bool>((value) {
|
||||
if (value)
|
||||
put<T>(name, resource, store, parent, null, 0, manager, attributes)
|
||||
.then<IResource>((value) {
|
||||
if (value != null)
|
||||
rt.trigger(resource);
|
||||
else
|
||||
rt.trigger(null);
|
||||
@ -427,49 +513,77 @@ class Warehouse {
|
||||
/// Put a resource template in the templates warehouse.
|
||||
/// </summary>
|
||||
/// <param name="template">Resource template.</param>
|
||||
static void putTemplate(ResourceTemplate template) {
|
||||
if (!_templates.containsKey(template.classId))
|
||||
_templates.add(template.classId, template);
|
||||
static void putTemplate(TypeTemplate template) {
|
||||
_templates[template.type][template.classId] = template;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a template by type from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||
/// Get a template by type from the templates warehouse. If not in the warehouse, a new TypeTemplate is created and added to the warehouse.
|
||||
/// </summary>
|
||||
/// <param name="type">.Net type.</param>
|
||||
/// <returns>Resource template.</returns>
|
||||
static ResourceTemplate getTemplateByType(Type type) {
|
||||
static TypeTemplate getTemplateByType(Type type) {
|
||||
// loaded ?
|
||||
for (var t in _templates.values)
|
||||
if (t.className == type.toString()) return t;
|
||||
for (var tmps in _templates.values)
|
||||
for (var tmp in tmps.values)
|
||||
if (tmp.className == type.toString()) return tmp;
|
||||
|
||||
var template = new ResourceTemplate.fromType(type);
|
||||
_templates.add(template.classId, template);
|
||||
var template = new TypeTemplate.fromType(type, true);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a template by class Id from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||
/// Get a template by class Id from the templates warehouse. If not in the warehouse, a new TypeTemplate is created and added to the warehouse.
|
||||
/// </summary>
|
||||
/// <param name="classId">Class Id.</param>
|
||||
/// <returns>Resource template.</returns>
|
||||
static AsyncReply<ResourceTemplate> getTemplateByClassId(Guid classId) {
|
||||
if (_templates.containsKey(classId))
|
||||
return new AsyncReply<ResourceTemplate>.ready(_templates[classId]);
|
||||
return null;
|
||||
static TypeTemplate getTemplateByClassId(Guid classId,
|
||||
[TemplateType templateType = TemplateType.Unspecified]) {
|
||||
if (templateType == TemplateType.Unspecified) {
|
||||
// look in resources
|
||||
var template = _templates[TemplateType.Resource][classId];
|
||||
if (template != null) return template;
|
||||
|
||||
// look in records
|
||||
template = _templates[TemplateType.Record][classId];
|
||||
if (template != null) return template;
|
||||
|
||||
// look in wrappers
|
||||
template = _templates[TemplateType.Wrapper][classId];
|
||||
return template;
|
||||
} else {
|
||||
return _templates[templateType][classId];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a template by class name from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
|
||||
/// Get a template by class name from the templates warehouse. If not in the warehouse, a new TypeTemplate is created and added to the warehouse.
|
||||
/// </summary>
|
||||
/// <param name="className">Class name.</param>
|
||||
/// <returns>Resource template.</returns>
|
||||
static AsyncReply<ResourceTemplate> getTemplateByClassName(String className) {
|
||||
for (var t in _templates.values)
|
||||
if (t.className == className)
|
||||
return new AsyncReply<ResourceTemplate>.ready(t);
|
||||
static TypeTemplate getTemplateByClassName(String className, [TemplateType templateType = TemplateType.Unspecified]) {
|
||||
|
||||
return null;
|
||||
if (templateType == TemplateType.Unspecified)
|
||||
{
|
||||
// look in resources
|
||||
var template = _templates[TemplateType.Resource].values.firstWhere((x) => x.className == className);
|
||||
if (template != null)
|
||||
return template;
|
||||
|
||||
// look in records
|
||||
template = _templates[TemplateType.Record].values.firstWhere((x) => x.className == className);
|
||||
if (template != null)
|
||||
return template;
|
||||
|
||||
// look in wrappers
|
||||
template = _templates[TemplateType.Wrapper].values.firstWhere((x) => x.className == className);
|
||||
return template;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _templates[templateType].values.firstWhere((x) => x.className == className);
|
||||
}
|
||||
}
|
||||
|
||||
static bool remove(IResource resource) {
|
||||
@ -505,8 +619,15 @@ class Warehouse {
|
||||
new KeyList<String, AsyncReply<IStore> Function(String, dynamic)>();
|
||||
rt.add(
|
||||
"iip",
|
||||
(String name, attributes) => Warehouse.New<DistributedConnection>(
|
||||
DistributedConnection(), name, null, null, null, attributes));
|
||||
(String name, attributes) =>
|
||||
Warehouse.newResource<DistributedConnection>(
|
||||
name, null, null, null, attributes));
|
||||
return rt;
|
||||
}
|
||||
|
||||
static KeyList<Type, Function()> _getBuiltInTypes() {
|
||||
var rt = KeyList<Type, Function()>();
|
||||
rt.add(DistributedConnection, () => DistributedConnection());
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
|
@ -36,5 +36,6 @@ enum ActionType
|
||||
AddChild,
|
||||
RemoveChild,
|
||||
Rename,
|
||||
ReceiveEvent
|
||||
ReceiveEvent,
|
||||
ViewTemplate
|
||||
}
|
143
pubspec.lock
143
pubspec.lock
@ -7,16 +7,16 @@ packages:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "22.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.39.4"
|
||||
version: "1.7.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
@ -28,77 +28,84 @@ packages:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.7.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
version: "1.3.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.12"
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.0"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.9"
|
||||
version: "0.15.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
csslib:
|
||||
version: "3.0.1"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.0+3"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.0+4"
|
||||
version: "2.0.1"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -126,28 +133,28 @@ packages:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.1+1"
|
||||
version: "0.6.3"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.6"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.8"
|
||||
version: "1.3.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -155,27 +162,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.6+3"
|
||||
multi_server_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: multi_server_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1+2"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -189,35 +175,35 @@ packages:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.2"
|
||||
version: "2.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
version: "1.8.0"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.11.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.5.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -238,7 +224,7 @@ packages:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
version: "0.2.9+2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -246,83 +232,90 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
source_gen:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.9"
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.1.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.2"
|
||||
version: "1.16.5"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.15"
|
||||
version: "0.2.19"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.3"
|
||||
version: "0.3.15"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
version: "1.3.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -336,27 +329,27 @@ packages:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+14"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0+1"
|
||||
version: "1.0.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.7.0 <3.0.0"
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
|
@ -1,13 +1,17 @@
|
||||
name: esiur
|
||||
description: Distributed Object Framework.
|
||||
version: 1.2.6
|
||||
# author: Ahmed Zamil <ahmed@dijlh.com>
|
||||
version: 1.3.0
|
||||
# author: Ahmed Zamil <ahmed@esiur.com>
|
||||
homepage: https://github.com/esiur/esiur-dart
|
||||
|
||||
|
||||
environment:
|
||||
sdk: ">=2.1.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
source_gen: ^1.0.2
|
||||
args: #
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.14.2
|
||||
|
||||
|
@ -1,12 +1,22 @@
|
||||
import 'package:esiur/src/Proxy/TemplateGenerator.dart';
|
||||
import "package:test/test.dart";
|
||||
import 'package:esiur/esiur.dart';
|
||||
import 'dart:io';
|
||||
import '../lib/localhost/Esiur.Generated.dart';
|
||||
import 'TestResource.dart';
|
||||
|
||||
main() async {
|
||||
try {
|
||||
var x = await Warehouse.get("iip://localhost:5070/sys/cp",
|
||||
{"username": "admin", "password": "1234", "domain": "example.com"});
|
||||
print(x);
|
||||
testMe();
|
||||
|
||||
var c = EsiurGenerated;
|
||||
print(c);
|
||||
print(Warehouse.protocols.length);
|
||||
|
||||
await TemplateGenerator.getTemplate("iip://localhost/sys/cp");
|
||||
// var x = await Warehouse.get("iip://localhost/sys/cp",
|
||||
// {"username": "guest", "password": "123456", "domain": "example.com"});
|
||||
// print(x);
|
||||
} catch (ex) {
|
||||
print("Error occured");
|
||||
print(ex);
|
||||
|
Loading…
x
Reference in New Issue
Block a user