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", "program": "test/main.dart",
"request": "launch", "request": "launch",
"type": "dart" "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 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 Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal 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/MemberType.dart';
export 'src/Resource/Template/PropertyPermission.dart'; export 'src/Resource/Template/PropertyPermission.dart';
export 'src/Resource/Template/PropertyTemplate.dart'; export 'src/Resource/Template/PropertyTemplate.dart';
export 'src/Resource/Template/ResourceTemplate.dart'; export 'src/Resource/Template/TypeTemplate.dart';
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Core // Core
@ -44,7 +44,8 @@ export 'src/Data/Structure.dart';
export 'src/Data/StructureComparisonResult.dart'; export 'src/Data/StructureComparisonResult.dart';
export 'src/Data/StructureMetadata.dart'; export 'src/Data/StructureMetadata.dart';
export 'src/Data/ValueObject.dart'; export 'src/Data/ValueObject.dart';
export 'src/Data/IRecord.dart';
export 'src/Data/Record.dart';
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Net // Net
export 'src/Net/NetworkBuffer.dart'; export 'src/Net/NetworkBuffer.dart';

View File

@ -1,63 +1,50 @@
import 'AsyncReply.dart'; 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 = <T>[];
List<AsyncReply<T>> _replies = new List<AsyncReply<T>>(); int _count = 0;
List<T> _results = new List<T>(); bool _sealedBag = false;
int _count = 0; Type arrayType;
bool _sealedBag = false;
seal() seal() {
{ //print("SEALED");
//print("SEALED");
if (_sealedBag) if (_sealedBag) return;
return;
_sealedBag = true; _sealedBag = true;
if (_results.length == 0) if (_results.length == 0) trigger(new List<T>());
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 k = _replies[i]; var index = i;
var index = i;
k.then<dynamic>((r) k.then<dynamic>((r) {
{ _results[index] = r;
_results[index] = r; _count++;
_count++; //print("Seal ${_count}/${_results.length}");
//print("Seal ${_count}/${_results.length}"); if (_count == _results.length) trigger(_results);
if (_count == _results.length) }).error((ex) {
trigger(_results); triggerError(ex);
}).error((ex){ });
triggerError(ex);
});
}
} }
}
add(AsyncReply<T> reply) add(AsyncReply<T> reply) {
{ if (!_sealedBag) {
if (!_sealedBag) _results.add(null);
{ _replies.add(reply);
_results.add(null);
_replies.add(reply);
}
} }
}
addBag(AsyncBag<T> bag) addBag(AsyncBag<T> bag) {
{ bag._replies.forEach((r) {
bag._replies.forEach((r) { add(r);
add(r); });
}); }
}
AsyncBag()
{
}
AsyncBag() {}
} }

View File

@ -26,196 +26,155 @@ import 'dart:core';
import 'AsyncException.dart'; import 'AsyncException.dart';
import 'ProgressType.dart'; import 'ProgressType.dart';
class AsyncReply<T> implements Future<T> class AsyncReply<T> implements Future<T> {
{ List<Function(T)> _callbacks = new List<Function(T)>();
List<Function(T)> _callbacks = new List<Function(T)>(); T _result;
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)>();
List<Function(T)> _chunkCallbacks = new List<Function(T)>(); bool _resultReady = false;
AsyncException _exception;
bool get ready {
return _resultReady;
}
set ready(value) {
_resultReady = value;
}
bool _resultReady = false; T get result {
AsyncException _exception; return _result;
}
setResultReady(bool val) {
_resultReady = val;
}
bool get ready AsyncReply<T> next(Function(T) callback) {
{
return _resultReady;
}
set ready(value)
{
_resultReady = value;
}
T get result
{
return _result;
}
setResultReady(bool val)
{
_resultReady = val;
}
AsyncReply<T> next(Function(T) callback)
{
then(callback); then(callback);
return this; 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);
_callbacks.add(onValue); if (onError != null) {
if (onError != null) if (onError is Function(dynamic, dynamic)) {
{ _errorCallbacks.add((ex) => onError(ex, null));
if (onError is Function(dynamic, dynamic)) } else if (onError is Function(dynamic)) {
{ _errorCallbacks.add(onError);
_errorCallbacks.add((ex)=>onError(ex, null)); } else if (onError is Function()) {
} _errorCallbacks.add((ex) => onError());
else if (onError is Function(dynamic)) } else if (onError is Function(Object, StackTrace)) {
{ _errorCallbacks.add((ex) => onError(ex, null));
_errorCallbacks.add(onError);
}
else if (onError is Function())
{
_errorCallbacks.add((ex)=>onError());
}
else if (onError is Function(Object, StackTrace))
{
_errorCallbacks.add((ex)=>onError(ex, null));
}
} }
}
if (_resultReady) onValue(result);
if (_resultReady) if (R == Null)
onValue(result); return null;
else
if (R == Null) return this as AsyncReply<R>;
return null;
else
return this as AsyncReply<R>;
} }
AsyncReply<T> whenComplete(FutureOr action()) AsyncReply<T> whenComplete(FutureOr action()) {
{
return this; return this;
//_callbacks.add(action); //_callbacks.add(action);
} }
Stream<T> asStream() Stream<T> asStream() {
{
return null; return null;
} }
AsyncReply<T> catchError(Function onError, {bool test(Object error)}) AsyncReply<T> catchError(Function onError, {bool test(Object error)}) {
{ return this.error(onError);
return this.error(onError);
} }
AsyncReply<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()}) AsyncReply<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()}) {
{
return this; return this;
} }
AsyncReply<T> error(Function(dynamic) callback) AsyncReply<T> error(Function(dynamic) callback) {
{ _errorCallbacks.add(callback);
_errorCallbacks.add(callback);
if (_exception != null) if (_exception != null) callback(_exception);
callback(_exception);
return this; return this;
} }
AsyncReply<T> progress(Function(ProgressType, int, int) callback) AsyncReply<T> progress(Function(ProgressType, int, int) callback) {
{ _progressCallbacks.add(callback);
_progressCallbacks.add(callback); return this;
return this; }
}
AsyncReply<T> chunk(Function(T) callback) {
_chunkCallbacks.add(callback);
return this;
}
AsyncReply<T> chunk(Function(T) callback) AsyncReply<T> trigger(T result) {
{ if (_resultReady) return this;
_chunkCallbacks.add(callback);
return this;
}
void trigger(T result) _result = result;
{ _resultReady = true;
// lock (callbacksLock) _callbacks.forEach((x) {
// { x(result);
if (_resultReady) });
return;
_result = result; return this;
_resultReady = true; }
_callbacks.forEach((x) { AsyncReply<T> triggerError(Exception exception) {
x(result); if (_resultReady) return this;
});
// } if (exception is AsyncException)
_exception = exception;
else
_exception = AsyncException.toAsyncException(exception);
} ///lock (callbacksLock)
//{
triggerError(Exception exception) if (this._errorCallbacks.length == 0)
{ throw _exception;
if (_resultReady) else
return; _errorCallbacks.forEach((x) {
x(_exception);
});
//}
if (exception is AsyncException) return this;
_exception = exception; }
else
_exception = AsyncException.toAsyncException(exception);
///lock (callbacksLock) AsyncReply<T> triggerProgress(ProgressType type, int value, int max) {
//{ _progressCallbacks.forEach((x) {
x(type, value, max);
});
if (this._errorCallbacks.length == 0) return this;
throw _exception; }
else
_errorCallbacks.forEach((x) {
x(_exception);
});
//}
} AsyncReply<T> triggerChunk(T value) {
_chunkCallbacks.forEach((x) {
x(value);
});
triggerProgress(ProgressType type, int value, int max) return this;
{ }
_progressCallbacks.forEach((x) {
x(type, value, max);
});
}
AsyncReply.ready(T result) {
_resultReady = true;
_result = result;
}
triggerChunk(T value) AsyncReply() {}
{
_chunkCallbacks.forEach((x) {
x(value);
});
}
AsyncReply.ready(T result)
{
_resultReady = true;
_result = result;
}
AsyncReply()
{
}
} }

