Пример #1
0
 public CuePrompter(MachineLearningActivity <T> .IMachineLearningActivity parentActivity)
 {
     Current = parentActivity;
     //cueEffect = new Effect("Cue sound", Resource.Raw._215028_shing);
 }
Пример #2
0
 public MlrnCuePrompter(MachineLearningActivity <T> parentActivity) : base(parentActivity)
 {
     Current = parentActivity;
 }
Пример #3
0
        //public static FieldState CannotAddNewClass = FieldState.Def("Add", false);
        //public static FieldState CanAddNewClass = FieldState.Def("Add", true);
        //public static FieldState RemoveClass = FieldState.Def("Remove", true);

        public void Update <T>(MachineLearningActivity <T> activity) where T : struct
        {
            // Silently fail if uninitialized (happens particularly during initialization of properties like Dataset)
            if (Save == null)
            {
                return;
            }

            // Prep easily-understood locals
            var Dataset    = activity.Dataset;
            var Classifier = activity.Classifier;

            // Anything for us to load?  This (and only this) doesn't depend on the dataset existing at all.
            bool foundAtLeastOneDataset = false;
            var  externalDir            = parentActivity.GetExternalFilesDir(null).AbsoluteFile;
            var  allFiles = externalDir.ListFiles().ToList();

            if (allFiles.Any(f => f.Name.EndsWith("." + DataSet.FileExtension)))
            {
                foundAtLeastOneDataset = true;
            }
            while (!foundAtLeastOneDataset && allFiles.Any(f => f.IsDirectory))
            {
                var subdir = allFiles.First(f => f.IsDirectory);
                allFiles.Remove(subdir);
                var subfiles = subdir.ListFiles().Select(f => f.AbsoluteFile);
                if (subfiles.Any(f => f.Name.EndsWith("." + DataSet.FileExtension) || f.Name.EndsWith("." + Classifier.FileExtension)))
                {
                    foundAtLeastOneDataset = true;
                    break;
                }
                allFiles.AddRange(subfiles);
            }
            //Log.Debug("FileDirTest", $"Files: {allFiles.Select(f => f.Name).Join()}");
            //foreach (File f in allFiles)
            //    if (f.Name.EndsWith("." + DataSet.FileExtension)) Log.Debug("FileDirTest", $"Including dataset {f.Name}");
            if (foundAtLeastOneDataset)
            {
                Load.State = CanLoad;
            }
            else
            {
                Load.State = CannotLoad;
            }

            if (_guessAndTeach != null)
            {
                _guessAndTeach.Enabled = (Classifier != null && Classifier.MachineOnline);
            }
            if (_cuemode != null)
            {
                _cuemode.Enabled     = (Classifier != null && Classifier.MachineOnline);
                _gimmeCue.Visibility =
                    _repeatCuesCheckbox.Visibility       =
                        _advancedCuesCheckbox.Visibility =
                            (_cuemode.Checked) ? ViewStates.Visible : ViewStates.Gone;
            }
            _newClassName.Text = _newClassName.Text + ""; // Causes it to reassess its "on text changed" event

            // Rapid exit if there is no dataset at all, since the rest of this would be gibberish and throw lots of exceptions.
            if (Dataset == null)
            {
                Save.State          = CannotSave;
                Clear.State         = NothingToClear;
                Compute.State       = CannotCompute;
                ComputeSingle.State = CannotComputeSingle;
                _listview.RequestLayout();
                return;
            }

            // Reference conditions needed through the rest of this process
            bool HasBeenNamed  = Dataset.NameIsUserChosen;
            bool HasClasses    = Dataset.Classes != null && Dataset.Classes.Count > 0;
            bool HasSamples    = Dataset.Samples != null && Dataset.Samples.Count > 0;
            bool HasNewSamples = Dataset.Samples.Any(s => !s.HasContributedToClassifier);

            bool DatasetHasChanged = Dataset.HasChanged;

            Dataset.HasChanged = false; // The "has changed" is "compared to the last time we ran ButtonStates.Update()", so now it's false by definition.

            // ======== Condition logic ===========

            // Does the dataset have a name?
            if (HasBeenNamed)
            {
                DatasetName.State = FieldState.Def(Dataset.Name, true);
            }
            else
            {
                DatasetName.State       = FieldState.Def(null, true);
                DatasetName.Target.Hint = Dataset.Name;
                if (Dataset.SavedAsName != null)
                {
                    if (Dataset.SavedAsName.Contains('/'))
                    {
                        int startIndex = Dataset.SavedAsName.LastIndexOf('/') + 1;
                        int length     = Dataset.SavedAsName.Length - startIndex - DataSet.FileExtension.Length - 1;
                        if (length > 0)
                        {
                            DatasetName.Target.Hint = Dataset.SavedAsName.Substring(startIndex, length);
                        }
                    }
                    else
                    {
                        DatasetName.Target.Hint = Dataset.SavedAsName.Substring(0, Dataset.SavedAsName.Length - DataSet.FileExtension.Length - 1);
                    }
                }
            }

            // Is it empty but for (possibly) a name?
            if (!HasClasses)
            {
                Save.State          = CannotSave;
                Compute.State       = CannotCompute;
                ComputeSingle.State = CannotComputeSingle;
                if (HasBeenNamed || Dataset.SavedAsName != null)
                {
                    Clear.State = IsClearedExceptName;
                }
                else
                {
                    Clear.State = NothingToClear;
                }
            }
            // Does it contain classes, but no actual sample data yet?
            else if (!HasSamples)
            {
                Save.State          = (DatasetHasChanged) ? CanSave : CannotSave; // Allowed to still save even if all it includes is empty gesture classes.
                Compute.State       = CannotCompute;
                ComputeSingle.State = CannotComputeSingle;
                Clear.State         = CanClear;
            }
            // Okay, so it contains meaningful content.  What kind?
            else
            {
                Save.State = CanSave;

                // Note that the case where it has neither new data, nor already analyzed data, is handled above (since it therefore has NO data at all).

                // Maybe it's got new data but never been analyzed...
                if (HasNewSamples && !Classifier.MachineOnline)
                {
                    Compute.State       = (Dataset.Classes.Count > 1) ? CanCompute : CannotCompute;
                    ComputeSingle.State = (Dataset.Classes.Count > 1) ? CanComputeSingle : CannotComputeSingle;
                    Clear.State         = CanClear;
                }
                // Or maybe it's got existing data and a classifier, but no new data...
                else if (!HasNewSamples && Classifier.MachineOnline)
                {
                    Compute.State       = JustComputed;
                    ComputeSingle.State = JustComputed;
                    Clear.State         = CanClear;
                }
                // Or, lastly, maybe it's got both existing data and a classifier to go with them, AND some new data...
                else if (HasNewSamples && Classifier.MachineOnline)
                {
                    Compute.State       = CanRecompute;
                    ComputeSingle.State = CanRecompute;
                    Clear.State         = CanClearNewData;
                }
            }

            //// Lastly, request an update of the list of gesture classes so that their data is up to date as well.
            //_listview.RequestLayout(); // Not sure whether this, or Invalidate(), is the more appropriate.
            //_listview.Invalidate();
            //parentActivity.RunOnUiThread(() =>
            //{
            //    _listview.RequestLayout();
            //    _listview.Invalidate();
            //    parentActivity.FindViewById(Resource.Id.mlrn_latest_sample_display).Invalidate();
            //});
            ((MachineLearningActivity <T> .IMachineLearningActivity)parentActivity).SetUpAdapters(Dataset);
        }