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;
}
}
}
Home Lab
Saturday, January 7, 2017
InvokeCommandAction passing in EventArgs
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;
}
Subscribe to:
Comments (Atom)