2011年8月29日 星期一

Cross-platform game engine CloudBox

Cross-platform game engine CloudBox was ported to Android!!!
Now the CloudBox can run in Android or iOS!






2011年6月8日 星期三

[C#] Generic Singleton Pattern

C# singleton pattern with generic.
Why need using generic singleton?
If we use an interface named ISingleton, and provide an Instance property, we must implement in all derived class.
Or we need to provide Instance property in all singleton class.
That is a trouble, so we use generic to solute it
Because singleton need provide private or protected constructor, so we can't use new T() in generic singleton pattern.
So we need to use reflection to call constructor.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace DesignPattern
{
public class TSingleton<T> where T : class
{
static object SyncRoot = new object();
static T instance;
public static readonly Type[] EmptyTypes = new Type[0];
public static T Instance
{
get
{
if (instance == null)
{
lock (SyncRoot)
{
if (instance == null)
{
ConstructorInfo ci = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, EmptyTypes, null);
if (ci == null) { throw new InvalidOperationException("class must contain a private constructor"); }
instance = (T)ci.Invoke(null);
//instance = Activator.CreateInstance(typeof(T)) as T;
}
}
}
return instance;
}
}
}
}

[iPhone] print all keys/values in info.plist

// get all keys and values in info.plist
NSBundle* mainBundle = [NSBundle mainBundle];
NSDictionary* infoDictionary = [mainBundle infoDictionary];
id key;
NSArray* keys = [infoDictionary allKeys];
NSLog(@"Display all keys and values in info.plist\n");
for(key in keys)
{
NSLog(@"key=%@ , value=%@\n",key,[infoDictionary objectForKey:key]);
}

2011年3月11日 星期五

[C#] Multi-thread delete file sample

just boring..

using
System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO;

namespace WPFTest
{
class Range
{
int m_start;
int m_end;
public Range(int start,int end)
{
m_start = start;
m_end = end;
}
public int Start
{
get { return m_start; }
set { m_start = value; }
}
public int End
{
get { return m_end; }
set { m_end = value; }
}
}

class Orz
{
List<string> m_delNameList;
List<Range> m_RangeList;
int m_threadCount;
Orz(){}
public Orz(List<string> delList,int threadCount)
{
m_delNameList = delList;
m_threadCount = threadCount;
m_RangeList = new List<Range>();
}
public void Start()
{
int count = m_delNameList.Count / m_threadCount;
for(int i = 0; i < m_threadCount ; i++)
{
Thread t = new Thread(new ThreadStart(DeleteProc));
t.Name = i.ToString();
m_RangeList.Add(new Range(i * count, (i + 1) * count));
t.Start();
}
}

void DeleteProc()
{
int index = Convert.ToInt32(Thread.CurrentThread.Name);
Range range = m_RangeList[index];
for (int i = range.Start; i < (index == m_threadCount-1 ? m_delNameList.Count : range.End); i++)
{
File.Delete(m_delNameList[i]);
}
}
}
}