diff --git a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java new file mode 100644 index 0000000000..108b4060e0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java @@ -0,0 +1,90 @@ +package info.nightscout.androidaps.data; + +import android.support.annotation.Nullable; +import android.support.v4.util.LongSparseArray; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.interfaces.Interval; + +/** + * Created by mike on 09.05.2017. + */ + +// Zero duration means end of interval + +public abstract class Intervals { + + LongSparseArray rawData = new LongSparseArray(); // oldest at index 0 + + public synchronized Intervals reset() { + rawData = new LongSparseArray(); + return this; + } + + protected abstract void merge(); + + /** + * The List must be sorted by `T.start()` in ascending order + * + * */ + public synchronized void add(List list) { + for (T interval : list) { + rawData.put(interval.start(), interval); + } + merge(); + } + + + + public synchronized List getList() { + List list = new ArrayList<>(); + for (int i = 0; i < rawData.size(); i++) + list.add(rawData.valueAt(i)); + return list; + } + + public synchronized List getReversedList() { + List list = new ArrayList<>(); + for (int i = rawData.size() -1; i>=0; i--) + list.add(rawData.valueAt(i)); + return list; + } + + protected synchronized int binarySearch(long value) { + int lo = 0; + int hi = rawData.size() - 1; + + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final Interval midVal = rawData.valueAt(mid); + + if (midVal.before(value)) { + lo = mid + 1; + } else if (midVal.after(value)) { + hi = mid - 1; + } else if (midVal.match(value)) { + return mid; // value found + } + } + return ~lo; // value not present + } + + public abstract T getValueByInterval(long time); + + public synchronized int size() { + return rawData.size(); + } + + public synchronized T get(int index) { + return rawData.valueAt(index); + } + + public synchronized T getReversed(int index) { + return rawData.valueAt(size() - 1 - index); + } + + + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java new file mode 100644 index 0000000000..385eeb9594 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java @@ -0,0 +1,30 @@ +package info.nightscout.androidaps.data; + + +import android.support.annotation.Nullable; + +import info.nightscout.androidaps.interfaces.Interval; + +/** + * Created by adrian on 15/07/17. + */ + +public class NonOverlappingIntervals extends Intervals { + + protected synchronized void merge() { + for (int index = 0; index < rawData.size() - 1; index++) { + Interval i = rawData.valueAt(index); + long startOfNewer = rawData.valueAt(index + 1).start(); + if (i.originalEnd() > startOfNewer) { + i.cutEndTo(startOfNewer); + } + } + } + + @Nullable + public synchronized T getValueByInterval(long time) { + int index = binarySearch(time); + if (index >= 0) return rawData.valueAt(index); + return null; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java index cc03936766..608fa8d328 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java @@ -1,99 +1,43 @@ package info.nightscout.androidaps.data; -import android.support.annotation.Nullable; -import android.support.v4.util.LongSparseArray; -import java.util.ArrayList; -import java.util.List; +import android.support.annotation.Nullable; import info.nightscout.androidaps.interfaces.Interval; /** - * Created by mike on 09.05.2017. + * Created by adrian on 15/07/17. */ -// Zero duration means end of interval +public class OverlappingIntervals extends Intervals { -public class OverlappingIntervals { + protected synchronized void merge() { + boolean needToCut = false; + long cutTime = 0; - private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 - - public OverlappingIntervals reset() { - rawData = new LongSparseArray<>(); - return this; - } - - public void add(T newInterval) { - rawData.put(newInterval.start(), newInterval); - merge(); - } - - public void add(List list) { - for (T interval : list) { - rawData.put(interval.start(), interval); - } - merge(); - } - - private void merge() { - for (int index = 0; index < rawData.size() - 1; index++) { - Interval i = rawData.valueAt(index); - long startOfNewer = rawData.valueAt(index + 1).start(); - if (i.originalEnd() > startOfNewer) { - i.cutEndTo(startOfNewer); + for (int index = rawData.size()-1; index > 0; index--) { //begin with newest + Interval cur = rawData.valueAt(index); + if (cur.isEndingEvent()){ + needToCut = true; + cutTime = cur.start(); + } else { + //event that is no EndingEvent might need to be stopped by an ending event + if(needToCut&&cur.end() > cutTime){ + cur.cutEndTo(cutTime); + } } } } @Nullable - public Interval getValueByInterval(long time) { - int index = binarySearch(time); - if (index >= 0) return rawData.valueAt(index); + public synchronized T getValueByInterval(long time) { + for (int index = rawData.size()-1; index > 0; index--) { //begin with newest + T cur = rawData.valueAt(index); + if (cur.match(time)){ + return cur; + } + } return null; } - public List getList() { - List list = new ArrayList<>(); - for (int i = 0; i < rawData.size(); i++) - list.add(rawData.valueAt(i)); - return list; - } - - public List getReversedList() { - List list = new ArrayList<>(); - for (int i = rawData.size() -1; i>=0; i--) - list.add(rawData.valueAt(i)); - return list; - } - - private int binarySearch(long value) { - int lo = 0; - int hi = rawData.size() - 1; - - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final Interval midVal = rawData.valueAt(mid); - - if (midVal.before(value)) { - lo = mid + 1; - } else if (midVal.after(value)) { - hi = mid - 1; - } else if (midVal.match(value)) { - return mid; // value found - } - } - return ~lo; // value not present - } - - public int size() { - return rawData.size(); - } - - public T get(int index) { - return rawData.valueAt(index); - } - - public T getReversed(int index) { - return rawData.valueAt(size() - 1 - index); - } -} \ No newline at end of file +} diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java index ef255ed901..3633f1079e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -19,24 +19,24 @@ public class ProfileIntervals { private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 - public ProfileIntervals reset() { + public synchronized ProfileIntervals reset() { rawData = new LongSparseArray<>(); return this; } - public void add(T newInterval) { + public synchronized void add(T newInterval) { rawData.put(newInterval.start(), newInterval); merge(); } - public void add(List list) { + public synchronized void add(List list) { for (T interval : list) { rawData.put(interval.start(), interval); } merge(); } - private void merge() { + private synchronized void merge() { for (int index = 0; index < rawData.size() - 1; index++) { Interval i = rawData.valueAt(index); long startOfNewer = rawData.valueAt(index + 1).start(); @@ -47,27 +47,27 @@ public class ProfileIntervals { } @Nullable - public Interval getValueToTime(long time) { + public synchronized Interval getValueToTime(long time) { int index = binarySearch(time); if (index >= 0) return rawData.valueAt(index); return null; } - public List getList() { + public synchronized List getList() { List list = new ArrayList<>(); for (int i = 0; i < rawData.size(); i++) list.add(rawData.valueAt(i)); return list; } - public List getReversedList() { + public synchronized List getReversedList() { List list = new ArrayList<>(); for (int i = rawData.size() -1; i>=0; i--) list.add(rawData.valueAt(i)); return list; } - private int binarySearch(long value) { + private synchronized int binarySearch(long value) { if (rawData.size() == 0) return -1; int lo = 0; @@ -95,15 +95,15 @@ public class ProfileIntervals { return -1; // value not present } - public int size() { + public synchronized int size() { return rawData.size(); } - public T get(int index) { + public synchronized T get(int index) { return rawData.valueAt(index); } - public T getReversed(int index) { + public synchronized T getReversed(int index) { return rawData.valueAt(size() - 1 - index); } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java index d9e3742c70..5e8b4e52e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/TreatmentsInterface.java @@ -10,7 +10,7 @@ import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.androidaps.data.ProfileIntervals; /** @@ -42,18 +42,18 @@ public interface TreatmentsInterface { TemporaryBasal getTempBasalFromHistory(long time); double getTempBasalAbsoluteRateHistory(); double getTempBasalRemainingMinutesFromHistory(); - OverlappingIntervals getTemporaryBasalsFromHistory(); + Intervals getTemporaryBasalsFromHistory(); boolean isInHistoryExtendedBoluslInProgress(); ExtendedBolus getExtendedBolusFromHistory(long time); - OverlappingIntervals getExtendedBolusesFromHistory(); + Intervals getExtendedBolusesFromHistory(); boolean addToHistoryExtendedBolus(ExtendedBolus extendedBolus); boolean addToHistoryTreatment(DetailedBolusInfo detailedBolusInfo); TempTarget getTempTargetFromHistory(long time); - OverlappingIntervals getTempTargetsFromHistory(); + Intervals getTempTargetsFromHistory(); ProfileSwitch getProfileSwitchFromHistory(long time); ProfileIntervals getProfileSwitchesFromHistory(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index 28821e0242..239318a6e4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -23,7 +23,7 @@ import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; import info.nightscout.androidaps.data.PumpEnactResult; @@ -827,7 +827,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getTemporaryBasalsFromHistory() { + public Intervals getTemporaryBasalsFromHistory() { return activeTreatments.getTemporaryBasalsFromHistory(); } @@ -874,7 +874,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getExtendedBolusesFromHistory() { + public Intervals getExtendedBolusesFromHistory() { return activeTreatments.getExtendedBolusesFromHistory(); } @@ -896,7 +896,7 @@ public class ConfigBuilderPlugin implements PluginBase, PumpInterface, Constrain } @Override - public OverlappingIntervals getTempTargetsFromHistory() { + public Intervals getTempTargetsFromHistory() { return activeTreatments.getTempTargetsFromHistory(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java index d7a2c26bc7..6a7f8c0873 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java @@ -8,7 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; -import java.util.Date; import java.util.List; import info.nightscout.androidaps.Config; @@ -19,6 +18,8 @@ import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Iob; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; +import info.nightscout.androidaps.data.Intervals; +import info.nightscout.androidaps.data.NonOverlappingIntervals; import info.nightscout.androidaps.data.OverlappingIntervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; @@ -48,9 +49,9 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { public static IobTotal lastTempBasalsCalculation; public static List treatments; - private static OverlappingIntervals tempBasals = new OverlappingIntervals<>(); - private static OverlappingIntervals extendedBoluses = new OverlappingIntervals<>(); - private static OverlappingIntervals tempTargets = new OverlappingIntervals<>(); + private static Intervals tempBasals = new NonOverlappingIntervals(); + private static Intervals extendedBoluses = new NonOverlappingIntervals(); + private static Intervals tempTargets = new OverlappingIntervals(); private static ProfileIntervals profiles = new ProfileIntervals<>(); private static boolean fragmentEnabled = true; @@ -347,7 +348,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public OverlappingIntervals getExtendedBolusesFromHistory() { + public Intervals getExtendedBolusesFromHistory() { return extendedBoluses; } @@ -380,7 +381,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public OverlappingIntervals getTemporaryBasalsFromHistory() { + public Intervals getTemporaryBasalsFromHistory() { return tempBasals; } @@ -442,7 +443,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { } @Override - public OverlappingIntervals getTempTargetsFromHistory() { + public Intervals getTempTargetsFromHistory() { return tempTargets; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java index 0acbf4b2c5..ca1cb002f8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java @@ -23,8 +23,6 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; @@ -35,7 +33,7 @@ import info.nightscout.androidaps.events.EventNewBG; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; public class TreatmentsExtendedBolusesFragment extends Fragment { @@ -48,9 +46,9 @@ public class TreatmentsExtendedBolusesFragment extends Fragment { public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals extendedBolusList; + Intervals extendedBolusList; - RecyclerViewAdapter(OverlappingIntervals extendedBolusList) { + RecyclerViewAdapter(Intervals extendedBolusList) { this.extendedBolusList = extendedBolusList; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java index 7a74ca4a86..2b3f310b38 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTempTargetFragment.java @@ -26,11 +26,10 @@ import info.nightscout.androidaps.Services.Intents; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventTempTargetChange; -import info.nightscout.androidaps.data.Profile; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; import info.nightscout.utils.SP; /** @@ -47,10 +46,12 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals tempTargetList; + Intervals tempTargetList; + TempTarget currentlyActiveTarget; - RecyclerViewAdapter(OverlappingIntervals TempTargetList) { + RecyclerViewAdapter(Intervals TempTargetList) { this.tempTargetList = TempTargetList; + currentlyActiveTarget = tempTargetList.getValueByInterval(System.currentTimeMillis()); } @Override @@ -81,10 +82,18 @@ public class TreatmentsTempTargetFragment extends Fragment implements View.OnCli holder.reasonLabel.setText(""); holder.reasonColon.setText(""); } - if (tempTarget.isInProgress()) - holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); - else + if (tempTarget.isInProgress()) { + if(tempTarget == currentlyActiveTarget){ + // active as newest + holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorInProgress)); + } else { + // other's that might become active again after the latest (overlapping) is over + holder.date.setTextColor(ContextCompat.getColor(MainApp.instance(), R.color.colorActive)); + } + } + else { holder.date.setTextColor(holder.reasonColon.getCurrentTextColor()); + } holder.remove.setTag(tempTarget); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java index 8db8a9c67b..219e421c49 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java @@ -23,8 +23,6 @@ import com.squareup.otto.Subscribe; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; - import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.IobTotal; @@ -35,7 +33,7 @@ import info.nightscout.androidaps.events.EventTempBasalChange; import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.NSUpload; -import info.nightscout.androidaps.data.OverlappingIntervals; +import info.nightscout.androidaps.data.Intervals; public class TreatmentsTemporaryBasalsFragment extends Fragment { @@ -50,9 +48,9 @@ public class TreatmentsTemporaryBasalsFragment extends Fragment { public class RecyclerViewAdapter extends RecyclerView.Adapter { - OverlappingIntervals tempBasalList; + Intervals tempBasalList; - RecyclerViewAdapter(OverlappingIntervals tempBasalList) { + RecyclerViewAdapter(Intervals tempBasalList) { this.tempBasalList = tempBasalList; }