C# – MutableWhen Extension for the Task Parallel Library (TPL)

This is a little playful MutableWhenAny and MutableWhenAll extension for the Task Parallel Library (TPL), using a ObservableCollection.

The extension makes it possible to add or removed tasks to/from an ObservableCollection<Task> while the MutableWhenAny or MutableWhenAll is used to wait on the tasks in this (mutable) collection.

 https://github.com/okmer/MutableWhen

It’s not super useful in practice, but a nice little exercise that combines two cool C# features into a fun asynchronous “magic” trick.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Threading;
using System.Threading.Tasks;
 
namespace Com.Okmer.Extensions.ObservableCollectionOfTask
{
    public static class ObservableCollectionOfTaskExtention
    {
        private const int INFINITE = -1;
 
        public static async Task MutableWhenAll(this ObservableCollection<Task> collection)
        {
            await MutableWhenSomething(collection, Task.WhenAll);
        }
 
        public static async Task MutableWhenAny(this ObservableCollection<Task> collection)
        {
            await MutableWhenSomething(collection, Task.WhenAny);
        }
 
        private static async Task MutableWhenSomething(this ObservableCollection<Task> collection, Func<IEnumerable<Task>, Task> whenSomething)
        {
            Task waitAllTask = null;
            Task helperTask = null;
 
            bool isCollectionChanged = false;
 
            do
            {
                //Cancellation on collection changed event
                var cts = new CancellationTokenSource();
                var cancelActionHandler = (sender, arg) => cts.Cancel(false);
                collection.CollectionChanged += cancelActionHandler;
 
                //Current collection
                waitAllTask = whenSomething(collection);
 
                //Wait on current collection or collection changed event
                try
                {
                    helperTask = Task.Delay(INFINITE, cts.Token);
                    await Task.WhenAny(waitAllTask, helperTask);
                }
                finally
                {
                    isCollectionChanged = cts.IsCancellationRequested;
                    cts.Cancel(false);
                    cts.Dispose();
                    collection.CollectionChanged -= cancelActionHandler;
                }
            }
            while (isCollectionChanged);
 
            //Return the WaitAll on collection results
            await waitAllTask;
        }
    }
}

A simple example application that demonstrates the MutableWhenAll extension on an observable collection of tasks. The longest running task is added to the observable collection after MutableWhenAll is called, but the MutableWhenAll will complete only when all tasks (included this longest running task) are completed.

using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
 
using Com.Okmer.Extensions.ObservableCollectionOfTask;
 
namespace MutableWhenAllTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ObservableCollection<Task> tasks = new ObservableCollection<Task>();
 
            Task t1 = Task.Run(async () => { await Task.Delay(1000); Console.WriteLine("t1"); });
            Task t2 = Task.Run(async () => { await Task.Delay(2000); Console.WriteLine("t2"); });
            Task t3 = Task.Run(async () => { await Task.Delay(3000); Console.WriteLine("t3"); });
 
            tasks.Add(t1);
            tasks.Add(t2);
 
            Task a1 = tasks.MutableWhenAll();
 
            tasks.Add(t3);
 
            a1.ContinueWith(t =>
            {
                if (t.IsCanceled)
                {
                    Console.WriteLine("Canceled");
                }
 
                if (t.IsFaulted)
                {
                    Console.WriteLine("Faulted");
                }
 
                if (t.IsCompleted)
                {
                    Console.WriteLine("Completed");
                }
            });
 
            a1.Wait();
 
            Console.ReadLine();
        }
 
    }
}

C# – DynamicBag playing with Dynamic and Polymorphism

DynamicBag is a toy project that used a Dictionary<string, dynamic> to create a dynamic storage class.

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
 
namespace Com.Okmer.DynamicTypes
{
    [Serializable]
    public class DynamicBag : Dictionary<stringdynamic>
    {
        public DynamicBag() { }
 
        public DynamicBag(int capacity) : base(capacity) { }
 
        public DynamicBag(IDictionary<stringdynamic> dictionary) : base(dictionary) { }
 
        public DynamicBag(SerializationInfo info, StreamingContext context) : base(info, context) { }
 
