Saturday, January 7, 2017

InvokeCommandAction passing in EventArgs


using System;
using System.Linq;
    using System.Reflection;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interactivity;

    /// <summary>
    /// For Trigger action Invoke command, Trigger Action will set Invoke Parameter so the foloowing can pass along EventArgs
    ///<i:EventTrigger EventName="MouseLeftButtonDown">
    ///<invokeActions:InvokeDelegateCommandAction>
    ///    <invokeActions:InvokeDelegateCommandAction.CommandParameter>
    ///        <MultiBinding Converter="">
    ///            <Binding/>
    ///            <Binding Path="InvokeParameter" RelativeSource="{RelativeSource Self}" />
    /// </summary>
    public sealed class InvokeDelegateCommandAction : TriggerAction<DependencyObject>
    {
        private string _commandName;

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

        public object CommandParameter
        {
            get { return GetValue(CommandParameterProperty);}
            set { SetValue(CommandParameterProperty, value);}
        }

        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
            "Command", typeof(ICommand), typeof(InvokeDelegateCommandAction), null);

        public ICommand Command
        {
            get { return (ICommand)this.GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value);}
        }
 
        public static readonly DependencyProperty InvokeParameterProperty = DependencyProperty.Register(
            "InvokeParameter", typeof(object), typeof(InvokeDelegateCommandAction), null);

        public object InvokeParameter
        {
            get { return GetValue(InvokeParameterProperty); }
            set { SetValue(InvokeParameterProperty, value); }
        }

        public string CommandName
        {
            get
            {
                return _commandName;
            }
            set
            {
                if (CommandName != value)
                {
                    _commandName = value;
                }
            }
        }

        protected override void Invoke(object parameter)
        {
            InvokeParameter = parameter;

            if (AssociatedObject == null)
                return;

            var command = ResolveCommand();
            if ((command != null) && command.CanExecute(CommandParameter))
            {
                command.Execute(CommandParameter);
            }
        }

        private ICommand ResolveCommand()
        {
            ICommand command = null;
            if (Command != null)
            {
                return Command;
            }

            var frameworkElement = AssociatedObject as FrameworkElement;
            if (frameworkElement != null)
            {
                var dataContext = frameworkElement.DataContext;
                if (dataContext != null)
                {
                    PropertyInfo commandPropertyInfo = dataContext
                        .GetType()
                        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                        .FirstOrDefault(
                            p =>
                            typeof(ICommand).IsAssignableFrom(p.PropertyType) &&
                            string.Equals(p.Name, CommandName, StringComparison.Ordinal)
                        );

                    if (commandPropertyInfo != null)
                    {
                        command = (ICommand)commandPropertyInfo.GetValue(dataContext, null);
                    }
                }
            }
            return command;
        }
    }
}

Tuesday, December 20, 2016

C++ Unit Test Framework Catch


1. class comparison in REQUIRE need operator == and  toString/template specialization/insertion operator
2. CATCH_TRANSLATE_EXCEPTION customize ex.message

 #define CATCH_CONFIG_MAIN  in stdafx.h

#include "stdafx.h"
#include "c:\__tools\catch.hpp"
#include <ostream>
#include <exception>

 class Book
{
public:
 int Id;
 bool operator==(const Book& b)
 {
  return b.Id == Id;
 }

};

//std::ostream& operator<<(std::ostream& os, Book const& b)
// {
// os << "overloading OS";
// return os;
//};
namespace Catch {
 template<> struct StringMaker<Book> {
  static std::string convert(Book const& value)
  {
   return "String Maker Specialization";
  }
 };

 //std::string toString(Book const& i)
 //{
 // return "to string for Book";
 //}
}
class myException : public std::exception
{
public:
 virtual const char* what() const throw()
 {
  return " my exception";
 }
};

CATCH_TRANSLATE_EXCEPTION(myException& ex)
{
 return ex.what();
}

TEST_CASE("This is a catch test","[Equal][LOG]")
{
 Book b1, b2;
 b1.Id = 90;
 INFO("Start Testing");
 REQUIRE(b1 == b2);
 WARN("One assertion failed");
 REQUIRE_FALSE(1 == 1);

}

TEST_CASE("This is another catch test","[CHK][EXP]")
{
 CHECK_FALSE(1 == 1);
 throw myException();
}



Saturday, December 10, 2016

