2
0
mirror of https://github.com/esiur/esiur-dart.git synced 2025-05-06 04:02:57 +00:00
This commit is contained in:
Ahmed Zamil 2021-07-14 05:16:40 +03:00
parent 7971c836b7
commit 737397da11
50 changed files with 6238 additions and 4926 deletions

8
.vscode/launch.json vendored
View File

@ -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"],
}
]
}

View File

@ -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
View 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
View 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
View 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;
''';
}
}

View File

@ -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';

View File

@ -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() {}
}

View File

@ -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() {}
}

View File

@ -31,5 +31,9 @@ enum ExceptionCode
SetPropertyDenied,
ReadOnlyProperty,
GeneralFailure,
AddToStoreFailed
AddToStoreFailed,
NotAttached,
AlreadyListened,
AlreadyUnlistened,
NotListenable
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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
View 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;
}

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

View File

@ -0,0 +1,6 @@
class RecordComparisonResult {
static const Null = 0;
static const Record = 1;
static const RecordSameType = 2;
static const Same = 3;
}

View 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
View 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

View File

@ -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;

View 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");
}

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

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

View File

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

View File

@ -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)

View File

@ -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
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

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

View File

@ -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;
}

View File

@ -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;

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

View File

@ -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) {}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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]);
}
}

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

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

View File

@ -0,0 +1,6 @@
enum TemplateType {
Unspecified,
Resource,
Record,
Wrapper,
}

View 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]);
}
}

View File

@ -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;
}
}

View File

@ -36,5 +36,6 @@ enum ActionType
AddChild,
RemoveChild,
Rename,
ReceiveEvent
ReceiveEvent,
ViewTemplate
}

View File

@ -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"

View File

@ -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

View File

@ -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);