mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-06-27 14:53:11 +00:00
null-safety
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
class FactoryEntry {
|
||||
final Type type;
|
||||
final Function() instanceCreator;
|
||||
final Function() arrayCreator;
|
||||
final Function instanceCreator;
|
||||
final Function arrayCreator;
|
||||
|
||||
FactoryEntry(this.type, this.instanceCreator, this.arrayCreator);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import 'Instance.dart';
|
||||
abstract class IResource extends IDestructible {
|
||||
AsyncReply<bool> trigger(ResourceTrigger trigger);
|
||||
|
||||
Instance instance;
|
||||
Instance? instance;
|
||||
|
||||
invoke(String name, List arguments);
|
||||
setProperty(String name, value);
|
||||
|
@ -28,18 +28,20 @@ import '../Data/KeyList.dart';
|
||||
import './Template/PropertyTemplate.dart';
|
||||
import '../Data/PropertyValue.dart';
|
||||
|
||||
// old
|
||||
// old
|
||||
// abstract class IStore extends IResource
|
||||
// new
|
||||
abstract class IStore implements IResource
|
||||
{
|
||||
AsyncReply<IResource> get(String path);
|
||||
AsyncReply<IResource> retrieve(int iid);
|
||||
AsyncReply<bool> put(IResource resource);
|
||||
String link(IResource resource);
|
||||
bool record(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
|
||||
bool modify(IResource resource, String propertyName, dynamic value, int age, DateTime dateTime);
|
||||
bool remove(IResource resource);
|
||||
abstract class IStore implements IResource {
|
||||
AsyncReply<IResource?> get(String path);
|
||||
AsyncReply<IResource?> retrieve(int iid);
|
||||
AsyncReply<bool> put(IResource resource);
|
||||
String? link(IResource resource);
|
||||
bool record(IResource resource, String propertyName, dynamic value, int age,
|
||||
DateTime dateTime);
|
||||
bool modify(IResource resource, String propertyName, dynamic value, int age,
|
||||
DateTime dateTime);
|
||||
bool remove(IResource resource);
|
||||
|
||||
AsyncReply<KeyList<PropertyTemplate, List<PropertyValue>>> getRecord(IResource resource, DateTime fromDate, DateTime toDate);
|
||||
AsyncReply<KeyList<PropertyTemplate, List<PropertyValue>>?> getRecord(
|
||||
IResource resource, DateTime fromDate, DateTime toDate);
|
||||
}
|
||||
|
@ -21,123 +21,97 @@ import './Template/MemberTemplate.dart';
|
||||
import '../Data/PropertyValue.dart';
|
||||
import 'Warehouse.dart';
|
||||
|
||||
class Instance extends IEventHandler
|
||||
{
|
||||
String _name;
|
||||
class Instance extends IEventHandler {
|
||||
String _name;
|
||||
|
||||
AutoList<IResource, Instance> _children;
|
||||
IResource _resource;
|
||||
IStore _store;
|
||||
AutoList<IResource, Instance> _parents;
|
||||
//bool inherit;
|
||||
TypeTemplate _template;
|
||||
late AutoList<IResource, Instance> _children;
|
||||
IResource _resource;
|
||||
IStore? _store;
|
||||
late AutoList<IResource, Instance> _parents;
|
||||
//bool inherit;
|
||||
late TypeTemplate _template;
|
||||
|
||||
AutoList<IPermissionsManager, Instance> _managers;
|
||||
late AutoList<IPermissionsManager, Instance> _managers;
|
||||
|
||||
late KeyList<String, dynamic> _attributes;
|
||||
|
||||
KeyList<String, dynamic> _attributes;
|
||||
List<int> _ages = <int>[];
|
||||
List<DateTime> _modificationDates = <DateTime>[];
|
||||
int _instanceAge;
|
||||
DateTime? _instanceModificationDate;
|
||||
|
||||
List<int> _ages = new List<int>();
|
||||
List<DateTime> _modificationDates = new List<DateTime>();
|
||||
int _instanceAge;
|
||||
DateTime _instanceModificationDate;
|
||||
int _id;
|
||||
|
||||
int _id;
|
||||
/// <summary>
|
||||
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
|
||||
/// </summary>
|
||||
KeyList<String, dynamic> get attributes => _attributes;
|
||||
|
||||
@override
|
||||
String toString() => _name + " (" + (link ?? '') + ")";
|
||||
|
||||
/// <summary>
|
||||
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
|
||||
/// </summary>
|
||||
KeyList<String, dynamic> get attributes => _attributes;
|
||||
|
||||
@override
|
||||
String toString() => _name + " (" + link + ")";
|
||||
|
||||
|
||||
bool removeAttributes([List<String> attributes = null])
|
||||
{
|
||||
if (attributes == null)
|
||||
this._attributes.clear();
|
||||
else
|
||||
{
|
||||
for (var attr in attributes)
|
||||
this.attributes.remove(attr);
|
||||
}
|
||||
|
||||
return true;
|
||||
bool removeAttributes([List<String>? attributes = null]) {
|
||||
if (attributes == null)
|
||||
this._attributes.clear();
|
||||
else {
|
||||
for (var attr in attributes) this.attributes.remove(attr);
|
||||
}
|
||||
|
||||
Structure getAttributes([List<String> attributes = null])
|
||||
{
|
||||
var st = new Structure();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (attributes == null)
|
||||
{
|
||||
var clone = this.attributes.keys.toList();
|
||||
clone.add("managers");
|
||||
attributes = clone.toList();
|
||||
}
|
||||
Structure getAttributes([List<String>? attributes = null]) {
|
||||
var st = new Structure();
|
||||
|
||||
for(var attr in attributes)
|
||||
{
|
||||
if (attr == "name")
|
||||
st["name"] = _name;
|
||||
else if (attr == "managers")
|
||||
{
|
||||
var mngrs = new List<Structure>();
|
||||
|
||||
for (var i = 0; i < _managers.length; i++)
|
||||
{
|
||||
var mst = new Structure();
|
||||
mst["type"] = _managers[i].runtimeType;
|
||||
mst["settings"] = _managers[i].settings;
|
||||
|
||||
mngrs.add(mst);
|
||||
}
|
||||
|
||||
st["managers"] = mngrs;
|
||||
}
|
||||
else if (attr == "parents")
|
||||
{
|
||||
st["parents"] = _parents.toList();
|
||||
}
|
||||
else if (attr == "children")
|
||||
{
|
||||
st["children"] = _children.toList();
|
||||
}
|
||||
else if (attr == "childrenCount")
|
||||
{
|
||||
st["childrenCount"] = _children.count;
|
||||
}
|
||||
else if (attr == "type")
|
||||
{
|
||||
st["type"] = resource.runtimeType;
|
||||
}
|
||||
else
|
||||
st[attr] = _attributes[attr];
|
||||
}
|
||||
|
||||
return st;
|
||||
if (attributes == null) {
|
||||
var clone = this.attributes.keys.toList();
|
||||
clone.add("managers");
|
||||
attributes = clone.toList();
|
||||
}
|
||||
|
||||
bool setAttributes(Structure attributes, [bool clearAttributes = false])
|
||||
{
|
||||
try
|
||||
{
|
||||
for (var attr in attributes) {
|
||||
if (attr == "name")
|
||||
st["name"] = _name;
|
||||
else if (attr == "managers") {
|
||||
var mngrs = <Structure>[];
|
||||
|
||||
if (clearAttributes)
|
||||
_attributes.clear();
|
||||
for (var i = 0; i < _managers.length; i++) {
|
||||
var mst = new Structure();
|
||||
mst["type"] = _managers[i].runtimeType;
|
||||
mst["settings"] = _managers[i].settings;
|
||||
|
||||
for (var attrKey in attributes.keys)
|
||||
if (attrKey == "name")
|
||||
_name = attributes[attrKey];
|
||||
else if (attrKey == "managers")
|
||||
{
|
||||
_managers.clear();
|
||||
mngrs.add(mst);
|
||||
}
|
||||
|
||||
var mngrs = attributes[attrKey] as List;
|
||||
// this is not implemented now, Flutter doesn't support mirrors, needs a workaround @ Warehouse.registerManager
|
||||
/*
|
||||
st["managers"] = mngrs;
|
||||
} else if (attr == "parents") {
|
||||
st["parents"] = _parents.toList();
|
||||
} else if (attr == "children") {
|
||||
st["children"] = _children.toList();
|
||||
} else if (attr == "childrenCount") {
|
||||
st["childrenCount"] = _children.count;
|
||||
} else if (attr == "type") {
|
||||
st["type"] = resource.runtimeType;
|
||||
} else
|
||||
st[attr] = _attributes[attr];
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
bool setAttributes(Structure attributes, [bool clearAttributes = false]) {
|
||||
try {
|
||||
if (clearAttributes) _attributes.clear();
|
||||
|
||||
for (var attrKey in attributes.keys)
|
||||
if (attrKey == "name")
|
||||
_name = attributes[attrKey] as String;
|
||||
else if (attrKey == "managers") {
|
||||
_managers.clear();
|
||||
|
||||
var mngrs = attributes[attrKey] as List;
|
||||
// this is not implemented now, Flutter doesn't support mirrors, needs a workaround @ Warehouse.registerManager
|
||||
/*
|
||||
for (var mngr in mngrs)
|
||||
{
|
||||
var m = mngr as Structure;
|
||||
@ -153,22 +127,17 @@ class Instance extends IEventHandler
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
_attributes[attrKey] = attributes[attrKey];
|
||||
}
|
||||
|
||||
} else {
|
||||
_attributes[attrKey] = attributes[attrKey];
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
public Structure GetAttributes()
|
||||
{
|
||||
var st = new Structure();
|
||||
@ -192,73 +161,67 @@ class Instance extends IEventHandler
|
||||
return st;
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// Get the age of a given property index.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <returns>Age.</returns>
|
||||
int getAge(int index)
|
||||
{
|
||||
if (index < _ages.length)
|
||||
return _ages[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the age of a given property index.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <returns>Age.</returns>
|
||||
int getAge(int index) {
|
||||
if (index < _ages.length)
|
||||
return _ages[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the age of a property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Age.</param>
|
||||
void setAge(int index, int value)
|
||||
{
|
||||
if (index < _ages.length)
|
||||
{
|
||||
_ages[index] = value;
|
||||
if (value > _instanceAge)
|
||||
_instanceAge = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the age of a property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Age.</param>
|
||||
void setAge(int index, int value) {
|
||||
if (index < _ages.length) {
|
||||
_ages[index] = value;
|
||||
if (value > _instanceAge) _instanceAge = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the modification date of a property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Modification date.</param>
|
||||
void setModificationDate(int index, DateTime value)
|
||||
{
|
||||
if (index < _modificationDates.length)
|
||||
{
|
||||
_modificationDates[index] = value;
|
||||
if (_instanceModificationDate == null || value.millisecondsSinceEpoch > _instanceModificationDate.millisecondsSinceEpoch)
|
||||
_instanceModificationDate = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the modification date of a property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Modification date.</param>
|
||||
void setModificationDate(int index, DateTime value) {
|
||||
if (index < _modificationDates.length) {
|
||||
_modificationDates[index] = value;
|
||||
if (_instanceModificationDate == null ||
|
||||
value.millisecondsSinceEpoch >
|
||||
(_instanceModificationDate as DateTime).millisecondsSinceEpoch)
|
||||
_instanceModificationDate = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get modification date of a specific property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index</param>
|
||||
/// <returns>Modification date.</returns>
|
||||
DateTime getModificationDate(int index)
|
||||
{
|
||||
if (index < _modificationDates.length)
|
||||
return _modificationDates[index];
|
||||
else
|
||||
return new DateTime(0);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get modification date of a specific property.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index</param>
|
||||
/// <returns>Modification date.</returns>
|
||||
DateTime getModificationDate(int index) {
|
||||
if (index < _modificationDates.length)
|
||||
return _modificationDates[index];
|
||||
else
|
||||
return new DateTime(0);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Load property value (used by stores)
|
||||
/// </summary>
|
||||
/// <param name="name">Property name</param>
|
||||
/// <param name="age">Property age</param>
|
||||
/// <param name="value">Property value</param>
|
||||
/// <returns></returns>
|
||||
bool loadProperty(String name, int age, DateTime modificationDate, dynamic value)
|
||||
{
|
||||
/*
|
||||
/// <summary>
|
||||
/// Load property value (used by stores)
|
||||
/// </summary>
|
||||
/// <param name="name">Property name</param>
|
||||
/// <param name="age">Property age</param>
|
||||
/// <param name="value">Property value</param>
|
||||
/// <returns></returns>
|
||||
bool loadProperty(
|
||||
String name, int age, DateTime modificationDate, dynamic value) {
|
||||
/*
|
||||
var pt = _template.getPropertyTemplate(name);
|
||||
|
||||
if (pt == null)
|
||||
@ -281,64 +244,58 @@ class Instance extends IEventHandler
|
||||
setModificationDate(pt.index, modificationDate);
|
||||
|
||||
*/
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Age of the instance, incremented by 1 in every modification.
|
||||
/// </summary>
|
||||
int get age => _instanceAge;
|
||||
// this must be internal
|
||||
set age(value) => _instanceAge = value;
|
||||
|
||||
/// <summary>
|
||||
/// Last modification date.
|
||||
/// </summary>
|
||||
DateTime? get modificationDate => _instanceModificationDate;
|
||||
|
||||
/// <summary>
|
||||
/// Instance Id.
|
||||
/// </summary>
|
||||
int get id => _id;
|
||||
|
||||
/// <summary>
|
||||
/// Import properties from bytes array.
|
||||
/// </summary>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
bool deserialize(List<PropertyValue> properties) {
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
var pt = _template.getPropertyTemplateByIndex(i);
|
||||
if (pt != null) {
|
||||
var pv = properties[i];
|
||||
loadProperty(pt.name, pv.age, pv.date, pv.value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Age of the instance, incremented by 1 in every modification.
|
||||
/// </summary>
|
||||
int get age => _instanceAge;
|
||||
// this must be internal
|
||||
set age (value) => _instanceAge = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Last modification date.
|
||||
/// </summary>
|
||||
DateTime get modificationDate => _instanceModificationDate;
|
||||
|
||||
/// <summary>
|
||||
/// Instance Id.
|
||||
/// </summary>
|
||||
int get id => _id;
|
||||
|
||||
/// <summary>
|
||||
/// Import properties from bytes array.
|
||||
/// </summary>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
bool deserialize(List<PropertyValue> properties)
|
||||
{
|
||||
for (var i = 0; i < properties.length; i++)
|
||||
{
|
||||
var pt = _template.getPropertyTemplateByIndex(i);
|
||||
if (pt != null)
|
||||
{
|
||||
var pv = properties[i];
|
||||
loadProperty(pt.name, pv.age, pv.date, pv.value);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Export all properties with ResourceProperty attributed as bytes array.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<PropertyValue> serialize() {
|
||||
List<PropertyValue> props = <PropertyValue>[];
|
||||
|
||||
return true;
|
||||
for (var pt in _template.properties) {
|
||||
// var rt = pt.info.getValue(resource, null);
|
||||
// props.add(new PropertyValue(rt, _ages[pt.index], _modificationDates[pt.index]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export all properties with ResourceProperty attributed as bytes array.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<PropertyValue> serialize()
|
||||
{
|
||||
List<PropertyValue> props = new List<PropertyValue>();
|
||||
|
||||
for (var pt in _template.properties)
|
||||
{
|
||||
// var rt = pt.info.getValue(resource, null);
|
||||
// props.add(new PropertyValue(rt, _ages[pt.index], _modificationDates[pt.index]));
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
/*
|
||||
return props;
|
||||
}
|
||||
/*
|
||||
public bool Deserialize(byte[] data, uint offset, uint length)
|
||||
{
|
||||
|
||||
@ -347,7 +304,7 @@ class Instance extends IEventHandler
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
/*
|
||||
public byte[] Serialize(bool includeLength = false, DistributedConnection sender = null)
|
||||
{
|
||||
|
||||
@ -405,70 +362,62 @@ class Instance extends IEventHandler
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// If True, the instance can be stored to disk.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool isStorable()
|
||||
{
|
||||
return false;
|
||||
/// <summary>
|
||||
/// If True, the instance can be stored to disk.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool isStorable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void emitModification(PropertyTemplate pt, dynamic value) {
|
||||
_instanceAge++;
|
||||
var now = DateTime.now().toUtc();
|
||||
|
||||
_ages[pt.index] = _instanceAge;
|
||||
_modificationDates[pt.index] = now;
|
||||
|
||||
if (pt.storage == StorageMode.NonVolatile) {
|
||||
_store?.modify(_resource, pt.name, value, _ages[pt.index], now);
|
||||
} else if (pt.storage == StorageMode.Recordable) {
|
||||
_store?.record(_resource, pt.name, value, _ages[pt.index], now);
|
||||
}
|
||||
|
||||
emitArgs("resourceModified", [_resource, pt.name, value]);
|
||||
//_resource.emitArgs("modified", [pt.name, value]);
|
||||
_resource.emitArgs(":${pt.name}", [value]);
|
||||
}
|
||||
|
||||
void emitModification(PropertyTemplate pt, dynamic value)
|
||||
{
|
||||
_instanceAge++;
|
||||
var now = DateTime.now().toUtc();
|
||||
|
||||
_ages[pt.index] = _instanceAge;
|
||||
_modificationDates[pt.index] = now;
|
||||
|
||||
if (pt.storage == StorageMode.NonVolatile)
|
||||
{
|
||||
_store.modify(_resource, pt.name, value, _ages[pt.index], now);
|
||||
}
|
||||
else if (pt.storage == StorageMode.Recordable)
|
||||
{
|
||||
_store.record(_resource, pt.name, value, _ages[pt.index], now);
|
||||
}
|
||||
|
||||
emitArgs("resourceModified", [_resource, pt.name, value]);
|
||||
//_resource.emitArgs("modified", [pt.name, value]);
|
||||
_resource.emitArgs(":${pt.name}", [value]);
|
||||
/// <summary>
|
||||
/// Notify listeners that a property was modified.
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="oldValue"></param>
|
||||
modified(String propertyName) {
|
||||
var valueObject = new ValueObject();
|
||||
if (getPropertyValue(propertyName, valueObject)) {
|
||||
var pt = _template.getPropertyTemplateByName(propertyName);
|
||||
if (pt != null) emitModification(pt, valueObject.value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notify listeners that a property was modified.
|
||||
/// </summary>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="oldValue"></param>
|
||||
modified(String propertyName)
|
||||
{
|
||||
var valueObject = new ValueObject();
|
||||
if (getPropertyValue(propertyName, valueObject))
|
||||
{
|
||||
var pt = _template.getPropertyTemplateByName(propertyName);
|
||||
emitModification(pt, valueObject.value);
|
||||
}
|
||||
}
|
||||
emitResourceEvent(
|
||||
issuer, List<Session>? receivers, String name, dynamic args) {
|
||||
emitArgs(
|
||||
"resourceEventOccurred", [_resource, issuer, receivers, name, args]);
|
||||
}
|
||||
|
||||
emitResourceEvent(issuer, List<Session> receivers, String name, dynamic args)
|
||||
{
|
||||
emitArgs("resourceEventOccurred", [_resource, issuer, receivers, name, args]);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the value of a given property by name.
|
||||
/// </summary>
|
||||
/// <param name="name">Property name</param>
|
||||
/// <param name="value">Output value</param>
|
||||
/// <returns>True, if the resource has the property.</returns>
|
||||
bool getPropertyValue(String name, ValueObject valueObject) {
|
||||
var pt = _template.getPropertyTemplateByName(name);
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a given property by name.
|
||||
/// </summary>
|
||||
/// <param name="name">Property name</param>
|
||||
/// <param name="value">Output value</param>
|
||||
/// <returns>True, if the resource has the property.</returns>
|
||||
bool getPropertyValue(String name, ValueObject valueObject)
|
||||
{
|
||||
var pt = _template.getPropertyTemplateByName(name);
|
||||
|
||||
/*
|
||||
/*
|
||||
if (pt != null && pt.info != null)
|
||||
{
|
||||
valueObject.value = pt.info.getValue(_resource, null);
|
||||
@ -476,146 +425,130 @@ class Instance extends IEventHandler
|
||||
|
||||
}*/
|
||||
|
||||
valueObject.value = null;
|
||||
return false;
|
||||
}
|
||||
valueObject.value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
public bool Inherit
|
||||
{
|
||||
get { return inherit; }
|
||||
}*/
|
||||
|
||||
/// <summary>
|
||||
/// List of parents.
|
||||
/// </summary>
|
||||
AutoList<IResource, Instance> get parents => _parents;
|
||||
|
||||
/// <summary>
|
||||
/// List of parents.
|
||||
/// </summary>
|
||||
AutoList<IResource, Instance> get parents => _parents;
|
||||
|
||||
/// <summary>
|
||||
/// Store responsible for creating and keeping the resource.
|
||||
/// </summary>
|
||||
IStore get store => _store;
|
||||
/// <summary>
|
||||
/// Store responsible for creating and keeping the resource.
|
||||
/// </summary>
|
||||
IStore? get store => _store;
|
||||
|
||||
/// <summary>
|
||||
/// List of children.
|
||||
/// </summary>
|
||||
AutoList<IResource, Instance> get children => _children;
|
||||
|
||||
/// <summary>
|
||||
/// The unique and permanent link to the resource.
|
||||
/// </summary>
|
||||
String get link
|
||||
{
|
||||
if (_store != null)
|
||||
return _store.link(_resource);
|
||||
else
|
||||
{
|
||||
var l = new List<String>();
|
||||
/// <summary>
|
||||
/// List of children.
|
||||
/// </summary>
|
||||
AutoList<IResource, Instance> get children => _children;
|
||||
|
||||
var p = _resource;
|
||||
/// <summary>
|
||||
/// The unique and permanent link to the resource.
|
||||
/// </summary>
|
||||
String? get link {
|
||||
if (_store != null)
|
||||
return _store?.link(_resource);
|
||||
else {
|
||||
var l = <String>[];
|
||||
|
||||
while (true)
|
||||
{
|
||||
l.insert(0, p.instance.name);
|
||||
var p = _resource;
|
||||
|
||||
if (p.instance.parents.count == 0)
|
||||
break;
|
||||
while (true) {
|
||||
if (p.instance != null) break;
|
||||
var pi = p.instance as Instance;
|
||||
|
||||
p = p.instance.parents.first();
|
||||
}
|
||||
l.insert(0, pi.name);
|
||||
|
||||
return l.join("/");
|
||||
}
|
||||
|
||||
if (pi.parents.count == 0) break;
|
||||
|
||||
p = pi.parents.first;
|
||||
}
|
||||
|
||||
return l.join("/");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instance name.
|
||||
/// </summary>
|
||||
String get name => _name;
|
||||
set name(value) => name = value;
|
||||
|
||||
/// <summary>
|
||||
/// Resource managed by this instance.
|
||||
/// </summary>
|
||||
IResource get resource => _resource;
|
||||
|
||||
/// <summary>
|
||||
/// Resource template describes the properties, functions and events of the resource.
|
||||
/// </summary>
|
||||
TypeTemplate get template => _template;
|
||||
|
||||
/// <summary>
|
||||
/// Check for permission.
|
||||
/// </summary>
|
||||
/// <param name="session">Caller sessions.</param>
|
||||
/// <param name="action">Action type</param>
|
||||
/// <param name="member">Function, property or event to check for permission.</param>
|
||||
/// <param name="inquirer">Permission inquirer.</param>
|
||||
/// <returns>Ruling.</returns>
|
||||
Ruling applicable(Session session, ActionType action, MemberTemplate? member,
|
||||
[dynamic inquirer = null]) {
|
||||
for (var i = 0; i < _managers.length; i++) {
|
||||
var r = _managers[i]
|
||||
.applicable(this.resource, session, action, member, inquirer);
|
||||
if (r != Ruling.DontCare) return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instance name.
|
||||
/// </summary>
|
||||
String get name => _name;
|
||||
set name(value) => name = value;
|
||||
|
||||
return Ruling.DontCare;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource managed by this instance.
|
||||
/// </summary>
|
||||
IResource get resource => _resource;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resource template describes the properties, functions and events of the resource.
|
||||
/// </summary>
|
||||
TypeTemplate get template => _template;
|
||||
/// <summary>
|
||||
/// Execution managers.
|
||||
/// </summary>
|
||||
AutoList<IPermissionsManager, Instance> get managers => _managers;
|
||||
|
||||
/// <summary>
|
||||
/// Check for permission.
|
||||
/// </summary>
|
||||
/// <param name="session">Caller sessions.</param>
|
||||
/// <param name="action">Action type</param>
|
||||
/// <param name="member">Function, property or event to check for permission.</param>
|
||||
/// <param name="inquirer">Permission inquirer.</param>
|
||||
/// <returns>Ruling.</returns>
|
||||
Ruling applicable(Session session, ActionType action, MemberTemplate member, [dynamic inquirer = null])
|
||||
{
|
||||
|
||||
for(var i = 0; i < _managers.length; i++)
|
||||
{
|
||||
var r = _managers[i].applicable(this.resource, session, action, member, inquirer);
|
||||
if (r != Ruling.DontCare)
|
||||
return r;
|
||||
}
|
||||
/// <summary>
|
||||
/// Create new instance.
|
||||
/// </summary>
|
||||
/// <param name="id">Instance Id.</param>
|
||||
/// <param name="name">Name of the instance.</param>
|
||||
/// <param name="resource">Resource to manage.</param>
|
||||
/// <param name="store">Store responsible for the resource.</param>
|
||||
Instance(this._id, this._name, this._resource, this._store,
|
||||
[TypeTemplate? customTemplate = null, this._instanceAge = 0]) {
|
||||
_attributes = new KeyList<String, dynamic>(this);
|
||||
_children = new AutoList<IResource, Instance>(this);
|
||||
_parents = new AutoList<IResource, Instance>(this);
|
||||
_managers = new AutoList<IPermissionsManager, Instance>(this);
|
||||
|
||||
return Ruling.DontCare;
|
||||
_children.on("add", children_OnAdd);
|
||||
_children.on("remove", children_OnRemoved);
|
||||
_parents.on("add", parents_OnAdd);
|
||||
_parents.on("remove", parents_OnRemoved);
|
||||
|
||||
resource.on("destroy", resource_OnDestroy);
|
||||
|
||||
if (customTemplate != null)
|
||||
_template = customTemplate;
|
||||
else
|
||||
_template = Warehouse.getTemplateByType(resource.runtimeType);
|
||||
|
||||
// set ages
|
||||
for (int i = 0; i < _template.properties.length; i++) {
|
||||
_ages.add(0);
|
||||
_modificationDates.add(new DateTime(0)); //DateTime.MinValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execution managers.
|
||||
/// </summary>
|
||||
AutoList<IPermissionsManager, Instance> get managers => _managers;
|
||||
|
||||
/// <summary>
|
||||
/// Create new instance.
|
||||
/// </summary>
|
||||
/// <param name="id">Instance Id.</param>
|
||||
/// <param name="name">Name of the instance.</param>
|
||||
/// <param name="resource">Resource to manage.</param>
|
||||
/// <param name="store">Store responsible for the resource.</param>
|
||||
Instance(int id, String name, IResource resource, IStore store, [TypeTemplate customTemplate = null, int age = 0])
|
||||
{
|
||||
_store = store;
|
||||
_resource = resource;
|
||||
_id = id;
|
||||
_name = name;
|
||||
_instanceAge = age;
|
||||
|
||||
_attributes = new KeyList<String, dynamic>(this);
|
||||
_children = new AutoList<IResource, Instance>(this);
|
||||
_parents = new AutoList<IResource, Instance>(this);
|
||||
_managers = new AutoList<IPermissionsManager, Instance>(this);
|
||||
|
||||
_children.on("add", children_OnAdd);
|
||||
_children.on("remove", children_OnRemoved);
|
||||
_parents.on("add", parents_OnAdd);
|
||||
_parents.on("remove", parents_OnRemoved);
|
||||
|
||||
resource.on("destroy", resource_OnDestroy);
|
||||
|
||||
if (customTemplate != null)
|
||||
_template = customTemplate;
|
||||
else
|
||||
_template = Warehouse.getTemplateByType(resource.runtimeType);
|
||||
|
||||
// set ages
|
||||
for (int i = 0; i < _template.properties.length; i++)
|
||||
{
|
||||
_ages.add(0);
|
||||
_modificationDates.add(new DateTime(0));//DateTime.MinValue);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
// connect events
|
||||
Type t = resource.runtimeType;
|
||||
|
||||
@ -650,33 +583,33 @@ class Instance extends IEventHandler
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void children_OnRemoved(Instance parent, IResource value)
|
||||
{
|
||||
value.instance.parents.remove(_resource);
|
||||
}
|
||||
void children_OnRemoved(Instance parent, IResource value) {
|
||||
value.instance?.parents.remove(_resource);
|
||||
}
|
||||
|
||||
void children_OnAdd(Instance parent, IResource value)
|
||||
{
|
||||
if (!value.instance.parents.contains(_resource))
|
||||
value.instance.parents.add(_resource);
|
||||
void children_OnAdd(Instance parent, IResource value) {
|
||||
if (value.instance != null) {
|
||||
var ins = value.instance as Instance;
|
||||
if (ins.parents.contains(_resource))
|
||||
value.instance?.parents.add(_resource);
|
||||
}
|
||||
}
|
||||
|
||||
void parents_OnRemoved(Instance parent, IResource value)
|
||||
{
|
||||
value.instance.children.remove(_resource);
|
||||
void parents_OnRemoved(Instance parent, IResource value) {
|
||||
value.instance?.children.remove(_resource);
|
||||
}
|
||||
|
||||
void parents_OnAdd(Instance parent, IResource value) {
|
||||
if (value.instance != null) {
|
||||
var ins = value.instance as Instance;
|
||||
if (!ins.children.contains(_resource))
|
||||
value.instance?.children.add(_resource);
|
||||
}
|
||||
}
|
||||
|
||||
void parents_OnAdd(Instance parent, IResource value)
|
||||
{
|
||||
if (!value.instance.children.contains(_resource))
|
||||
value.instance.children.add(_resource);
|
||||
}
|
||||
|
||||
|
||||
void resource_OnDestroy(sender)
|
||||
{
|
||||
emitArgs("resourceDestroyed", [sender]);
|
||||
}
|
||||
void resource_OnDestroy(sender) {
|
||||
emitArgs("resourceDestroyed", [sender]);
|
||||
}
|
||||
}
|
||||
|
@ -3,32 +3,30 @@ import '../../Data/BinaryList.dart';
|
||||
import "../../Data/ParseResult.dart";
|
||||
import './TemplateDataType.dart';
|
||||
|
||||
class ArgumentTemplate
|
||||
{
|
||||
String name;
|
||||
class ArgumentTemplate {
|
||||
String name;
|
||||
|
||||
TemplateDataType type;
|
||||
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);
|
||||
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();
|
||||
}
|
||||
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 (BinaryList()
|
||||
..addUint8(name.length)
|
||||
..addDC(name)
|
||||
..addDC(type.compose()))
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import 'MemberType.dart';
|
||||
import 'TemplateDataType.dart';
|
||||
|
||||
class EventTemplate extends MemberTemplate {
|
||||
String expansion;
|
||||
String? expansion;
|
||||
bool listenable;
|
||||
TemplateDataType argumentType;
|
||||
|
||||
@ -14,21 +14,21 @@ class EventTemplate extends MemberTemplate {
|
||||
var name = super.compose();
|
||||
|
||||
if (expansion != null) {
|
||||
var exp = DC.stringToBytes(expansion);
|
||||
return new BinaryList()
|
||||
.addUint8(listenable ? 0x58 : 0x50)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(argumentType.compose())
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp)
|
||||
var exp = DC.stringToBytes(expansion as String);
|
||||
return (BinaryList()
|
||||
..addUint8(listenable ? 0x58 : 0x50)
|
||||
..addUint8(name.length)
|
||||
..addDC(name)
|
||||
..addDC(argumentType.compose())
|
||||
..addInt32(exp.length)
|
||||
..addDC(exp))
|
||||
.toDC();
|
||||
} else {
|
||||
return new BinaryList()
|
||||
.addUint8(listenable ? 0x48 : 0x40)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(argumentType.compose())
|
||||
return (BinaryList()
|
||||
..addUint8(listenable ? 0x48 : 0x40)
|
||||
..addUint8(name.length)
|
||||
..addDC(name)
|
||||
..addDC(argumentType.compose()))
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import 'ArgumentTemplate.dart';
|
||||
import 'TemplateDataType.dart';
|
||||
|
||||
class FunctionTemplate extends MemberTemplate {
|
||||
String expansion;
|
||||
bool isVoid;
|
||||
String? expansion;
|
||||
// bool isVoid;
|
||||
|
||||
TemplateDataType returnType;
|
||||
List<ArgumentTemplate> arguments;
|
||||
@ -18,10 +18,10 @@ class FunctionTemplate extends MemberTemplate {
|
||||
var name = super.compose();
|
||||
|
||||
var bl = new BinaryList()
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(returnType.compose())
|
||||
.addUint8(arguments.length);
|
||||
..addUint8(name.length)
|
||||
..addDC(name)
|
||||
..addDC(returnType.compose())
|
||||
..addUint8(arguments.length);
|
||||
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
bl.addDC(arguments[i].compose());
|
||||
@ -29,9 +29,9 @@ class FunctionTemplate extends MemberTemplate {
|
||||
|
||||
if (expansion != null)
|
||||
{
|
||||
var exp = DC.stringToBytes(expansion);
|
||||
bl.addInt32(exp.length)
|
||||
.addDC(exp);
|
||||
var exp = DC.stringToBytes(expansion as String);
|
||||
bl..addInt32(exp.length)
|
||||
..addDC(exp);
|
||||
bl.insertUint8(0, 0x10);
|
||||
}
|
||||
else
|
||||
@ -41,9 +41,9 @@ class FunctionTemplate extends MemberTemplate {
|
||||
}
|
||||
|
||||
FunctionTemplate(TypeTemplate template, int index, String name,
|
||||
this.arguments, this.returnType, String expansion)
|
||||
this.arguments, this.returnType, this.expansion)
|
||||
: super(template, MemberType.Property, index, name) {
|
||||
this.isVoid = isVoid;
|
||||
this.expansion = expansion;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,8 @@ class MemberTemplate
|
||||
|
||||
TypeTemplate get template => _template;
|
||||
|
||||
MemberTemplate(TypeTemplate template, MemberType type, int index, String name)
|
||||
MemberTemplate(this._template, this._type, this._index, this._name)
|
||||
{
|
||||
this._template = template;
|
||||
this._type = type;
|
||||
this._index = index;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
String get fullname => _template.className + "." + _name;
|
||||
|
@ -14,63 +14,59 @@ class PropertyTemplate extends MemberTemplate {
|
||||
|
||||
int storage;
|
||||
|
||||
String readExpansion;
|
||||
String? readExpansion;
|
||||
|
||||
String writeExpansion;
|
||||
String? writeExpansion;
|
||||
|
||||
DC compose() {
|
||||
var name = super.compose();
|
||||
var pv = ((permission) << 1) | (storage == StorageMode.Recordable ? 1 : 0);
|
||||
|
||||
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)
|
||||
var rexp = DC.stringToBytes(readExpansion as String);
|
||||
var wexp = DC.stringToBytes(writeExpansion as String);
|
||||
return (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)
|
||||
var wexp = DC.stringToBytes(writeExpansion as String);
|
||||
return (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)
|
||||
var rexp = DC.stringToBytes(readExpansion as String);
|
||||
return (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())
|
||||
return (BinaryList()
|
||||
..addUint8(0x20 | pv)
|
||||
..addUint8(name.length)
|
||||
..addDC(name)
|
||||
..addDC(valueType.compose()))
|
||||
.toDC();
|
||||
}
|
||||
|
||||
PropertyTemplate(TypeTemplate template, int index, String name,
|
||||
TemplateDataType valueType, String read, String write, int storage)
|
||||
this.valueType, this.readExpansion, this.writeExpansion, this.storage)
|
||||
: super(template, MemberType.Property, index, name) {
|
||||
//this.Recordable = recordable;
|
||||
this.storage = storage;
|
||||
this.readExpansion = read;
|
||||
this.writeExpansion = write;
|
||||
this.valueType = valueType;
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ import '../../Resource/Warehouse.dart';
|
||||
import 'TemplateType.dart';
|
||||
|
||||
class TemplateDataType {
|
||||
int type;
|
||||
TypeTemplate get typeTemplate =>
|
||||
typeGuid == null ? null : Warehouse.getTemplateByClassId(typeGuid);
|
||||
late int type;
|
||||
TypeTemplate? get typeTemplate => typeGuid == null
|
||||
? null
|
||||
: Warehouse.getTemplateByClassId(typeGuid as Guid);
|
||||
|
||||
Guid typeGuid;
|
||||
Guid? typeGuid;
|
||||
|
||||
// @TODO: implement fromType
|
||||
TemplateDataType.fromType(type, bool isArray) {
|
||||
@ -98,7 +99,10 @@ class TemplateDataType {
|
||||
type == DataType.ResourceArray ||
|
||||
type == DataType.Record ||
|
||||
type == DataType.RecordArray) {
|
||||
return BinaryList().addUint8(type).addDC(typeGuid.value).toDC();
|
||||
return (BinaryList()
|
||||
..addUint8(type)
|
||||
..addDC((typeGuid as Guid).value))
|
||||
.toDC();
|
||||
} else
|
||||
return DC.fromList([type]);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import '../../Data/DataType.dart';
|
||||
|
||||
class TemplateDescriber {
|
||||
final List<Prop> properties;
|
||||
final List<Evt> events;
|
||||
final List<Func> functions;
|
||||
final List<Prop>? properties;
|
||||
final List<Evt>? events;
|
||||
final List<Func>? functions;
|
||||
final String nameSpace;
|
||||
final int version;
|
||||
|
||||
@ -47,8 +47,8 @@ class Prop {
|
||||
final String name;
|
||||
final Type type;
|
||||
final bool isArray;
|
||||
final String readAnnotation;
|
||||
final String writeAnnotation;
|
||||
final String? readAnnotation;
|
||||
final String? writeAnnotation;
|
||||
Prop(this.name, this.type, this.isArray,
|
||||
[this.readAnnotation = null, this.writeAnnotation = null]);
|
||||
}
|
||||
@ -58,7 +58,7 @@ class Evt {
|
||||
final bool listenable;
|
||||
final Type type;
|
||||
final bool isArray;
|
||||
final String annotation;
|
||||
final String? annotation;
|
||||
|
||||
Evt(this.name, this.type, this.isArray,
|
||||
[this.listenable = false, this.annotation]);
|
||||
@ -69,7 +69,7 @@ class Func {
|
||||
final Type returnType;
|
||||
final List<Arg> argsType;
|
||||
final bool isArray;
|
||||
final String annotation;
|
||||
final String? annotation;
|
||||
|
||||
Func(this.name, this.returnType, this.isArray, this.argsType,
|
||||
[this.annotation = null]);
|
||||
|
@ -22,26 +22,26 @@ import 'TemplateDataType.dart';
|
||||
import 'TemplateType.dart';
|
||||
|
||||
class TypeTemplate {
|
||||
Guid _classId;
|
||||
String _className;
|
||||
late Guid _classId;
|
||||
late String _className;
|
||||
List<MemberTemplate> _members = [];
|
||||
List<FunctionTemplate> _functions = [];
|
||||
List<EventTemplate> _events = [];
|
||||
List<PropertyTemplate> _properties = [];
|
||||
int _version;
|
||||
late int _version;
|
||||
//bool isReady;
|
||||
|
||||
TemplateType _templateType;
|
||||
late TemplateType _templateType;
|
||||
|
||||
DC _content;
|
||||
late DC _content;
|
||||
|
||||
DC get content => _content;
|
||||
|
||||
TemplateType get type => _templateType;
|
||||
|
||||
Type _definedType;
|
||||
Type? _definedType;
|
||||
|
||||
Type get definedType => _definedType;
|
||||
Type? get definedType => _definedType;
|
||||
/*
|
||||
MemberTemplate getMemberTemplate(MemberInfo member)
|
||||
{
|
||||
@ -59,32 +59,32 @@ class TypeTemplate {
|
||||
//@TODO: implement
|
||||
static List<TypeTemplate> getDependencies(TypeTemplate template) => [];
|
||||
|
||||
EventTemplate getEventTemplateByName(String eventName) {
|
||||
EventTemplate? getEventTemplateByName(String eventName) {
|
||||
for (var i in _events) if (i.name == eventName) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
EventTemplate getEventTemplateByIndex(int index) {
|
||||
EventTemplate? getEventTemplateByIndex(int index) {
|
||||
for (var i in _events) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByName(String functionName) {
|
||||
FunctionTemplate? getFunctionTemplateByName(String functionName) {
|
||||
for (var i in _functions) if (i.name == functionName) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionTemplate getFunctionTemplateByIndex(int index) {
|
||||
FunctionTemplate? getFunctionTemplateByIndex(int index) {
|
||||
for (var i in _functions) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByIndex(int index) {
|
||||
PropertyTemplate? getPropertyTemplateByIndex(int index) {
|
||||
for (var i in _properties) if (i.index == index) return i;
|
||||
return null;
|
||||
}
|
||||
|
||||
PropertyTemplate getPropertyTemplateByName(String propertyName) {
|
||||
PropertyTemplate? getPropertyTemplateByName(String propertyName) {
|
||||
for (var i in _properties) if (i.name == propertyName) return i;
|
||||
return null;
|
||||
}
|
||||
@ -143,9 +143,11 @@ class TypeTemplate {
|
||||
if (addToWarehouse) Warehouse.putTemplate(this);
|
||||
// _templates.add(template.classId, template);
|
||||
|
||||
if (describer.properties != null)
|
||||
for (var i = 0; i < describer.properties.length; i++) {
|
||||
var pi = describer.properties[i];
|
||||
if (describer.properties != null) {
|
||||
var props = describer.properties as List<Prop>;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var pi = props[i];
|
||||
var pt = PropertyTemplate(
|
||||
this,
|
||||
i,
|
||||
@ -156,10 +158,13 @@ class TypeTemplate {
|
||||
0);
|
||||
properties.add(pt);
|
||||
}
|
||||
}
|
||||
|
||||
if (describer.functions != null)
|
||||
for (var i = 0; i < describer.functions.length; i++) {
|
||||
var fi = describer.functions[i];
|
||||
if (describer.functions != null) {
|
||||
var funcs = describer.functions as List<Func>;
|
||||
|
||||
for (var i = 0; i < funcs.length; i++) {
|
||||
var fi = funcs[i];
|
||||
|
||||
List<ArgumentTemplate> args = fi.argsType
|
||||
.map((arg) => ArgumentTemplate(
|
||||
@ -176,10 +181,12 @@ class TypeTemplate {
|
||||
|
||||
functions.add(ft);
|
||||
}
|
||||
}
|
||||
|
||||
if (describer.events != null)
|
||||
for (var i = 0; i < describer.events.length; i++) {
|
||||
var ei = describer.events[i];
|
||||
if (describer.events != null) {
|
||||
var evts = describer.events as List<Evt>;
|
||||
for (var i = 0; i < evts.length; i++) {
|
||||
var ei = evts[i];
|
||||
|
||||
var et = new EventTemplate(
|
||||
this,
|
||||
@ -191,6 +198,7 @@ class TypeTemplate {
|
||||
|
||||
events.add(et);
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
events.forEach(_members.add);
|
||||
@ -200,14 +208,13 @@ class TypeTemplate {
|
||||
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);
|
||||
var b = BinaryList()
|
||||
..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()));
|
||||
@ -429,7 +436,7 @@ class TypeTemplate {
|
||||
|
||||
*/
|
||||
|
||||
TypeTemplate.parse(DC data, [int offset = 0, int contentLength]) {
|
||||
TypeTemplate.parse(DC data, [int offset = 0, int? contentLength]) {
|
||||
// cool Dart feature
|
||||
contentLength ??= data.length;
|
||||
|
||||
@ -464,7 +471,7 @@ class TypeTemplate {
|
||||
|
||||
if (type == 0) // function
|
||||
{
|
||||
String expansion = null;
|
||||
String? expansion = null;
|
||||
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||
|
||||
var name = data.getString(offset + 1, data[offset]);
|
||||
@ -497,7 +504,7 @@ class TypeTemplate {
|
||||
_functions.add(ft);
|
||||
} else if (type == 1) // property
|
||||
{
|
||||
String readExpansion = null, writeExpansion = null;
|
||||
String? readExpansion = null, writeExpansion = null;
|
||||
|
||||
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
|
||||
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
@ -539,7 +546,7 @@ class TypeTemplate {
|
||||
_properties.add(pt);
|
||||
} else if (type == 2) // Event
|
||||
{
|
||||
String expansion = null;
|
||||
String? expansion = null;
|
||||
var hasExpansion = ((data[offset] & 0x10) == 0x10);
|
||||
var listenable = ((data[offset++] & 0x8) == 0x8);
|
||||
|
||||
|
@ -22,6 +22,10 @@ SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
import '../Core/AsyncException.dart';
|
||||
import '../Core/ErrorType.dart';
|
||||
import '../Core/ExceptionCode.dart';
|
||||
|
||||
import '../Data/AutoList.dart';
|
||||
import 'FactoryEntry.dart';
|
||||
import 'Template/TemplateType.dart';
|
||||
@ -41,8 +45,7 @@ import '../Net/IIP/DistributedConnection.dart';
|
||||
|
||||
// Centeral Resource Issuer
|
||||
class Warehouse {
|
||||
static AutoList<IResource, Instance> _stores =
|
||||
new AutoList<IResource, Instance>(null);
|
||||
static AutoList<IStore, Instance> _stores = AutoList<IStore, Instance>();
|
||||
static Map<int, IResource> _resources = new Map<int, IResource>();
|
||||
static int resourceCounter = 0;
|
||||
|
||||
@ -74,8 +77,8 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="name">Store instance name</param>
|
||||
/// <returns></returns>
|
||||
static IStore getStore(String name) {
|
||||
for (var s in _stores) if (s.instance.name == name) return s;
|
||||
static IStore? getStore(String name) {
|
||||
for (var s in _stores) if (s.instance?.name == name) return s;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -84,11 +87,11 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="id">Instance Id</param>
|
||||
/// <returns></returns>
|
||||
static AsyncReply<IResource> getById(int id) {
|
||||
static AsyncReply<IResource?> getById(int id) {
|
||||
if (_resources.containsKey(id))
|
||||
return new AsyncReply<IResource>.ready(_resources[id]);
|
||||
return new AsyncReply<IResource?>.ready(_resources[id]);
|
||||
else
|
||||
return new AsyncReply<IResource>.ready(null);
|
||||
return new AsyncReply<IResource?>.ready(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -106,20 +109,21 @@ class Warehouse {
|
||||
var rt = new AsyncReply<bool>();
|
||||
bag.then((x) {
|
||||
for (var b in x)
|
||||
if (!b) {
|
||||
if (b == null || b == false) {
|
||||
rt.trigger(false);
|
||||
return;
|
||||
}
|
||||
|
||||
var rBag = new AsyncBag<bool>();
|
||||
for (var rk in _resources.keys)
|
||||
rBag.add(_resources[rk].trigger(ResourceTrigger.SystemInitialized));
|
||||
rBag.add((_resources[rk] as IResource)
|
||||
.trigger(ResourceTrigger.SystemInitialized));
|
||||
|
||||
rBag.seal();
|
||||
|
||||
rBag.then((y) {
|
||||
for (var b in y)
|
||||
if (!b) {
|
||||
if (b == null || b == false) {
|
||||
rt.trigger(false);
|
||||
return;
|
||||
}
|
||||
@ -158,7 +162,7 @@ class Warehouse {
|
||||
var rt = new AsyncReply<bool>();
|
||||
bag.then((x) {
|
||||
for (var b in x)
|
||||
if (!b) {
|
||||
if (b == null || b == false) {
|
||||
rt.trigger(false);
|
||||
return;
|
||||
}
|
||||
@ -178,19 +182,21 @@ class Warehouse {
|
||||
for (var child in resources) rt.add(child);
|
||||
else
|
||||
for (var child in resources)
|
||||
if (child.instance.name == path[index]) rt.add(child);
|
||||
if (child.instance?.name == path[index]) rt.add(child);
|
||||
} else
|
||||
for (var child in resources)
|
||||
if (child.instance.name == path[index])
|
||||
rt.addAll(qureyIn(path, index + 1, child.instance.children));
|
||||
if (child.instance?.name == path[index])
|
||||
rt.addAll(qureyIn(path, index + 1,
|
||||
child.instance?.children as AutoList<IResource, Instance>));
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
static AsyncReply<List<IResource>> query(String path) {
|
||||
static AsyncReply<List<IResource>?> query(String? path) {
|
||||
if (path == null || path == "") {
|
||||
var roots = _stores.where((s) => s.instance.parents.length == 0).toList();
|
||||
return new AsyncReply<List<IResource>>.ready(roots);
|
||||
var roots =
|
||||
_stores.where((s) => s.instance?.parents.length == 0).toList();
|
||||
return new AsyncReply<List<IResource>?>.ready(roots);
|
||||
} else {
|
||||
var rt = new AsyncReply<List<IResource>>();
|
||||
get(path).then((x) {
|
||||
@ -215,40 +221,46 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns>Resource instance.</returns>
|
||||
static AsyncReply<T> get<T extends IResource>(String path,
|
||||
static AsyncReply<T?> get<T extends IResource>(String path,
|
||||
[attributes = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null]) {
|
||||
var rt = AsyncReply<T>();
|
||||
IResource? parent = null,
|
||||
IPermissionsManager? manager = null]) {
|
||||
var rt = AsyncReply<T?>();
|
||||
|
||||
// Should we create a new store ?
|
||||
if (_urlRegex.hasMatch(path)) {
|
||||
var url = _urlRegex.allMatches(path).first;
|
||||
|
||||
if (protocols.containsKey(url[1])) {
|
||||
var handler = protocols[url[1]];
|
||||
var handler =
|
||||
protocols[url[1]] as AsyncReply<IStore> Function(String, dynamic);
|
||||
|
||||
var getFromStore = () {
|
||||
handler(url[2], attributes).then<IStore>((store) {
|
||||
if (url[3].length > 0 && url[3] != "")
|
||||
store.get(url[3]).then<dynamic>((r) {
|
||||
rt.trigger(r);
|
||||
}).error((e) => rt.triggerError(e));
|
||||
else
|
||||
rt.trigger(store as T);
|
||||
}).error((e) {
|
||||
rt.triggerError(e);
|
||||
//Warehouse.remove(store);
|
||||
});
|
||||
handler(url[2] as String, attributes)
|
||||
..then((store) {
|
||||
if ((url[3] as String).length > 0 && url[3] != "")
|
||||
store.get(url[3] as String)
|
||||
..then((r) {
|
||||
rt.trigger(r as T);
|
||||
})
|
||||
..error((e) => rt.triggerError(e));
|
||||
else
|
||||
rt.trigger(store as T);
|
||||
})
|
||||
..error((e) {
|
||||
rt.triggerError(e);
|
||||
//Warehouse.remove(store);
|
||||
});
|
||||
};
|
||||
|
||||
if (!_warehouseIsOpen)
|
||||
open().then((v) {
|
||||
if (v)
|
||||
getFromStore();
|
||||
else
|
||||
rt.trigger(null);
|
||||
});
|
||||
open()
|
||||
..then((v) {
|
||||
if (v)
|
||||
getFromStore();
|
||||
else
|
||||
rt.trigger(null);
|
||||
});
|
||||
else
|
||||
getFromStore();
|
||||
|
||||
@ -258,7 +270,7 @@ class Warehouse {
|
||||
|
||||
query(path).then((rs) {
|
||||
if (rs != null && rs.length > 0)
|
||||
rt.trigger(rs[0]);
|
||||
rt.trigger(rs[0] as T);
|
||||
else
|
||||
rt.trigger(null);
|
||||
});
|
||||
@ -342,14 +354,14 @@ class Warehouse {
|
||||
/// <param name="name">Resource name.</param>
|
||||
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
|
||||
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
|
||||
static AsyncReply<T> put<T extends IResource>(String name, T resource,
|
||||
[IStore store = null,
|
||||
IResource parent = null,
|
||||
TypeTemplate customTemplate = null,
|
||||
static AsyncReply<T?> put<T extends IResource>(String name, T resource,
|
||||
[IStore? store = null,
|
||||
IResource? parent = null,
|
||||
TypeTemplate? customTemplate = null,
|
||||
int age = 0,
|
||||
IPermissionsManager manager = null,
|
||||
IPermissionsManager? manager = null,
|
||||
attributes = null]) {
|
||||
var rt = AsyncReply<T>();
|
||||
var rt = AsyncReply<T?>();
|
||||
|
||||
if (resource.instance != null) {
|
||||
rt.triggerError(Exception("Resource has a store."));
|
||||
@ -415,19 +427,21 @@ class Warehouse {
|
||||
resourceCounter++, name, resource, store, customTemplate, age);
|
||||
|
||||
if (attributes != null)
|
||||
resource.instance.setAttributes(Structure.fromMap(attributes));
|
||||
resource.instance?.setAttributes(Structure.fromMap(attributes));
|
||||
|
||||
if (manager != null) resource.instance.managers.add(manager);
|
||||
if (manager != null) resource.instance?.managers.add(manager);
|
||||
|
||||
if (store == parent) parent = null;
|
||||
|
||||
if (parent == null) {
|
||||
if (!(resource is IStore)) store.instance.children.add(resource);
|
||||
if (!(resource is IStore)) store?.instance?.children.add(resource);
|
||||
} else
|
||||
parent.instance.children.add(resource);
|
||||
parent.instance?.children.add(resource);
|
||||
|
||||
var initResource = () {
|
||||
_resources[resource.instance.id] = resource;
|
||||
if (resource.instance == null) return;
|
||||
|
||||
_resources[(resource.instance as Instance).id] = resource;
|
||||
|
||||
if (_warehouseIsOpen) {
|
||||
resource.trigger(ResourceTrigger.Initialize).then<dynamic>((value) {
|
||||
@ -451,7 +465,7 @@ class Warehouse {
|
||||
_stores.add(resource);
|
||||
initResource();
|
||||
} else {
|
||||
store.put(resource).then<dynamic>((value) {
|
||||
store?.put(resource).then<dynamic>((value) {
|
||||
if (value)
|
||||
initResource();
|
||||
else
|
||||
@ -468,20 +482,23 @@ class Warehouse {
|
||||
}
|
||||
|
||||
static T createInstance<T>(Type T) {
|
||||
return _factory[T].instanceCreator.call();
|
||||
return _factory[T]?.instanceCreator.call();
|
||||
}
|
||||
|
||||
static List<T> createArray<T>(Type T) {
|
||||
return _factory[T].arrayCreator.call();
|
||||
return _factory[T]?.arrayCreator.call();
|
||||
}
|
||||
|
||||
static AsyncReply<T> newResource<T extends IResource>(String name,
|
||||
[IStore store = null,
|
||||
IResource parent = null,
|
||||
IPermissionsManager manager = null,
|
||||
[IStore? store = null,
|
||||
IResource? parent = null,
|
||||
IPermissionsManager? manager = null,
|
||||
attributes = null,
|
||||
properties = null]) {
|
||||
var resource = _factory[T].instanceCreator.call();
|
||||
if (_factory[T] == null)
|
||||
throw Exception("No Instance Creator was found for type ${T}");
|
||||
|
||||
var resource = _factory[T]?.instanceCreator.call();
|
||||
|
||||
if (properties != null) {
|
||||
dynamic d = resource;
|
||||
@ -494,12 +511,16 @@ class Warehouse {
|
||||
var rt = AsyncReply<T>();
|
||||
|
||||
put<T>(name, resource, store, parent, null, 0, manager, attributes)
|
||||
.then<IResource>((value) {
|
||||
if (value != null)
|
||||
rt.trigger(resource);
|
||||
else
|
||||
rt.trigger(null);
|
||||
}).error((ex) => rt.triggerError(ex));
|
||||
..then((value) {
|
||||
if (value != null)
|
||||
rt.trigger(resource);
|
||||
else
|
||||
rt.triggerError(AsyncException(
|
||||
ErrorType.Management,
|
||||
ExceptionCode.GeneralFailure.index,
|
||||
"Can't put the resource")); // .trigger(null);
|
||||
})
|
||||
..error((ex) => rt.triggerError(ex));
|
||||
|
||||
return rt;
|
||||
|
||||
@ -516,7 +537,7 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="template">Resource template.</param>
|
||||
static void putTemplate(TypeTemplate template) {
|
||||
_templates[template.type][template.classId] = template;
|
||||
_templates[template.type]?[template.classId] = template;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -541,22 +562,22 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="classId">Class Id.</param>
|
||||
/// <returns>Resource template.</returns>
|
||||
static TypeTemplate getTemplateByClassId(Guid classId,
|
||||
static TypeTemplate? getTemplateByClassId(Guid classId,
|
||||
[TemplateType templateType = TemplateType.Unspecified]) {
|
||||
if (templateType == TemplateType.Unspecified) {
|
||||
// look in resources
|
||||
var template = _templates[TemplateType.Resource][classId];
|
||||
var template = _templates[TemplateType.Resource]?[classId];
|
||||
if (template != null) return template;
|
||||
|
||||
// look in records
|
||||
template = _templates[TemplateType.Record][classId];
|
||||
template = _templates[TemplateType.Record]?[classId];
|
||||
if (template != null) return template;
|
||||
|
||||
// look in wrappers
|
||||
template = _templates[TemplateType.Wrapper][classId];
|
||||
template = _templates[TemplateType.Wrapper]?[classId];
|
||||
return template;
|
||||
} else {
|
||||
return _templates[templateType][classId];
|
||||
return _templates[templateType]?[classId];
|
||||
}
|
||||
}
|
||||
|
||||
@ -565,29 +586,29 @@ class Warehouse {
|
||||
/// </summary>
|
||||
/// <param name="className">Class name.</param>
|
||||
/// <returns>Resource template.</returns>
|
||||
static TypeTemplate getTemplateByClassName(String className,
|
||||
static TypeTemplate? getTemplateByClassName(String className,
|
||||
[TemplateType templateType = TemplateType.Unspecified]) {
|
||||
if (templateType == TemplateType.Unspecified) {
|
||||
// look in resources
|
||||
var template = _templates[TemplateType.Resource]
|
||||
.values
|
||||
?.values
|
||||
.firstWhere((x) => x.className == className);
|
||||
if (template != null) return template;
|
||||
|
||||
// look in records
|
||||
template = _templates[TemplateType.Record]
|
||||
.values
|
||||
?.values
|
||||
.firstWhere((x) => x.className == className);
|
||||
if (template != null) return template;
|
||||
|
||||
// look in wrappers
|
||||
template = _templates[TemplateType.Wrapper]
|
||||
.values
|
||||
?.values
|
||||
.firstWhere((x) => x.className == className);
|
||||
return template;
|
||||
} else {
|
||||
return _templates[templateType]
|
||||
.values
|
||||
?.values
|
||||
.firstWhere((x) => x.className == className);
|
||||
}
|
||||
}
|
||||
@ -595,8 +616,8 @@ class Warehouse {
|
||||
static bool remove(IResource resource) {
|
||||
if (resource.instance == null) return false;
|
||||
|
||||
if (_resources.containsKey(resource.instance.id))
|
||||
_resources.remove(resource.instance.id);
|
||||
if (_resources.containsKey(resource.instance?.id))
|
||||
_resources.remove(resource.instance?.id);
|
||||
else
|
||||
return false;
|
||||
|
||||
@ -605,14 +626,14 @@ class Warehouse {
|
||||
|
||||
// remove all objects associated with the store
|
||||
var toBeRemoved =
|
||||
_resources.values.where((x) => x.instance.store == resource);
|
||||
_resources.values.where((x) => x.instance?.store == resource);
|
||||
for (var o in toBeRemoved) remove(o);
|
||||
|
||||
// StoreDisconnected?.Invoke(resource as IStore);
|
||||
}
|
||||
|
||||
if (resource.instance.store != null)
|
||||
resource.instance.store.remove(resource);
|
||||
if (resource.instance?.store != null)
|
||||
resource.instance?.store?.remove(resource);
|
||||
|
||||
resource.destroy();
|
||||
|
||||
|
Reference in New Issue
Block a user