View File

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

View File

@ -32,7 +32,7 @@ import 'Guid.dart';
class BinaryList class BinaryList
{ {
var _list = new List<int>(); var _list = <int>[];
int get length => _list.length; int get length => _list.length;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@ class DataType
ResourceLink = 0x11, ResourceLink = 0x11,
String = 0x12, String = 0x12,
Structure = 0x13, Structure = 0x13,
Record = 0x14,
//Stream, //Stream,
//Array = 0x80, //Array = 0x80,
VarArray = 0x80, VarArray = 0x80,
@ -66,6 +67,7 @@ class DataType
ResourceLinkArray = 0x91, ResourceLinkArray = 0x91,
StringArray = 0x92, StringArray = 0x92,
StructureArray = 0x93, StructureArray = 0x93,
RecordArray = 0x94,
NotModified = 0x7F, NotModified = 0x7F,
Unspecified = 0xFF; Unspecified = 0xFF;

View File

@ -1,16 +1,21 @@
import 'DC.dart'; import 'DC.dart';
class Guid class Guid {
{
DC _data; DC _data;
Guid(DC data) Guid(DC data) {
{
_data = data; _data = data;
} }
DC get value => _data; DC get value => _data;
bool operator ==(Object other) {
if (other is Guid)
return _data.sequenceEqual(other._data);
else
return false;
}
@override @override
String toString() { String toString() {
return _data.getString(0, _data.length); 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; //bool _isReady = false;
String _link; String _link;
int _age;
List _properties; List _properties;
bool _destroyed = false; bool _destroyed = false;
List<KeyValuePair<int, dynamic>> _queued_updates = List<KeyValuePair<int, dynamic>> _queued_updates = [];
List<KeyValuePair<int, dynamic>>();
/// <summary> /// <summary>
/// Connection responsible for the distributed resource. /// Connection responsible for the distributed resource.
@ -111,6 +112,15 @@ class DistributedResource extends IResource {
this._link = link; this._link = link;
this._connection = connection; this._connection = connection;
this._instanceId = instanceId; 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() //void _ready()
@ -165,6 +175,38 @@ class DistributedResource extends IResource {
return true; 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) { void emitEventByIndex(int index, dynamic args) {
// neglect events when the object is not yet attached // neglect events when the object is not yet attached
if (!_attached) return; 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 '../Core/IDestructible.dart';
import 'Sockets/ISocket.dart'; import 'Sockets/ISocket.dart';
import 'Sockets/SocketState.dart'; import 'Sockets/SocketState.dart';
@ -29,178 +31,145 @@ import 'NetworkBuffer.dart';
import '../Data/DC.dart'; import '../Data/DC.dart';
import 'Sockets/IPEndPoint.dart'; import 'Sockets/IPEndPoint.dart';
class NetworkConnection extends IDestructible class NetworkConnection extends IDestructible with INetworkReceiver<ISocket> {
{ ISocket _sock;
ISocket _sock;
DateTime _lastAction; DateTime _lastAction;
//public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data); //public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data);
//public delegate void ConnectionClosedEvent(NetworkConnection sender); //public delegate void ConnectionClosedEvent(NetworkConnection sender);
//public delegate void ConnectionEstablishedEvent(NetworkConnection sender); //public delegate void ConnectionEstablishedEvent(NetworkConnection sender);
//public event ConnectionEstablishedEvent OnConnect; //public event ConnectionEstablishedEvent OnConnect;
//public event DataReceivedEvent OnDataReceived; //public event DataReceivedEvent OnDataReceived;
//public event ConnectionClosedEvent OnClose; //public event ConnectionClosedEvent OnClose;
//public event DestroyedEvent OnDestroy; //public event DestroyedEvent OnDestroy;
//object receivingLock = new object(); //object receivingLock = new object();
bool _processing = false; bool _processing = false;
// to be overridden void destroy() {
void connectionClosed() // if (connected)
{ close();
//emitArgs("close", [this]);
//OnDestroy?.Invoke(this);
}
NetworkConnection() {}
ISocket get socket => _sock;
void assign(ISocket socket) {
_lastAction = DateTime.now();
_sock = socket;
socket.receiver = this;
//socket.on("receive", socket_OnReceive);
//socket.on("close", socket_OnClose);
//socket.on("connect", socket_OnConnect);
}
ISocket unassign() {
if (_sock != null) {
// connected = false;
// _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
return null;
}
// to be overridden
void dataReceived(NetworkBuffer data) {
emitArgs("dataReceived", [data]);
}
void connected(){
}
void disconnected(){
}
void close() {
try {
if (_sock != null) _sock.close();
} catch (ex) {
//Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
} }
}
void destroy() DateTime get lastAction => _lastAction;
{
// if (connected) IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint;
close();
//emitArgs("close", [this]); IPEndPoint get localEndPoint => _sock?.localEndPoint;
//OnDestroy?.Invoke(this);
bool get isConnected => _sock.state == SocketState.Established;
void send(DC msg) {
try {
if (_sock != null) {
_lastAction = DateTime.now();
_sock.send(msg);
}
} catch (ex) {
//Console.WriteLine(ex.ToString());
} }
}
NetworkConnection() 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());
} }
}
ISocket get socket => _sock;
void assign(ISocket socket)
{
_lastAction = DateTime.now();
_sock = socket;
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)
{
// connected = false;
_sock.off("close", socket_OnClose);
_sock.off("connect", socket_OnConnect);
_sock.off("receive", socket_OnReceive);
var rt = _sock;
_sock = null;
return rt;
}
else
return null;
}
void dataReceived(NetworkBuffer data)
{
emitArgs("dataReceived", [data]);
}
void close()
{
try
{
if (_sock != null)
_sock.close();
}
catch(ex)
{
//Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
}
}
DateTime get lastAction => _lastAction;
IPEndPoint get remoteEndPoint => _sock?.remoteEndPoint;
IPEndPoint get localEndPoint => _sock?.localEndPoint;
bool get connected => _sock.state == SocketState.Established;
void send(DC msg)
{
try
{
if (_sock != null)
{
_lastAction = DateTime.now();
_sock.send(msg);
}
}
catch (ex)
{
//Console.WriteLine(ex.ToString());
}
}
void sendString(String data)
{
send(DC.stringToBytes(data));
}
} }

View File

@ -235,11 +235,14 @@ class IIPAuthPacket
localMethod = AuthenticationMethod.values[ ((data[offset] >> 2) & 0x3)]; localMethod = AuthenticationMethod.values[ ((data[offset] >> 2) & 0x3)];
var encrypt = ((data[offset++] & 0x2) == 0x2); var encrypt = ((data[offset++] & 0x2) == 0x2);
if (_notEnough(offset, ends, 1)) if (remoteMethod == AuthenticationMethod.None)
return -_dataLengthNeeded; {
if (localMethod == AuthenticationMethod.None)
{
if (remoteMethod == AuthenticationMethod.Credentials // do nothing
}
}
else if (remoteMethod == AuthenticationMethod.Credentials
|| remoteMethod == AuthenticationMethod.Token) || remoteMethod == AuthenticationMethod.Token)
{ {
if (localMethod == AuthenticationMethod.None) if (localMethod == AuthenticationMethod.None)

View File

@ -361,7 +361,8 @@ class IIPPacket
resourceId = data.getUint32(offset); resourceId = data.getUint32(offset);
offset += 4; offset += 4;
} }
else if (action == IIPPacketAction.QueryLink) else if (action == IIPPacketAction.QueryLink
|| action == IIPPacketAction.LinkTemplates)
{ {
if (_notEnough(offset, ends, 2)) if (_notEnough(offset, ends, 2))
return -_dataLengthNeeded; return -_dataLengthNeeded;
@ -420,7 +421,8 @@ class IIPPacket
offset += cl; offset += cl;
} }
else if (action == IIPPacketAction.GetProperty) else if (action == IIPPacketAction.Listen
|| action == IIPPacketAction.Unlisten)
{ {
if (_notEnough(offset, ends, 5)) if (_notEnough(offset, ends, 5))
return -_dataLengthNeeded; return -_dataLengthNeeded;
@ -429,22 +431,32 @@ class IIPPacket
offset += 4; offset += 4;
methodIndex = data[offset++]; methodIndex = data[offset++];
} }
else if (action == IIPPacketAction.GetPropertyIfModified) // else if (action == IIPPacketAction.GetProperty)
{ // {
if (_notEnough(offset, ends, 9)) // if (_notEnough(offset, ends, 5))
return -_dataLengthNeeded; // return -_dataLengthNeeded;
resourceId = data.getUint32(offset); // resourceId = data.getUint32(offset);
offset += 4; // 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) else if (action == IIPPacketAction.SetProperty)
{ {
if (_notEnough(offset, ends, 6)) if (_notEnough(offset, ends, 6))
@ -567,6 +579,7 @@ class IIPPacket
|| action == IIPPacketAction.ResourceChildren || action == IIPPacketAction.ResourceChildren
|| action == IIPPacketAction.ResourceParents || action == IIPPacketAction.ResourceParents
|| action == IIPPacketAction.ResourceHistory || action == IIPPacketAction.ResourceHistory
|| action == IIPPacketAction.LinkTemplates
// Attribute // Attribute
|| action == IIPPacketAction.GetAllAttributes || action == IIPPacketAction.GetAllAttributes
|| action == IIPPacketAction.GetAttributes) || action == IIPPacketAction.GetAttributes)
@ -584,9 +597,9 @@ class IIPPacket
offset += cl; offset += cl;
} }
else if (action == IIPPacketAction.InvokeFunctionArrayArguments else if (action == IIPPacketAction.InvokeFunctionArrayArguments
|| action == IIPPacketAction.InvokeFunctionNamedArguments || action == IIPPacketAction.InvokeFunctionNamedArguments)
|| action == IIPPacketAction.GetProperty //|| action == IIPPacketAction.GetProperty
|| action == IIPPacketAction.GetPropertyIfModified) //|| action == IIPPacketAction.GetPropertyIfModified)
{ {
if (_notEnough(offset, ends, 1)) if (_notEnough(offset, ends, 1))
return -_dataLengthNeeded; return -_dataLengthNeeded;
@ -617,7 +630,9 @@ class IIPPacket
offset += size; offset += size;
} }
} }
else if (action == IIPPacketAction.SetProperty) else if (action == IIPPacketAction.SetProperty
|| action == IIPPacketAction.Listen
|| action == IIPPacketAction.Unlisten)
{ {
// nothing to do // nothing to do
} }

View File

@ -1,36 +1,36 @@
class IIPPacketAction class IIPPacketAction {
{ // Request Manage
// Request Manage static const int AttachResource = 0x0;
static const int AttachResource = 0x0; static const int ReattachResource = 0x1;
static const int ReattachResource = 0x1; static const int DetachResource = 0x2;
static const int DetachResource = 0x2; static const int CreateResource = 0x3;
static const int CreateResource = 0x3; static const int DeleteResource = 0x4;
static const int DeleteResource = 0x4; static const int AddChild = 0x5;
static const int AddChild = 0x5; static const int RemoveChild = 0x6;
static const int RemoveChild = 0x6; static const int RenameResource = 0x7;
static const int RenameResource = 0x7;
// Request Inquire // Request Inquire
static const int TemplateFromClassName = 0x8; static const int TemplateFromClassName = 0x8;
static const int TemplateFromClassId = 0x9; static const int TemplateFromClassId = 0x9;
static const int TemplateFromResourceId = 0xA; static const int TemplateFromResourceId = 0xA;
static const int QueryLink = 0xB; static const int QueryLink = 0xB;
static const int ResourceHistory = 0xC; static const int ResourceHistory = 0xC;
static const int ResourceChildren = 0xD; static const int ResourceChildren = 0xD;
static const int ResourceParents = 0xE; static const int ResourceParents = 0xE;
static const int LinkTemplates = 0xF;
// Request Invoke // Request Invoke
static const int InvokeFunctionArrayArguments = 0x10; static const int InvokeFunctionArrayArguments = 0x10;
static const int GetProperty = 0x11; static const int InvokeFunctionNamedArguments = 0x11;
static const int GetPropertyIfModified = 0x12; static const int Listen = 0x12;
static const int SetProperty = 0x13; static const int Unlisten = 0x13;
static const int InvokeFunctionNamedArguments = 0x14; static const int SetProperty = 0x14;
// Request Attribute // Request Attribute
static const int GetAllAttributes = 0x18; static const int GetAllAttributes = 0x18;
static const int UpdateAllAttributes = 0x19; static const int UpdateAllAttributes = 0x19;
static const int ClearAllAttributes = 0x1A; static const int ClearAllAttributes = 0x1A;
static const int GetAttributes = 0x1B; static const int GetAttributes = 0x1B;
static const int UpdateAttributes = 0x1C; static const int UpdateAttributes = 0x1C;
static const int ClearAttributes = 0x1D; static const int ClearAttributes = 0x1D;
} }

View File

@ -23,25 +23,28 @@ SOFTWARE.
*/ */
import '../../Core/IDestructible.dart'; import '../../Core/IDestructible.dart';
import '../../Data/DC.dart'; import '../../Data/DC.dart';
import '../INetworkReceiver.dart';
import 'IPEndPoint.dart'; import 'IPEndPoint.dart';
import '../../Core/AsyncReply.dart'; import '../../Core/AsyncReply.dart';
import 'SocketState.dart'; import 'SocketState.dart';
abstract class ISocket extends IDestructible abstract class ISocket extends IDestructible {
{ SocketState get state; //{ get; }
SocketState get state ; //{ get; }
//event ISocketReceiveEvent OnReceive; //event ISocketReceiveEvent OnReceive;
//event ISocketConnectEvent OnConnect; //event ISocketConnectEvent OnConnect;
//event ISocketCloseEvent OnClose; //event ISocketCloseEvent OnClose;
//void send(DC message); //void send(DC message);
void send(DC message, [int offset, int size]);
void close();
AsyncReply<bool> connect(String hostname, int port);
bool begin();
AsyncReply<ISocket> accept(); INetworkReceiver<ISocket> receiver;
IPEndPoint remoteEndPoint;
IPEndPoint localEndPoint; void send(DC message, [int offset, int size]);
void close();
AsyncReply<bool> connect(String hostname, int port);
bool begin();
AsyncReply<ISocket> accept();
IPEndPoint remoteEndPoint;
IPEndPoint localEndPoint;
} }

View File

@ -32,24 +32,23 @@ import 'SocketState.dart';
import 'IPEndPoint.dart'; import 'IPEndPoint.dart';
import '../../Core/AsyncReply.dart'; import '../../Core/AsyncReply.dart';
class TCPSocket extends ISocket class TCPSocket extends ISocket {
{ Socket sock;
Socket sock; NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
//bool asyncSending; //bool asyncSending;
bool began = false; bool began = false;
SocketState _state = SocketState.Initial; SocketState _state = SocketState.Initial;
//public event ISocketReceiveEvent OnReceive; //public event ISocketReceiveEvent OnReceive;
//public event ISocketConnectEvent OnConnect; //public event ISocketConnectEvent OnConnect;
//public event ISocketCloseEvent OnClose; //public event ISocketCloseEvent OnClose;
//public event DestroyedEvent OnDestroy; //public event DestroyedEvent OnDestroy;
//SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs(); //SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();
/* /*
void connected(Task t) void connected(Task t)
{ {
state = SocketState.Established; state = SocketState.Established;
@ -58,143 +57,117 @@ class TCPSocket extends ISocket
} }
*/ */
IPEndPoint _localEP, _remoteEP; IPEndPoint _localEP, _remoteEP;
bool begin() bool begin() {
{ if (began) return false;
if (began)
return false;
began = true; began = true;
_localEP = IPEndPoint(sock.address.rawAddress, sock.port); _localEP = IPEndPoint(sock.address.rawAddress, sock.port);
_remoteEP = IPEndPoint(sock.remoteAddress.rawAddress, sock.remotePort); _remoteEP = IPEndPoint(sock.remoteAddress.rawAddress, sock.remotePort);
return true; return true;
} }
void dataHandler(List<int> data){ void dataHandler(List<int> data) {
//print(new String.fromCharCodes(data).trim()); //print(new String.fromCharCodes(data).trim());
try {
if (_state == SocketState.Closed || _state == SocketState.Terminated)
return;
try var dc = new DC.fromList(data);
{ receiveNetworkBuffer.write(dc, 0, dc.length);
if (_state == SocketState.Closed || _state == SocketState.Terminated) receiver.networkReceive(this, receiveNetworkBuffer);
return;
//emitArgs("receive", [receiveNetworkBuffer]);
var dc = new DC.fromList(data); } catch (ex) {
receiveNetworkBuffer.write(dc, 0, dc.length); if (_state != SocketState.Closed) // && !sock.connected)
emitArgs("receive", [receiveNetworkBuffer]); {
_state = SocketState.Terminated;
}
catch (ex)
{
if (_state != SocketState.Closed)// && !sock.connected)
{
_state = SocketState.Terminated;
close();
}
}
}
void errorHandler(error, StackTrace trace){
print(error);
}
void doneHandler(){
close();
sock.destroy();
}
AsyncReply<bool> connect(String hostname, int port)
{
var rt = new AsyncReply<bool>();
try
{
_state = SocketState.Connecting;
Socket.connect(hostname, port).then((s){
sock = s;
s.listen(dataHandler,
onError: errorHandler,
onDone: doneHandler,
cancelOnError: false);
_state = SocketState.Established;
emitArgs("connect", []);
begin();
rt.trigger(true);
}).catchError((ex){
close();
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)
{
sock = socket;
//if (socket.)
// _state = SocketState.Established;
}
TCPSocket()
{
// default constructor
}
void close()
{
if (state != SocketState.Closed && state != SocketState.Terminated)
_state = SocketState.Closed;
sock?.close();
emitArgs("close", []);
}
void send(DC message, [int offset, int size])
{
if (state == SocketState.Established)
sock.add(message.toList());
}
void destroy()
{
close(); close();
emitArgs("destroy", [this]); }
}
}
void errorHandler(error, StackTrace trace) {
print(error);
}
void doneHandler() {
close();
sock.destroy();
}
AsyncReply<bool> connect(String hostname, int port) {
var rt = new AsyncReply<bool>();
try {
_state = SocketState.Connecting;
Socket.connect(hostname, port).then((s) {
sock = s;
s.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
_state = SocketState.Established;
//emitArgs("connect", []);
receiver?.networkConnect(this);
begin();
rt.trigger(true);
}).catchError((ex) {
close();
rt.triggerError(AsyncException(ErrorType.Management,
ExceptionCode.HostNotReachable.index, ex.toString()));
});
} catch (ex) {
rt.triggerError(AsyncException(ErrorType.Management,
ExceptionCode.HostNotReachable.index, ex.toString()));
} }
AsyncReply<ISocket> accept() return rt;
{ }
IPEndPoint get localEndPoint => _localEP;
IPEndPoint get remoteEndPoint => _remoteEP;
var reply = new AsyncReply<ISocket>(); SocketState get state => _state;
return reply;
TCPSocket.fromSocket(Socket socket) {
sock = socket;
//if (socket.)
// _state = SocketState.Established;
}
TCPSocket() {
// default constructor
}
void close() {
if (state != SocketState.Closed && state != SocketState.Terminated)
_state = SocketState.Closed;
sock?.close();
receiver?.networkClose(this);
//emitArgs("close", []);
}
void send(DC message, [int offset, int size]) {
if (state == SocketState.Established) sock.add(message.toList());
}
void destroy() {
close();
emitArgs("destroy", [this]);
}
AsyncReply<ISocket> accept() {
var reply = new AsyncReply<ISocket>();
return reply;
/* /*
ServerSocket.bind(InternetAddress.ANY_IP_V4, 4567).then( ServerSocket.bind(InternetAddress.ANY_IP_V4, 4567).then(
@ -212,5 +185,5 @@ class TCPSocket extends ISocket
} }
*/ */
} }
} }

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 '../Core/IDestructible.dart';
import 'ResourceTrigger.dart'; import 'ResourceTrigger.dart';
import '../Core/AsyncReply.dart'; import '../Core/AsyncReply.dart';
import 'Instance.dart'; import 'Instance.dart';
abstract class IResource extends IDestructible abstract class IResource extends IDestructible {
{ AsyncReply<bool> trigger(ResourceTrigger trigger);
AsyncReply<bool> trigger(ResourceTrigger trigger); Instance instance;
/*
{
// do nothing
return new AsyncReply.ready(true);
}
destroy() invoke(String name, List arguments);
{ setProperty(String name, value);
// Destroyed getProperty(String name);
}
*/ TemplateDescriber get template;
Instance instance;
} }

View File

@ -11,7 +11,7 @@ import '../Core/IEventHandler.dart';
import '../Security/Permissions/Ruling.dart'; import '../Security/Permissions/Ruling.dart';
import '../Security/Permissions/IPermissionsManager.dart'; import '../Security/Permissions/IPermissionsManager.dart';
import '../Security/Permissions/ActionType.dart'; import '../Security/Permissions/ActionType.dart';
import './Template/ResourceTemplate.dart'; import 'Template/TypeTemplate.dart';
import './Template/PropertyTemplate.dart'; import './Template/PropertyTemplate.dart';
import './Template/FunctionTemplate.dart'; import './Template/FunctionTemplate.dart';
import './Template/EventTemplate.dart'; import './Template/EventTemplate.dart';
@ -30,7 +30,7 @@ class Instance extends IEventHandler
IStore _store; IStore _store;
AutoList<IResource, Instance> _parents; AutoList<IResource, Instance> _parents;
//bool inherit; //bool inherit;
ResourceTemplate _template; TypeTemplate _template;
AutoList<IPermissionsManager, Instance> _managers; AutoList<IPermissionsManager, Instance> _managers;
@ -547,7 +547,7 @@ class Instance extends IEventHandler
/// <summary> /// <summary>
/// Resource template describes the properties, functions and events of the resource. /// Resource template describes the properties, functions and events of the resource.
/// </summary> /// </summary>
ResourceTemplate get template => _template; TypeTemplate get template => _template;
/// <summary> /// <summary>
/// Check for permission. /// Check for permission.
@ -583,7 +583,7 @@ class Instance extends IEventHandler
/// <param name="name">Name of the instance.</param> /// <param name="name">Name of the instance.</param>
/// <param name="resource">Resource to manage.</param> /// <param name="resource">Resource to manage.</param>
/// <param name="store">Store responsible for the resource.</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; _store = store;
_resource = resource; _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 'MemberTemplate.dart';
import '../../Data/DC.dart'; import '../../Data/DC.dart';
import '../../Data/BinaryList.dart'; import '../../Data/BinaryList.dart';
import 'ResourceTemplate.dart'; import 'TypeTemplate.dart';
import 'MemberType.dart'; import 'MemberType.dart';
import 'TemplateDataType.dart';
class EventTemplate extends MemberTemplate class EventTemplate extends MemberTemplate {
{
String expansion; String expansion;
bool listenable;
TemplateDataType argumentType;
DC compose() {
var name = super.compose();
DC compose() if (expansion != null) {
{ var exp = DC.stringToBytes(expansion);
var name = super.compose(); return new BinaryList()
.addUint8(listenable ? 0x58 : 0x50)
if (expansion != null) .addUint8(name.length)
{ .addDC(name)
var exp = DC.stringToBytes(expansion); .addDC(argumentType.compose())
return new BinaryList() .addInt32(exp.length)
.addUint8(0x50) .addDC(exp)
.addUint8(name.length) .toDC();
.addDC(name) } else {
.addInt32(exp.length) return new BinaryList()
.addDC(exp) .addUint8(listenable ? 0x48 : 0x40)
.toDC(); .addUint8(name.length)
} .addDC(name)
else .addDC(argumentType.compose())
{ .toDC();
return new BinaryList() }
.addUint8(0x40)
.addUint8(name.length)
.addDC(name)
.toDC();
}
} }
EventTemplate(TypeTemplate template, int index, String name,
EventTemplate(ResourceTemplate template, int index, String name, String expansion) this.argumentType, this.expansion, this.listenable)
: super(template, MemberType.Property, index, name) : super(template, MemberType.Property, index, name) {}
{
this.expansion = expansion;
}
} }

View File

@ -1,42 +1,49 @@
import 'MemberTemplate.dart'; import 'MemberTemplate.dart';
import '../../Data/DC.dart'; import '../../Data/DC.dart';
import '../../Data/BinaryList.dart'; import '../../Data/BinaryList.dart';
import 'ResourceTemplate.dart'; import 'TypeTemplate.dart';
import 'MemberType.dart'; import 'MemberType.dart';
import 'ArgumentTemplate.dart';
import 'TemplateDataType.dart';
class FunctionTemplate extends MemberTemplate class FunctionTemplate extends MemberTemplate {
{ String expansion;
bool isVoid;
String expansion; TemplateDataType returnType;
bool isVoid; List<ArgumentTemplate> arguments;
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());
DC compose() if (expansion != null)
{ {
var name = super.compose(); var exp = DC.stringToBytes(expansion);
bl.addInt32(exp.length)
.addDC(exp);
bl.insertUint8(0, 0x10);
}
else
bl.insertUint8(0, 0x0);
if (expansion != null) return bl.toDC();
{ }
var exp = DC.stringToBytes(expansion);
return new BinaryList().addUint8((0x10 | (isVoid ? 0x8 : 0x0)))
.addUint8(name.length)
.addDC(name)
.addInt32(exp.length)
.addDC(exp)
.toDC();
}
else
return new BinaryList().addUint8((isVoid ? 0x8 : 0x0))
.addUint8(name.length)
.addDC(name)
.toDC();
}
FunctionTemplate(TypeTemplate template, int index, String name,
FunctionTemplate(ResourceTemplate template, int index, String name, bool isVoid, String expansion) this.arguments, this.returnType, String expansion)
:super(template, MemberType.Property, index, name) : super(template, MemberType.Property, index, name) {
{ this.isVoid = isVoid;
this.isVoid = isVoid; this.expansion = expansion;
this.expansion = expansion; }
}
} }

View File

@ -1,7 +1,7 @@
import 'MemberType.dart'; import 'MemberType.dart';
import '../../Data/DC.dart'; import '../../Data/DC.dart';
import './ResourceTemplate.dart'; import 'TypeTemplate.dart';
class MemberTemplate class MemberTemplate
{ {
@ -10,14 +10,14 @@ class MemberTemplate
String get name => _name; String get name => _name;
MemberType get type => _type; MemberType get type => _type;
ResourceTemplate _template; TypeTemplate _template;
String _name; String _name;
MemberType _type; MemberType _type;
int _index; 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._template = template;
this._type = type; this._type = type;

View File

@ -1,80 +1,76 @@
import 'TemplateDataType.dart';
import 'MemberTemplate.dart'; import 'MemberTemplate.dart';
import '../../Data/DC.dart'; import '../../Data/DC.dart';
import '../../Data/BinaryList.dart'; import '../../Data/BinaryList.dart';
import 'ResourceTemplate.dart'; import 'TypeTemplate.dart';
import 'MemberType.dart'; import 'MemberType.dart';
import 'PropertyPermission.dart';
import '../StorageMode.dart'; import '../StorageMode.dart';
class PropertyTemplate extends MemberTemplate class PropertyTemplate extends MemberTemplate {
{ TemplateDataType valueType;
int permission;
int permission; int storage;
String readExpansion;
int storage; String writeExpansion;
String readExpansion; DC compose() {
var name = super.compose();
var pv = ((permission) << 1) | (storage == StorageMode.Recordable ? 1 : 0);
String writeExpansion; 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) {
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) {
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
return new BinaryList()
.addUint8(0x20 | pv)
.addUint8(name.length)
.addDC(name)
.addDC(valueType.compose())
.toDC();
}
DC compose() PropertyTemplate(TypeTemplate template, int index, String name,
{ TemplateDataType valueType, String read, String write, int storage)
var name = super.compose(); : super(template, MemberType.Property, index, name) {
var pv = ((permission) << 1) | (storage == StorageMode.Recordable ? 1 : 0); //this.Recordable = recordable;
this.storage = storage;
if (writeExpansion != null && readExpansion != null) this.readExpansion = read;
{ this.writeExpansion = write;
var rexp = DC.stringToBytes(readExpansion); this.valueType = valueType;
var wexp = DC.stringToBytes(writeExpansion); }
return new BinaryList()
.addUint8(0x38 | pv)
.addUint8(name.length)
.addDC(name)
.addInt32(wexp.length)
.addDC(wexp)
.addInt32(rexp.length)
.addDC(rexp)
.toDC();
}
else if (writeExpansion != null)
{
var wexp = DC.stringToBytes(writeExpansion);
return new BinaryList()
.addUint8(0x30 | pv)
.addUint8(name.length)
.addDC(name)
.addInt32(wexp.length)
.addDC(wexp)
.toDC();
}
else if (readExpansion != null)
{
var rexp = DC.stringToBytes(readExpansion);
return new BinaryList()
.addUint8(0x28 | pv)
.addUint8(name.length)
.addDC(name)
.addInt32(rexp.length)
.addDC(rexp)
.toDC();
}
else
return new BinaryList()
.addUint8(0x20 | pv)
.addUint8(name.length)
.addDC(name)
.toDC();
}
PropertyTemplate(ResourceTemplate template, int index, String name, String read, String write, int storage)
:super(template, MemberType.Property, index, name)
{
//this.Recordable = recordable;
this.storage = storage;
this.readExpansion = read;
this.writeExpansion = write;
}
} }

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 '../Data/AutoList.dart';
import './Template/ResourceTemplate.dart'; import 'Template/TemplateType.dart';
import 'Template/TypeTemplate.dart';
import '../Data/Guid.dart'; import '../Data/Guid.dart';
import '../Data/KeyList.dart'; import '../Data/KeyList.dart';
import '../Data/Structure.dart'; import '../Data/Structure.dart';
@ -44,20 +45,30 @@ class Warehouse {
static Map<int, IResource> _resources = new Map<int, IResource>(); static Map<int, IResource> _resources = new Map<int, IResource>();
static int resourceCounter = 0; static int resourceCounter = 0;
static KeyList<Guid, ResourceTemplate> _templates =
new KeyList<Guid, ResourceTemplate>();
//public delegate void StoreConnectedEvent(IStore store, string name); static KeyList<TemplateType, KeyList<Guid, TypeTemplate>> _templates =
//public delegate void StoreDisconnectedEvent(IStore store); _initTemplates(); //
//public static event StoreConnectedEvent StoreConnected; static _initTemplates() {
///public static event StoreDisconnectedEvent StoreDisconnected; 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)> static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
protocols = _getSupportedProtocols(); protocols = _getSupportedProtocols();
static bool _warehouseIsOpen = false;
static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))'); static final _urlRegex = RegExp(r'^(?:([^\s|:]*):\/\/([^\/]*)\/?(.*))');
/// <summary> /// <summary>
@ -162,7 +173,7 @@ class Warehouse {
static List<IResource> qureyIn( static List<IResource> qureyIn(
List<String> path, int index, AutoList<IResource, Instance> resources) { List<String> path, int index, AutoList<IResource, Instance> resources) {
var rt = new List<IResource>(); List<IResource> rt = [];
if (index == path.length - 1) { if (index == path.length - 1) {
if (path[index] == "") if (path[index] == "")
@ -206,11 +217,11 @@ class Warehouse {
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <returns>Resource instance.</returns> /// <returns>Resource instance.</returns>
static AsyncReply<dynamic> get(String path, static AsyncReply<T> get<T extends IResource>(String path,
[attributes = null, [attributes = null,
IResource parent = null, IResource parent = null,
IPermissionsManager manager = null]) { IPermissionsManager manager = null]) {
var rt = AsyncReply<IResource>(); var rt = AsyncReply<T>();
// Should we create a new store ? // Should we create a new store ?
if (_urlRegex.hasMatch(path)) { if (_urlRegex.hasMatch(path)) {
@ -226,7 +237,7 @@ class Warehouse {
rt.trigger(r); rt.trigger(r);
}).error((e) => rt.triggerError(e)); }).error((e) => rt.triggerError(e));
else else
rt.trigger(store); rt.trigger(store as T);
}).error((e) { }).error((e) {
rt.triggerError(e); rt.triggerError(e);
//Warehouse.remove(store); //Warehouse.remove(store);
@ -333,14 +344,74 @@ class Warehouse {
/// <param name="name">Resource name.</param> /// <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="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> /// <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, [IStore store = null,
IResource parent = null, IResource parent = null,
ResourceTemplate customTemplate = null, TypeTemplate customTemplate = null,
int age = 0, int age = 0,
IPermissionsManager manager = null, IPermissionsManager manager = null,
attributes = 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( resource.instance = new Instance(
resourceCounter++, name, resource, store, customTemplate, age); resourceCounter++, name, resource, store, customTemplate, age);
@ -364,11 +435,17 @@ class Warehouse {
resource.trigger(ResourceTrigger.Initialize).then<dynamic>((value) { resource.trigger(ResourceTrigger.Initialize).then<dynamic>((value) {
if (resource is IStore) if (resource is IStore)
resource.trigger(ResourceTrigger.Open).then<dynamic>((value) { resource.trigger(ResourceTrigger.Open).then<dynamic>((value) {
rt.trigger(value); rt.trigger(resource);
}).error((ex) => rt.triggerError(ex)); }).error((ex) {
Warehouse.remove(resource);
rt.triggerError(ex);
});
else else
rt.trigger(value); rt.trigger(resource);
}).error((ex) => rt.triggerError(ex)); }).error((ex) {
Warehouse.remove(resource);
rt.triggerError(ex);
});
} }
}; };
@ -380,8 +457,11 @@ class Warehouse {
if (value) if (value)
initResource(); initResource();
else else
rt.trigger(false); rt.trigger(null);
}).error((ex) => rt.triggerError(ex)); }).error((ex) {
Warehouse.remove(resource);
rt.triggerError(ex);
});
} }
// return new name // return new name
@ -389,12 +469,18 @@ class Warehouse {
return rt; 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, [IStore store = null,
IResource parent = null, IResource parent = null,
IPermissionsManager manager = null, IPermissionsManager manager = null,
attributes = null, attributes = null,
properties = null]) { properties = null]) {
var resource = _factory[T].call();
if (properties != null) { if (properties != null) {
dynamic d = resource; dynamic d = resource;
@ -405,9 +491,9 @@ class Warehouse {
var rt = AsyncReply<T>(); var rt = AsyncReply<T>();
put(resource, name, store, parent, null, 0, manager, attributes) put<T>(name, resource, store, parent, null, 0, manager, attributes)
.then<bool>((value) { .then<IResource>((value) {
if (value) if (value != null)
rt.trigger(resource); rt.trigger(resource);
else else
rt.trigger(null); rt.trigger(null);
@ -427,49 +513,77 @@ class Warehouse {
/// Put a resource template in the templates warehouse. /// Put a resource template in the templates warehouse.
/// </summary> /// </summary>
/// <param name="template">Resource template.</param> /// <param name="template">Resource template.</param>
static void putTemplate(ResourceTemplate template) { static void putTemplate(TypeTemplate template) {
if (!_templates.containsKey(template.classId)) _templates[template.type][template.classId] = template;
_templates.add(template.classId, template);
} }
/// <summary> /// <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> /// </summary>
/// <param name="type">.Net type.</param> /// <param name="type">.Net type.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static ResourceTemplate getTemplateByType(Type type) { static TypeTemplate getTemplateByType(Type type) {
// loaded ? // loaded ?
for (var t in _templates.values) for (var tmps in _templates.values)
if (t.className == type.toString()) return t; for (var tmp in tmps.values)
if (tmp.className == type.toString()) return tmp;
var template = new ResourceTemplate.fromType(type); var template = new TypeTemplate.fromType(type, true);
_templates.add(template.classId, template);
return template; return template;
} }
/// <summary> /// <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> /// </summary>
/// <param name="classId">Class Id.</param> /// <param name="classId">Class Id.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static AsyncReply<ResourceTemplate> getTemplateByClassId(Guid classId) { static TypeTemplate getTemplateByClassId(Guid classId,
if (_templates.containsKey(classId)) [TemplateType templateType = TemplateType.Unspecified]) {
return new AsyncReply<ResourceTemplate>.ready(_templates[classId]); if (templateType == TemplateType.Unspecified) {
return null; // 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> /// <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> /// </summary>
/// <param name="className">Class name.</param> /// <param name="className">Class name.</param>
/// <returns>Resource template.</returns> /// <returns>Resource template.</returns>
static AsyncReply<ResourceTemplate> getTemplateByClassName(String className) { static TypeTemplate getTemplateByClassName(String className, [TemplateType templateType = TemplateType.Unspecified]) {
for (var t in _templates.values)
if (t.className == className)
return new AsyncReply<ResourceTemplate>.ready(t);
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) { static bool remove(IResource resource) {
@ -505,8 +619,15 @@ class Warehouse {
new KeyList<String, AsyncReply<IStore> Function(String, dynamic)>(); new KeyList<String, AsyncReply<IStore> Function(String, dynamic)>();
rt.add( rt.add(
"iip", "iip",
(String name, attributes) => Warehouse.New<DistributedConnection>( (String name, attributes) =>
DistributedConnection(), name, null, null, null, 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; return rt;
} }
} }

View File

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

View File

@ -7,16 +7,16 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "22.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.39.4" version: "1.7.1"
args: args:
dependency: transitive dependency: "direct main"
description: description:
name: args name: args
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
@ -28,77 +28,84 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.1" version: "2.7.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.12" version: "1.15.0"
convert: convert:
dependency: transitive dependency: transitive
description: description:
name: convert name: convert
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.1" version: "3.0.0"
coverage: coverage:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.13.9" version: "0.15.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "3.0.1"
csslib: dart_style:
dependency: transitive dependency: transitive
description: description:
name: csslib name: dart_style
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: glob:
dependency: transitive dependency: transitive
description: description:
name: glob name: glob
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "2.0.1"
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"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@ -126,28 +133,28 @@ packages:
name: js name: js
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.1+1" version: "0.6.3"
logging: logging:
dependency: transitive dependency: transitive
description: description:
name: logging name: logging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.11.4" version: "1.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.6" version: "0.12.10"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.3.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -155,27 +162,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.6+3" 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: node_preamble:
dependency: transitive dependency: transitive
description: description:
@ -189,35 +175,35 @@ packages:
name: package_config name: package_config
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.2" version: "2.0.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.6.4" version: "1.8.0"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.0" version: "1.11.1"
pool: pool:
dependency: transitive dependency: transitive
description: description:
name: pool name: pool
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.0" version: "1.5.0"
pub_semver: pub_semver:
dependency: transitive dependency: transitive
description: description:
name: pub_semver name: pub_semver
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.4.4" version: "2.0.0"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
@ -238,7 +224,7 @@ packages:
name: shelf_static name: shelf_static
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.8" version: "0.2.9+2"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
@ -246,83 +232,90 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.3" 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: source_map_stack_trace:
dependency: transitive dependency: transitive
description: description:
name: source_map_stack_trace name: source_map_stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
source_maps: source_maps:
dependency: transitive dependency: transitive
description: description:
name: source_maps name: source_maps
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.10.9" version: "0.10.10"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.9.3" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
test: test:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: test name: test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.2" version: "1.16.5"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.15" version: "0.2.19"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.3" version: "0.3.15"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.6" version: "1.3.0"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -336,27 +329,27 @@ packages:
name: watcher name: watcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.7+14" version: "1.0.0"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
webkit_inspection_protocol: webkit_inspection_protocol:
dependency: transitive dependency: transitive
description: description:
name: webkit_inspection_protocol name: webkit_inspection_protocol
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.0+1" version: "1.0.0"
yaml: yaml:
dependency: transitive dependency: transitive
description: description:
name: yaml name: yaml
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "3.1.0"
sdks: sdks:
dart: ">=2.7.0 <3.0.0" dart: ">=2.12.0 <3.0.0"

View File

@ -1,13 +1,17 @@
name: esiur name: esiur
description: Distributed Object Framework. description: Distributed Object Framework.
version: 1.2.6 version: 1.3.0
# author: Ahmed Zamil <ahmed@dijlh.com> # author: Ahmed Zamil <ahmed@esiur.com>
homepage: https://github.com/esiur/esiur-dart homepage: https://github.com/esiur/esiur-dart
environment: environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.1.0 <3.0.0"
dependencies:
source_gen: ^1.0.2
args: #
dev_dependencies: dev_dependencies:
test: ^1.14.2 test: ^1.14.2

View File

@ -1,12 +1,22 @@
import 'package:esiur/src/Proxy/TemplateGenerator.dart';
import "package:test/test.dart"; import "package:test/test.dart";
import 'package:esiur/esiur.dart'; import 'package:esiur/esiur.dart';
import 'dart:io'; import 'dart:io';
import '../lib/localhost/Esiur.Generated.dart';
import 'TestResource.dart';
main() async { main() async {
try { try {
var x = await Warehouse.get("iip://localhost:5070/sys/cp", testMe();
{"username": "admin", "password": "1234", "domain": "example.com"});
print(x); 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) { } catch (ex) {
print("Error occured"); print("Error occured");
print(ex); print(ex);