Compile Time Check IsNullable and IsReferenceType


        public TimeSpan i { get; set; }
        public TimeSpan? j { get; set; }
        public string k { get; set; }
        public Status? Status { get; set; }
        public Data st1 { get; set; }
        public Data? st2 { get; set; }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            
            bool b1 = IsNullable(i);
            bool b2 = IsNullable(j);
            bool b3 = IsNullable(k);
            bool b4 = IsNullable(Status);
            bool b5 = IsNullable(st1);
            bool b6 = IsNullable(st2);
            bool b7 = IsReferenceType(k);
        }
         static bool IsNullable<T>(T t) { return false; }
         static bool IsNullable<T>(T? t) where T : struct { return true; }
         static bool IsReferenceType<T>(T t) where T : class { return true; }
    

    public enum Status
    {
        None,
        Ok,
        Error
    }

    public struct Data
    {

    }

Thursday, December 8, 2016

Shift Operator, ilog2 and test power of 2

(1) shift left of 1 generate all powers of 2.
(2) ilog2 is template specialization.
(3) shift 1 by ilog2(n) will get back n for power of 2 only
(4) compiler say too complex when using recursion for non-template function is_power_of_2

#include "stdafx.h"
#include <iostream>

using namespace std;

template <size_t X>
struct ilog2
{
 enum {value=(1+ilog2<X/2>::value) };
};

template<>
struct ilog2<1> {enum {value=0}; };

template<size_t N>
bool is_pow_of_2()
{
 return ((size_t)1 << ilog2<N>::value == N);
};

int main() {
 
 cout << (1 << 3) << endl; // 8
 cout << (1 << 9) << endl; // 512=2 power 9
 
 cout << ((size_t)1 << ilog2<9>::value == 9) << endl;
 cout << ((size_t)1 << ilog2<512>::value == 512) << endl;
 
 cout << is_pow_of_2<9>() << endl;
 cout << is_pow_of_2<512>() << endl;
 return 0;
}



Wednesday, December 7, 2016

locking, lock free and wait free

locking --- lock_guard + mutex
lock free --- atomic + CAS
wait free --- atomic +fetch_add
ring buffer-- producer makes progress without any wait, so wait-free.


using namespace std;
typedef unsigned long ulong;

ulong _shared = 123UL;
int main() {
 {
  ulong* p=nullptr;  //locking
  *p = _shared;
  mutex M;
  {
   lock_guard<mutex> l(M);
   ++(*p);
  }
 }
 atomic<ulong>* p=0;  //lock free
 *p = _shared;
 ulong xl = p->load(memory_order_relaxed);
 while (!p->compare_exchange_strong(xl, xl + 1, std::memory_order_relaxed)) {}

 p->fetch_add(1, memory_order_relaxed);  //wait free


 // cache line is 64 bytes, ul is 8 bytes, so thread>8=> sit on separate cache line, no sharing faster.

 

 return 0;
}

lock_guard vs shared_lock is exclusive vs. shared in c++14

(1) C++ 14/17 rare write mostly read is Microsoft  ReaderWriter Lock concept.
(2) lock_guard also aware of how many shared lock in effect before exclude locking so some overhead.
(3) shared_lock can try timed 1 ms to see if writing in progress and give up
(4) both lock_guard and shared_lock construct on the same shared_timed_mutex


std::map<std::string, std::string> _map;
std::shared_timed_mutex m;

std::string find_entry(std::string s)
{
 std::shared_lock<std::shared_timed_mutex> guard(m);
 auto it = _map.find(s);
 if (it == _map.end())
 {
  throw runtime_error("not found");
 }
 return it->second;
}
void add_entry(std::string key,::string s)
{
 std::lock_guard<std::shared_timed_mutex> guard(m);
 _map.insert(make_pair(key,s));
}

void do_work_if_get_lock_in_1sec()
{
 shared_lock<shared_timed_mutex> sl(m, std::chrono::seconds(1));
 if (!sl.owns_lock())
  return;
 //do work after getting lock
}

Saturday, December 3, 2016

JSON Tester


#include "stdafx.h"
#include <iostream>
#include "JSONWrapper.hpp"
#include "render.hpp"

using namespace std;

int main() {

 JSONWrapper jw, jw1, jw2;
 //jw.value = true;
 //jw.value = 123.45;
 //jw.value = std::string{ "test" };
 //jw.value = nullptr;

 
 jw1.value = 678.90;
 jw2.value = true;

 JSONArray a{ jw1,jw2 };
 JSONArray b{ jw1,jw2 };
 //jw.value = a;

 JSONObject obj;
 obj.insert(std::pair<string, JSONArray>("k1", a));
 obj["k2"] = b;
 jw.value = obj;
 
 cout << render_json_value(jw.value) << endl;

 return 0;
}