diff options
| author | Roy <roy.mail.net@gmail.com> | 2017-11-21 02:00:17 +0200 |
|---|---|---|
| committer | Roy <roy.mail.net@gmail.com> | 2017-11-21 02:00:17 +0200 |
| commit | de6319ff6f0531495fa125c6639a9d622ecbd9b1 (patch) | |
| tree | a0feb03b08446c3aa0e36fc44e228500f5f9b255 /Software | |
| parent | 0cd6796d91605432237f379b0c28918f24c8a622 (diff) | |
| download | Tango-de6319ff6f0531495fa125c6639a9d622ecbd9b1.tar.gz Tango-de6319ff6f0531495fa125c6639a9d622ecbd9b1.zip | |
Implemented progress stub on android.
Some bug fixes.
Diffstat (limited to 'Software')
13 files changed, 363 insertions, 26 deletions
diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java index 6301cdf24..92e4f9305 100644 --- a/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java +++ b/Software/Android_Studio/Tango.SharedUI/src/main/java/com/twine/tango/sharedui/editors/ParameterizedEditor.java @@ -58,9 +58,9 @@ public class ParameterizedEditor extends ScrollView for (ParameterItem item : items) { - TextView textView = new TextView(this.getContext()); - textView.setText(item.getName()); - layout.addView(textView); + View titleView = LayoutInflater.from(layout.getContext()).inflate(R.layout.editor_title,layout,false); + ((TextView)titleView.findViewById(R.id.editor_title_txtView)).setText(item.getName()); + layout.addView(titleView); ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(layout.getContext()), R.layout.editor_range, layout, false); binding.setVariable(BR.item, item); diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/drawable/rounded_rectangle.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/drawable/rounded_rectangle.xml new file mode 100644 index 000000000..ed4e6abde --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/drawable/rounded_rectangle.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <solid android:color="#606060"/> + + <padding android:left="1dp" + android:top="1dp" + android:right="1dp" + android:bottom="1dp" + /> + + <corners android:bottomRightRadius="7dp" android:bottomLeftRadius="7dp" + android:topLeftRadius="7dp" android:topRightRadius="7dp"/> +</shape>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_title.xml b/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_title.xml new file mode 100644 index 000000000..cc4a3a901 --- /dev/null +++ b/Software/Android_Studio/Tango.SharedUI/src/main/res/layout/editor_title.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" android:layout_width="match_parent" + android:layout_height="match_parent"> + + + <TextView + android:id="@+id/editor_title_txtView" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:layout_marginBottom="5dp" + android:padding="5dp" + android:background="@drawable/rounded_rectangle" + android:text="TextView" /> +</LinearLayout>
\ No newline at end of file diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java index c91197b99..d6c02fa75 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Calculate.java @@ -46,7 +46,7 @@ public class Calculate extends StubBase MessageFactory.createTangoMessage( CalculateRequest.class, CalculateRequest.newBuilder().setA(num1).setB(num2).build())).subscribe((response) -> - subject.onNext(String.valueOf(response.getSum()))); + subject.onNext(String.valueOf(response.getSum())), subject::onError); return subject; } diff --git a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java index 94c2a199d..a9d8176a2 100644 --- a/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java +++ b/Software/Android_Studio/Tango.Stubs/src/main/java/com/twine/tango/stubs/stubs/Progress.java @@ -3,6 +3,8 @@ package com.twine.tango.stubs.stubs; import com.twine.tango.pmr.MessageFactory; import com.twine.tango.pmr.stubs.ProgressRequestOuterClass.ProgressRequest; import com.twine.tango.pmr.stubs.ProgressResponseOuterClass.ProgressResponse; +import com.twine.tango.sharedui.editors.ParameterAnnotation; +import com.twine.tango.sharedui.mvvm.DependencyProperty; import com.twine.tango.stubs.StubAnnotation; import com.twine.tango.stubs.StubBase; import com.twine.tango.stubs.StubDirection; @@ -23,17 +25,23 @@ public class Progress extends StubBase super(transporter); } + @ParameterAnnotation(name = "Amount", maximum = 1000, defaultValue = 100) + public DependencyProperty<Number> amount = new DependencyProperty<>(100); + + @ParameterAnnotation(name = "Delay", maximum = 20, defaultValue = 4) + public DependencyProperty<Number> delay = new DependencyProperty<>(4); + @Override protected Observable<String> onRun() { PublishSubject<String> subject = PublishSubject.create(); - + getTransporter().<ProgressRequest, ProgressResponse>sendContinuousRequest( MessageFactory.createTangoMessage( ProgressRequest.class, - ProgressRequest.newBuilder().build())).subscribe((response) -> + ProgressRequest.newBuilder().setAmount(amount.get().intValue()).setDelay(delay.get().intValue()).build())).subscribe((response) -> subject.onNext(String.valueOf(response.getProgress()))); - + return subject; } } diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java index 6794b0f57..475893f02 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/ITransporter.java @@ -31,9 +31,11 @@ public interface ITransporter extends ITransportComponent { <Response extends GeneratedMessageV3> Single<Response> sendResponse(TangoMessage<Response> response,String token); - void setRequestReceiverListener(EventHandler<MessageContainer> listener); + void setRequestReceivedListener(EventHandler<MessageContainer> listener); Period getRequestTimeout(); void setRequestTimeout(Period duration); + + } diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java index 422f4ad00..5c0715806 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/TransporterBase.java @@ -200,7 +200,7 @@ public abstract class TransporterBase implements ITransporter sendingQueue = new ConcurrentLinkedQueue<>(); pendingRequests = new ArrayList<>(); arrivedResponses = new ConcurrentLinkedQueue<>(); - setRequestTimeout(Period.seconds(10)); + setRequestTimeout(Period.seconds(2)); } public TransporterBase(ITransportAdapter adapter) @@ -226,7 +226,7 @@ public abstract class TransporterBase implements ITransporter } @Override - public void setRequestReceiverListener(EventHandler<MessageContainer> listener) + public void setRequestReceivedListener(EventHandler<MessageContainer> listener) { this.requestReceivedListener = listener; } @@ -311,9 +311,10 @@ public abstract class TransporterBase implements ITransporter { if (!subject.hasComplete()) { - XLog.i("Request message " + request.getClass().getSimpleName() + " had timed out after " + getRequestTimeout().getSeconds() + " seconds."); + TimeoutException exception = new TimeoutException("Request message " + request.getMessage().getClass().getSimpleName() + " had timed out after " + getRequestTimeout().getSeconds() + " seconds."); + XLog.e(exception); XLog.i("Setting request task exception..."); - subject.onError(new TimeoutException()); + subject.onError(exception); } }); @@ -445,8 +446,11 @@ public abstract class TransporterBase implements ITransporter } } else { - message.getAdapter().write(message.getSerialize().invoke()); - XLog.i("message sent on adapter: " + message.getAdapter().getAddress() + "..."); + if (message.getAdapter().getState() == TransportComponentState.Connected) + { + message.getAdapter().write(message.getSerialize().invoke()); + XLog.i("message sent on adapter: " + message.getAdapter().getAddress() + "..."); + } } if (message.getDirection() == TransportMessageDirection.Request) diff --git a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java index 3435917a3..b72d1669b 100644 --- a/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java +++ b/Software/Android_Studio/Tango.Transport/src/main/java/com/twine/tango/transport/adapters/TcpTransportAdapter.java @@ -9,6 +9,7 @@ import com.twine.tango.transport.TransportComponentState; import java.io.IOException; import java.io.InputStream; +import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; import java.nio.channels.Selector; @@ -82,7 +83,8 @@ public class TcpTransportAdapter extends TransportAdapterBase { if (!initializedFromConstructor) { - socket = new Socket(getAddress(), getPort()); + socket = new Socket(); + socket.connect(new InetSocketAddress(getAddress(), getPort()), 2000); //selector = Selector.open(); //socket.getChannel().register(selector, SelectionKey.OP_READ); } diff --git a/Software/Visual_Studio/Tango.Core/ConcurrentList.cs b/Software/Visual_Studio/Tango.Core/ConcurrentList.cs new file mode 100644 index 000000000..d77ca14db --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/ConcurrentList.cs @@ -0,0 +1,280 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Tango.Core +{ + /// <summary> + /// Thread safe List. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <seealso cref="System.Collections.Generic.IList{T}" /> + /// <seealso cref="System.IDisposable" /> + public class ConcurrentList<T> : IList<T>, IDisposable + { + #region Fields + internal readonly List<T> InnerList; + private readonly ReaderWriterLockSlim _lock; + #endregion + + #region Constructors + public ConcurrentList() + { + this._lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + this.InnerList = new List<T>(); + } + + public ConcurrentList(int capacity) + { + this._lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + this.InnerList = new List<T>(capacity); + } + + public ConcurrentList(IEnumerable<T> items) + { + this._lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + this.InnerList = new List<T>(items); + } + #endregion + + #region Methods + public void Add(T item) + { + try + { + this._lock.EnterWriteLock(); + this.InnerList.Add(item); + } + finally + { + this._lock.ExitWriteLock(); + } + } + + public void Insert(int index, T item) + { + try + { + this._lock.EnterWriteLock(); + this.InnerList.Insert(index, item); + } + finally + { + this._lock.ExitWriteLock(); + } + } + + public bool Remove(T item) + { + try + { + this._lock.EnterWriteLock(); + return this.InnerList.Remove(item); + } + finally + { + this._lock.ExitWriteLock(); + } + } + + public void RemoveAt(int index) + { + try + { + this._lock.EnterWriteLock(); + this.InnerList.RemoveAt(index); + } + finally + { + this._lock.ExitWriteLock(); + } + } + + public int IndexOf(T item) + { + try + { + this._lock.EnterReadLock(); + return this.InnerList.IndexOf(item); + } + finally + { + this._lock.ExitReadLock(); + } + } + + public void Clear() + { + try + { + this._lock.EnterWriteLock(); + this.InnerList.Clear(); + } + finally + { + this._lock.ExitWriteLock(); + } + } + + public bool Contains(T item) + { + try + { + this._lock.EnterReadLock(); + return this.InnerList.Contains(item); + } + finally + { + this._lock.ExitReadLock(); + } + } + + public void CopyTo(T[] array, int arrayIndex) + { + try + { + this._lock.EnterReadLock(); + this.InnerList.CopyTo(array, arrayIndex); + } + finally + { + this._lock.ExitReadLock(); + } + } + + public IEnumerator<T> GetEnumerator() + { + return new ConcurrentEnumerator<T>(this.InnerList, this._lock); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return new ConcurrentEnumerator<T>(this.InnerList, this._lock); + } + + ~ConcurrentList() + { + this.Dispose(false); + } + + public void Dispose() + { + this.Dispose(true); + } + + private void Dispose(bool disposing) + { + if (disposing) + GC.SuppressFinalize(this); + + this._lock.Dispose(); + } + #endregion + + #region Properties + public T this[int index] + { + get + { + try + { + this._lock.EnterReadLock(); + return this.InnerList[index]; + } + finally + { + this._lock.ExitReadLock(); + } + } + set + { + try + { + this._lock.EnterWriteLock(); + this.InnerList[index] = value; + } + finally + { + this._lock.ExitWriteLock(); + } + } + } + + public int Count + { + get + { + try + { + this._lock.EnterReadLock(); + return this.InnerList.Count; + } + finally + { + this._lock.ExitReadLock(); + } + } + } + + public bool IsReadOnly + { + get { return false; } + } + #endregion + } + + /// <summary> + /// Thread safe enumerator. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <seealso cref="System.Collections.Generic.IEnumerator{T}" /> + public class ConcurrentEnumerator<T> : IEnumerator<T> + { + #region Fields + private readonly IEnumerator<T> _inner; + private readonly ReaderWriterLockSlim _lock; + #endregion + + #region Constructor + public ConcurrentEnumerator(IEnumerable<T> inner, ReaderWriterLockSlim @lock) + { + this._lock = @lock; + this._lock.EnterReadLock(); + this._inner = inner.GetEnumerator(); + } + #endregion + + #region Methods + public bool MoveNext() + { + return _inner.MoveNext(); + } + + public void Reset() + { + _inner.Reset(); + } + + public void Dispose() + { + this._lock.ExitReadLock(); + } + #endregion + + #region Properties + public T Current + { + get { return _inner.Current; } + } + + object IEnumerator.Current + { + get { return _inner.Current; } + } + #endregion + } +} diff --git a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj index 4954868d3..7b1074a3d 100644 --- a/Software/Visual_Studio/Tango.Core/Tango.Core.csproj +++ b/Software/Visual_Studio/Tango.Core/Tango.Core.csproj @@ -51,6 +51,7 @@ <Compile Include="..\Versioning\GlobalVersionInfo.cs"> <Link>GlobalVersionInfo.cs</Link> </Compile> + <Compile Include="ConcurrentList.cs" /> <Compile Include="ExtensionMethods\DependencyObjectExtensions.cs" /> <Compile Include="ExtensionMethods\EnumExtensions.cs" /> <Compile Include="ExtensionMethods\IMessageExtensions.cs" /> diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index b41fd1804..c799adc93 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -66,13 +66,13 @@ namespace Tango.Emulations.Emulators Task.Factory.StartNew(() => { - for (int i = 0; i < 10; i++) + for (int i = 0; i < r.Amount; i++) { - Thread.Sleep(500); + Thread.Sleep(r.Delay * 10); var res = MessageFactory.CreateTangoMessage<ProgressResponse>(container.Token); res.Message.Progress = i; - if (i == 9) res.Container.Completed = true; + if (i == r.Amount - 1) res.Container.Completed = true; Transporter.SendResponse(res); } diff --git a/Software/Visual_Studio/Tango.Transport/ITransporter.cs b/Software/Visual_Studio/Tango.Transport/ITransporter.cs index 07b7dd554..9127d0138 100644 --- a/Software/Visual_Studio/Tango.Transport/ITransporter.cs +++ b/Software/Visual_Studio/Tango.Transport/ITransporter.cs @@ -91,5 +91,10 @@ namespace Tango.Transport /// Gets or sets the request timeout. /// </summary> TimeSpan RequestTimeout { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the transporter should remove an adapter when it fails. + /// </summary> + bool RemoveAdaptersOnFailed { get; set; } } } diff --git a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs index 3bfa019f3..bb3a95cbc 100644 --- a/Software/Visual_Studio/Tango.Transport/TransporterBase.cs +++ b/Software/Visual_Studio/Tango.Transport/TransporterBase.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Tango.Core; using Tango.Logging; using Tango.PMR; using Tango.PMR.Common; @@ -84,6 +85,11 @@ namespace Tango.Transport /// </summary> public TimeSpan RequestTimeout { get; set; } + /// <summary> + /// Gets or sets a value indicating whether the transporter should remove an adapter when it fails. + /// </summary> + public bool RemoveAdaptersOnFailed { get; set; } + #endregion #region Virtual Methods @@ -97,7 +103,7 @@ namespace Tango.Transport { LogManager.Log("Adapters collection changed, Listing adapters:"); - foreach (var ad in _adapters) + foreach (var ad in new ConcurrentList<ITransportAdapter>(_adapters)) { LogManager.Log(ad.GetType().Name + ", " + ad.Address + ", " + ad.State.ToString()); @@ -120,14 +126,10 @@ namespace Tango.Transport /// <param name="e">The e.</param> protected virtual void OnAdapterStateChanged(object sender, TransportComponentState e) { - if (e == TransportComponentState.Disposed) + if (e == TransportComponentState.Failed && RemoveAdaptersOnFailed) { Adapters.Remove(sender as ITransportAdapter); } - else if (e == TransportComponentState.Failed) - { - //TODO: decide what to do in this case.. - } } /// <summary> @@ -209,6 +211,7 @@ namespace Tango.Transport /// </summary> public TransporterBase() { + RemoveAdaptersOnFailed = true; Adapters = new ObservableCollection<ITransportAdapter>(); _pendingResponses = new Dictionary<string, PendingResponse>(); _sendingQueue = new ConcurrentQueue<TransportMessageBase>(); @@ -434,8 +437,11 @@ namespace Tango.Transport } else { - message.Adapter.Write(message.Serialize()); - LogManager.Log("Message sent on adapter: " + message.Adapter.Address + "..."); + if (message.Adapter.State == TransportComponentState.Connected) + { + message.Adapter.Write(message.Serialize()); + LogManager.Log("Message sent on adapter: " + message.Adapter.Address + "..."); + } } if (message.Direction == TransportMessageDirection.Request) |