        public void ToBinaryFile(string fileName)
        {
            BinarySerialization.ToFile(this, fileName);
        }
 
        public static DynamicBag FromBinaryFile(string fileName)
        {
            return BinarySerialization.FromFile<DynamicBag>(fileName);
        }
    }
}

These DynamicBag(s) can be serialized to and deserialized from a file using BinarySerialization.

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace Com.Okmer.DynamicTypes
{
    public static class BinarySerialization
    {
        public static void ToFile<T>(T value, string fileName) where T : ISerializable
        {
            IFormatter formatter = new BinaryFormatter();
            using (Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                formatter.Serialize(stream, value);
            }
        }
 
        public static T FromFile<T>(string fileName) where T : ISerializablenew()
        {
            T result = new T();
            IFormatter formatter = new BinaryFormatter();
            using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                result = (T)formatter.Deserialize(stream);
            }
            return result;
        }
    }
}

The simple example application uses polymorphism to print the content of the DynamicBag(s) to the console.

using System;
using System.Collections.Generic;
 
using Com.Okmer.DynamicTypes;
 
namespace SampleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            DynamicBag shoppingBag = new DynamicBag();
            DynamicBag spareBag = new DynamicBag();
 
            shoppingBag.Add("spareBag", spareBag);
            shoppingBag.Add("shoppingList"new string[] { "eggs""milk""cheese" });
 
            spareBag.Add("carCoin""50ct");
            spareBag.Add("carValue", 50);
 
            Print(shoppingBag);
 
            Console.Write("---------------------------> ENTER <----: ");
            Console.ReadLine();
 
            shoppingBag.ToBinaryFile("shoppingBag.bin");
 
            DynamicBag shoppingBagFromBinaryFile = DynamicBag.FromBinaryFile("shoppingBag.bin");
 
            Print(shoppingBagFromBinaryFile);
 
            Console.Write("---------------------------> ENTER <----: ");
            Console.ReadLine();
        }
 
        private static void Print(DynamicBag bag)
        {
            Console.WriteLine("BAG BEGIN");
            foreach (string key in bag.Keys)
            {
                Console.WriteLine(key + ": ");
                Print(bag[key]);
            }
            Console.WriteLine("BAG END");
        }
 
        private static void Print(IEnumerable<dynamic> values)
        {
            Console.WriteLine("ENUMERABLE BEGIN");
            foreach (dynamic value in values)
            {
                Print(value);
            }
            Console.WriteLine("ENUMERABLE END");
        }
 
        private static void Print(bool value) => Console.WriteLine("bool -> " + value.ToString());
 
        private static void Print(int value) => Console.WriteLine("int -> " + value.ToString());
 
        private static void Print(double value) => Console.WriteLine("double -> " + value.ToString());
 
        private static void Print(string value) => Console.WriteLine("string -> " + value.ToString());
 
        private static void Print(object value) => Console.WriteLine("object-> " + value.ToString());
    }
}

InnoFaith – 3D.js front-end for embedded devices

SVG vector bases, touchscreen enabled, animated, and 3D.js driven front-end, running on an “embedded” Raspberry-Pi that is sampling 21 USB connected skin moisture sensors (each containing an array of 256×300 sample points).

3D.js SVG front-end data visualisation

The system is running battery power in a bag pack, carried by the human test subject. De system is hosting a live measurement data as a web service using a Wifi AP hosted by WiFi USB dongle connected to the Raspberry Pi, in connection with the 21 USB connected skin moisture sensors.

3D.js SVG front-end status visualisation

System status (including the external battery) can also be monitored through the same web interface (running fullscreen on a iPad).

EvilDir, create an EVIL named directory in Windows

A little “fun” Qt5 console application to create a directory (a.k.a. folder) ending with a space character (” “). This directory can not be removed with standard Windows tools, including most console applications.

#include <QCoreApplication>
#include <QDir>

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);

  QString evil_dir_name("Remko is a little Evil !!! ");

  for(int i=1; i<a.arguments().count(); i++)
  {
    if(a.arguments().at(i).compare("-d", Qt::CaseInsensitive) != 0)
    {
      evil_dir_name = a.arguments().at(i);
      evil_dir_name.append(" ");
      break;
    }
  }

  if(a.arguments().contains("-d"))
  {
    if(QDir(evil_dir_name).exists())
    {
      QDir().rmdir(evil_dir_name);
    }
  }
  else
  {
    QDir().mkdir(evil_dir_name);
  }
 
  return 0;
}

InnoFaith – OBSERV 520 iOS App

The skin diagnostics suite bundled with the OBSERV 520. This iPad based skin diagnostics suite uses the Bluetooth 4.0 Low Energy (BLE) to communicate with the OBSERV 520 by Sylton, and uses the iPad camera in combination with GPU accelerated image filters to visualise a broad range of skin concerns.

Overview of the OBSERV 520 iOS App

App Store link: https://itunes.apple.com/us/app/observ-520/id781554722

Sylton (InnoFaith) product information: https://sylton.com/products

InnoFaith – AVEAL 210/220 iOS App

Skin care consultation suite for Point-of-Sale applications using the AVEAL 210/220. An iPad based skin care consultation suite, that combines questioners and measurements (using a bluetooth connected MFi+iAP measurement device), to provide an end-user with a skin type description. The goal is to provide a smooth and fast interface, with intuitive data visualisations.

App Store link: https://itunes.apple.com/us/app/aveal/id674486824

Sylton (InnoFaith) product information: https://www.sylton.com

Color Picker 1.1

I build a simple Color Picker 1.1 application that samples the pixel color under the mouse cursor point (because I needed it). The application is a stand alone (static build) Qt5 application with some minor Win32 API stuff, to sample the color at the cursor position.

ColorPicker 1.1

The application supports a number of RGB based color formats and formating formats. The application can run in the background, and used the CTRL+1, CTRL+2, and CTRL+3 hotkey combinations to sample a color in one of its three sample slots. The CTRL+SHIFT+1, CTRL+SHIFT+2, and CTRL+SHIFT+3 hotkey combinations can be used to copy the sample slot content to the clibboard. This enables easy copy and paste access to the sampled color values.

Coffee Tray 1.0 App for the iPad

Your relationships with your colleagues is important! Provide some work delight by getting a round of coffee once in a while (or get some colleague to do it for you).

Coffee Tray 1.0 main screen

This application will help you to remember and transport the hot beverage of choice for up-to five colleagues (plus one additional beverage for your self). Make great use of the perfectly flat surface of your own (or the companies) iPad.

Coffee Tray 1.0 icon

The current version provides a width range of hot beverages to choose from:
– Coffee black
– Coffee sugar
– Coffee creamer
– Coffee sugar & cream
– Bean coffee black
– Bean coffee sugar
– Cappuccino
– Cappuccino sugar
– Espresso
– Espresso sugar
– Chocolate
– Chocolate sugar
– Tea
– Tea sugar
– (Hot) Water

Start using the full office environment potential of your iPad today, and download this application!

Coffee Tray 1.0 selection screen

Apples reason to not approve the application for the App Store:
“We found your app encourages behavior that could result in damage to the user’s device, which is not in compliance with the App Store Review Guidelines.

Specifically, your App encourages the user to transport hot liquids on the device.”

InnoFaith – Fingernail curvature reconstruction

A fun little test setup that uses three (cheap) webcams and a (static) line projector, to measure the outline and curvatures of a human fingernail. Resulting in an Bézier curves based 3D model, that approximates the subjects fingernail.

Final test setup with three webcams and a static line projector.
Original ghetto setup using three webcams and a line projector.

A small volume is calibrated for all three cameras (using a simple calibration cube). Making it relatively easy to measure and reconstruct the outlines and curvature of a fingernail in a distinct color.

The line projector is used to add a high contrast reference on the smooth fingernail surface.

Proof of concept prototype.
Proof-of-concept software implementation (Qt5, OpenCV, and OpenGL).

The end goal is to get an low data approximation of the fingernail shape, to produce custom (as in perfect fitting) artificial nails.