2010年12月29日 星期三

[iPhone] Toilet War coming soon!!

New game Toilet War coming soon!
Producer & Director: TS Huang
Architect & Chief programmer: Cloud Hsu
Programmer: Joe Huang
Arts:
FLYKING
PAPALA
SAKANA
Music & Sound: JungMusic
Translator: Charles Chung
Special Thanks
B.B.
MingJen
DGW





2010年12月2日 星期四

[IPhone] Send SMS sample with IPhone

Introduction

I will demo some sample to present how to send SMS in iphone programming.

Sample 1

The easiest way is this demo.

[[UIApplication sharedApplication] openURL: @"sms:12345678"];



HTML links:  
<a href="sms:" mce_href="sms:">Launch Text Application</a>
<a href="sms:1-408-555-1212" mce_href="sms:1-408-555-1212">New SMS Message</a>

Native application URL strings:

sms:
sms:1-408-555-1212



Sample 2

We can use MessageUI Framework and MFMessageComposeViewController to send SMS.

-(IBAction) sendInAppSMS:(id) sender
{
MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
controller.body = @"Hello from Mugunth";
controller.recipients = [NSArray arrayWithObjects:@"12345678", @"87654321", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
}


You have to handle a callback method of MFMessageComposeViewControllerDelegate so as to dismiss the modal view controller.


- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result) {
case MessageComposeResultCancelled:
NSLog(@"Cancelled");
break;
case MessageComposeResultFailed:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"MyApp" message:@"Unknown Error"
delegate:self cancelButtonTitle:@”OK” otherButtonTitles: nil];
[alert show];
[alert release];
break;
case MessageComposeResultSent:

break;
default:
break;
}

[self dismissModalViewControllerAnimated:YES];
}




Sample 3

This is a full sample code for MFMessageComposeViewController.


//  SMS2ViewController.h
// SMS2
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMessageComposeViewController.h>
@interface SMS2ViewController : UIViewController <MFMessageComposeViewControllerDelegate>
{
UILabel *message;
}
@property (nonatomic, retain) UILabel *message;
-(void)displayComposerSheet;
@end



//  SMS2ViewController.m
// SMS2
#import "SMS2ViewController.h"
@implementation SMS2ViewController
@synthesize message;
/*
// The designated initializer.
Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
{
// Custom initialization
}
return self;
}
*/
// Implement loadView to create a view hierarchy programmatically, without using a nib.
/*
- (void)loadView
{
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *smsButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
smsButton.frame = CGRectMake(97.0, 301.0, 125.0, 37.0);
smsButton.adjustsImageWhenDisabled = YES;
[smsButton setTitle:@" Send SMS" forState:UIControlStateNormal];
[smsButton setTitleColor:[UIColor colorWithWhite:0.000 alpha:1.000] forState:UIControlStateNormal];
[smsButton setTitleShadowColor:[UIColor colorWithWhite:0.000 alpha:1.000] forState:UIControlStateNormal];
[smsButton addTarget:self action:@selector(displayComposerSheet) forControlEvents:UIControlEventTouchUpInside];
message = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 360.0, 280.0, 29.0)];
message.frame = CGRectMake(20.0, 360.0, 280.0, 29.0);
message.adjustsFontSizeToFitWidth = YES;
message.hidden = YES;
message.text = @"";
message.userInteractionEnabled = NO;
[self.view addSubview:smsButton];
[self.view addSubview:message];
}
-(void)displayComposerSheet
{
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
icker.messageComposeDelegate = self;
picker.recipients = [NSArray arrayWithObject:@"123456789"];
// your recipient number or self for testing
picker.body = @"test from OS4";
[self presentModalViewController:picker animated:YES];
[picker release];
NSLog(@"SMS fired");
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
message.hidden = NO;\
switch (result)
{
case MessageComposeResultCancelled:
message.text = @"Result: canceled";
NSLog(@"Result: canceled");
break;
case MessageComposeResultSent:
message.text = @"Result: sent";
NSLog(@"Result: sent");
break;
case MessageComposeResultFailed:
message.text = @"Result: failed";
NSLog(@"Result: failed");
break;
default:
message.text = @"Result: not sent";
NSLog(@"Result: not sent");
break;
}
[self dismissModalViewControllerAnimated:YES];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc
{
[super dealloc];
}
@end

2010年11月28日 星期日

[IPhone] Remind to rank/review sample code

Introduction

How can we remind user to review or rank in App?
We can show a alert box to remind user to review, I writed a sample code using singleton to remind user.

How to use

[[CloudReview sharedReview]reviewFor:395519376];

CloudReview.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface CloudReview : NSObject {
int m_appleID;
}

+(CloudReview*)sharedReview;
-(void) reviewFor:(int)appleID;
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;

@end


CloudReview.m
#import "CloudReview.h"


@implementation CloudReview

static CloudReview* _sharedReview = nil;

+(CloudReview*)sharedReview
{
@synchronized([CloudReview class])
{
if (!_sharedReview)
[[self alloc] init];

return _sharedReview;
}

return nil;
}

+(id)alloc
{
@synchronized([CloudReview class])
{
NSAssert(_sharedReview == nil, @"Attempted to allocate a second instance of a singleton.");
_sharedReview = [super alloc];
return _sharedReview;
}

return nil;
}

-(void)reviewFor:(int)appleID
{
m_appleID = appleID;
BOOL neverRate = [[NSUserDefaults standardUserDefaults] boolForKey:@"neverRate"];
if(neverRate != YES) {
//Show alert here
UIAlertView *alert;
alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"rate_title",@"Rate My Appication")
message:NSLocalizedString(@"rate_main",@"Please Rate my Application")
delegate: self
cancelButtonTitle:NSLocalizedString(@"rate_cancel",@"Cancel")
otherButtonTitles: NSLocalizedString(@"rate_now",@"Rate Now"),
NSLocalizedString(@"rate_never",@"Never Rate"), nil];
[alert show];
[alert release];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// Never Review Button
if (buttonIndex == 2)
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"neverRate"];
}
// Review Button
else if (buttonIndex == 1)
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"neverRate"];
NSString *str = [NSString stringWithFormat:
@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%d",
m_appleID ];
NSLog(str);
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
}
}

@end

2010年11月10日 星期三

[Design Pattern] MVC pattern



Model–View–Controller (MVC) is a software architecture,[1] currently considered an architectural pattern used in software engineering. The pattern isolates "domain logic" (the application logic for the user) from the user interface (input and presentation), permitting independent development, testing and maintenance of each (separation of concerns).

The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller). In event-driven systems, the model notifies observers (usually views) when the information changes so that they can react.

The view renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for different purposes. A viewport typically has a one to one correspondence with a display surface and knows how to render to it.

The controller receives input and initiates a response by making calls on model objects. A controller accepts input from the user and instructs the model and viewport to perform actions based on that input.

An MVC application may be a collection of model/view/controller triads, each responsible for a different UI element. The Swing GUI system, for example, models almost all interface components as individual MVC systems.

MVC is often seen in web applications where the view is the HTML or XHTML generated by the app. The controller receives GET or POST input and decides what to do with it, handing over to domain objects (i.e. the model) which contain the business rules and know how to carry out specific tasks such as processing a new subscription, and which hand control to (X)HTML-generating components such as templating engines, XML pipelines, AJAX callbacks, etc.

The model is not a database: the 'model' in MVC is both the data and the business/domain logic needed to manipulate the data in the application. Many applications use a persistent storage mechanism such as a database to store data. MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the model. Models are not data access objects; however, in very simple apps that have little domain logic there is no real distinction to be made. Active Record is an accepted design pattern which merges domain logic and data access code - a model which knows how to persist itself.

[Design Pattern] Facade Pattern


The facade pattern is a software engineering design pattern commonly used with Object-oriented programming. (The name is by analogy to an architectural facade.)

A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:

make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;
make code that uses the library more readable, for the same reason;
reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;
wrap a poorly-designed collection of APIs with a single well-designed API (as per task needs).


2010年10月28日 星期四

[IPhone] Fight Bingo Lite V1.0

Category top free 100 in 15 countries.
In Taiwan, Fight Bingo Lite got top 7.
Thank you very much.^^



The Fight Bingo Lite was on sales.
Simple AI with Lite version.

http://itunes.apple.com/us/app/fight-bingo-lite/id399638337?mt=8



2010年10月18日 星期一

[iPhone] Bingo Fight v1.1 update

V1.1.1 will fix this bug.
V1.1.1 was already in review.
Bug report:
Found a bug, when palyer won then click new game.
Touch board could not response.
Click new game again will fix it.
I will fix thisbug at next version.
Thanks very much.

Bingo Fight update to v1.1
1. Add fighter's fighting animation.
2. You can see two people fight with fire ball.

download link

Promotional Codes:
A6RWM3MHJNTR
69W36JX3MPM6
EAM3W9WJ93LL
ENNFXJ4PMH67
JL7MP3R3N4J6
JR673LW63L7W
9EA3EW3KXR33
9ENKF3XAE4FY
TWK6WXX9RHKN
LNAF6EKKMFEM







2010年10月6日 星期三

[IPhone] My first iphone app(Bingo Fight)

It's my first one Iphone Game (Bingo Fight) on sale now. The idea is from an Bingo Game that I made,
just simple rules that just get five lines to win.
Download with the link if interested as a treat to me for drinking.

Thanks Page Huang to support.

How to Play:
You must touch Left Board with number, then computer will cohice a number.
Five numbers to get a line.
If you get five lines first, you will win the game.

Promotional Codes:
X3KPAT9R4HA7
PH9KT3L4LEAY
TEMMW94ML4MA
NF7FHRYJ4YXJ
7ETX9TJ6RXHK

download link










2010年9月7日 星期二

[C++] Hex string convert to integer with stringstream

Sometimes we need to convert hex string to integer.
Usually we will use this alrorithm.
char xtod(char c) {
if (c>='0' && c<='9') return c-'0';
if (c>='A' && c<='F') return c-'A'+10;
if (c>='a' && c<='f') return c-'a'+10;
return c=0; // not Hex digit
}
This is a conventional usage.
Tonight I found a question in CSDN, then I try to found a better solution.
In stackoverflow, I found this answer.
It is very nice.
#include <sstream>
#include <iostream>

int main() {
unsigned int x;
std::stringstream ss;
ss << std::hex << "FF";
ss >> x;
// output it as a signed type
std::cout << static_cast<int>(x) << std::endl;
}

2010年8月20日 星期五

[C] OOP in C sample

Because I got a job, it was a C project.
So I am learning how to implement OOP in C now.
This is a example searched form google.
I use Xcode 3.2.3 with gcc4.2 to implement and test it.


#include <stdio.h>
#include <stdlib.h>

typedef void (*Walk_Fun)(struct Animal *a_This);
typedef struct Animal * (*Dtor_Fun)(struct Animal *a_This);

typedef struct _Animal_Vtable{
Walk_Fun Walk;
Dtor_Fun Dtor;
}Animal_Vtable;

typedef struct _Animal{
Animal_Vtable vtable;

char *Name;
}Animal;

typedef struct _Dog{
Animal_Vtable vtable;

char *Name; // mirror member variables for easy access
char *Type;
}Dog;

void Animal_Walk(Animal *a_This){
printf("Animal (%s) walking\n", a_This->Name);
}

struct Animal* Animal_Dtor(struct Animal *a_This){
printf("animal::dtor\n");
return a_This;
}

Animal *Animal_Alloc(){
return (Animal*)malloc(sizeof(Animal));
}

Animal *Animal_New(Animal *a_Animal){
a_Animal->vtable.Walk = Animal_Walk;
a_Animal->vtable.Dtor = Animal_Dtor;
a_Animal->Name = "Anonymous";
return a_Animal;
}

void Animal_Free(Animal *a_This){
a_This->vtable.Dtor(a_This);

free(a_This);
}

void Dog_Walk(Dog *a_This){
printf("Dog walking %s (%s)\n", a_This->Type, a_This->Name);
}

Dog* Dog_Dtor(Dog *a_This){
// explicit call to parent destructor
Animal_Dtor((Animal*)a_This);

printf("dog::dtor\n");

return a_This;
}

Dog *Dog_Alloc(){
return (Dog*)malloc(sizeof(Dog));
}

Dog *Dog_New(Dog *a_Dog){
// explict call to parent constructor
Animal_New((Animal*)a_Dog);

a_Dog->Type = "Dog type";
a_Dog->vtable.Walk = (Walk_Fun) Dog_Walk;
a_Dog->vtable.Dtor = (Dtor_Fun) Dog_Dtor;

return a_Dog;
}


int main (int argc, const char * argv[]) {
/*
base class:
Animal *a_Animal = Animal_New(Animal_Alloc());
*/
Animal *a_Animal = (Animal*)Dog_New(Dog_Alloc());

a_Animal->vtable.Walk(a_Animal);

Animal_Free(a_Animal);

return 0;
}

2010年8月5日 星期四

[IPhone] How to make iphone automatically distinguish 640 * 960 and 320 * 640 resolution






Using two images named a.png for 480*320 and named a@2x.png for 960*480.
Then use this code.
UIImage* anImage = [UIImage imageNamed:@"a"];

[.NET] How to draw on desktop

This is a demo for draw on desktop.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace DrawDesktop
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
IntPtr hdc = GetDCEx(GetDesktopWindow(), IntPtr.Zero, 1027);
using (Graphics g = Graphics.FromHdc(hdc))
{
g.FillEllipse(Brushes.Red, 0, 0, 400, 400);
}
}

[DllImport("user32.dll")]
static extern IntPtr GetDesktopWindow();

[DllImport("user32.dll")]
static extern IntPtr GetDCEx(IntPtr hwnd, IntPtr hrgn, uint flags);
}
}

2010年7月26日 星期一

[C++] Poker with OOP

Introduction
I found a OOP question from CSND.
That is how to design a OO with Poker.

Source Code


#include <iostream>
#include <vector>
using namespace std;

enum Suit
{
Spade = 0,
Heart,
Diamond,
Club
};

class Poker
{
private:
Suit m_suit;
int m_number;
public:
Poker(Suit suit,int number)
{
m_suit = suit;
m_number = number;
}

string GetSuit()
{
string suit = "Spade";
if(m_suit == Heart)
suit = "Heart";
if(m_suit == Diamond)
suit = "Diamond";
if(m_suit == Club)
suit = "Club";
return suit;
}

friend ostream& operator <<(ostream& os, Poker* pk)
{
string suit = pk->GetSuit();
os << "[" << suit.c_str() << ":" << pk->m_number << "]";
return os;
}
};

class Cards
{
private:
vector<Poker*> m_cards;
public:
Cards()
{
for(int i = 0 ; i < 52 ; i++)
{
m_cards.push_back(new Poker((Suit)(i / 13), (i % 13)+1));
}
}
void Output()
{
vector<Poker*>::iterator iter = m_cards.begin();
for(; iter != m_cards.end() ; iter++)
{
cout<<(Poker*)(*iter)<<endl;
}
}
};

int _tmain(int argc, _TCHAR* argv[])
{
Cards *cards = new Cards();
cards->Output();
int a = 0;
a = cin.get();
return 0;
}

2010年7月20日 星期二

[Game] Develop Game Loop

Introduction
Game is a real-time application.
In the section, I use some image and sample code to explain how to develop game loop.


Background
First, game status need to update in game world.
Secound, game allow interaction with player.
And last, the result need to dislpay for players, whether screen, sound or other outputs.
Game status and player input can consider as a behavior.
So game is as a combination of update and render.



Game Loop


while(!GameEnd)
{
Update();
Render();
}


void Loader()
{
thread t1 = new thread(&Update,1000/frequency);
t1.Start();
thread t2 = new thread(&Render,1000/60);
t2.Start();
}

void Update()
{
// do update
}

void Render()
{
// do render
}



long lastTime = getTimeTick();
while(!GameEnd)
{
if( (getTimeTick() - lastTime) > (1000/frequency) )
{
Update();
lastTime = getTimeTick();
}
Render();
}


First loop, update and render everytime.
When game logic is too complex, it may reduce render's performance.
Secound loop, using multi-thread to update and render.
Last loop, using a timer to record last update time.

2010年7月18日 星期日

[IPhone] Memory management with UIView

Introduction
Memory management in the Iphone is a hot topic.
I might as well share some tips here from my own experience.

Background
I got a game project of iphone at the end of March, 2010.
Then I started to study development in Iphone with Object-C and C++.
I developed a library that named CloudBox and used to develop my project of game.
In the past, I had met many times of crash, the reason was issue of memory management.

Sample 1

    UIImage *tmp = [UIImage imageNamed:@"logo.png"]; // imageNamed will return an autorelease object
bigpicture = [[UIImageView alloc] initWithImage:tmp];
//[tmp release];
// if you release a autorelease object, you application may be crash.
// so it dose not need release
Avoid using autorelease object.
If you use an autorelease object, you can not control when it was released.
And if you release an autorelease object by yourself, sometimes might cause crash.
[NSxxx xxxGenerate] naming function will return an autorelease object, like [UIImage imageNamed] or [NSString stringWithFormat].

Sample 2

class SuccessView
{
private:
UIImageView* m_View;
public:
SuccessView(UIView* parentView);
~SuccessView();
};

SuccessView::SuccessView(UIView* parentView)
{
m_View = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
// after alloc, m_View's retainCount = 1
[parentView addSubView:m_View];
// after addSubView, m_View's retainCount = 2
}

SuccessView::~SuccessView()
{
[m_View removeFromSuperview];
// after removeFromSuperview, m_View's retainCount = 1
[m_View release];
// after release, m_View's retainCount = 0, release success.
}

class CrashView
{
private:
UIImageView* m_View;
public:
CrashView(UIView* parentView);
~CrashView();
};

CrashView::CrashView(UIView* parentView)
{
m_View = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
// after alloc, m_View's retainCount = 1
[parentView addSubView:m_View];
// after addSubView, m_View's retainCount = 2
[m_View release];
// after release, m_View's retainCount = 1
}

CrashView::~CrashView()
{
[m_View release];
// this release may cause application crash.
}

class DemoSample
{
private:
UIView* m_MainView;
SuccessView* success;
CrashView* crash;
public:
DemoSample();
~DemoSample();

void TestRemoveSuccessView();
void TestRemoveCrashView();
};

DemoSample::DemoSample()
{
m_MainView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
success = new SuccessView(m_MainView); // draw success view on m_MainView
crash = new CrashView(m_MainView); // draw crash view on m_MainView
}

DemoSample::~DemoSample()
{
[m_MainView release];
}

void DemoSample::TestRemoveSuccessView()
{
delete success; // it will success to remove this view from m_MainView
}
void DemoSample::TestRemoveCrashView()
{
delete crash; // it will cause crash
}
In develop of game, I used random generate NPC.
If NPC dead, I will remove NPC on screen and release it.
In the past, I got a experience.
When I release UIImageView without removeFromSuperview, the application will crash.
I got some conclusions:
1. view = [UIImageView alloc] => view's retainCount = 1
2. [parentView addSubview:view] => view's retainCount = 2
3. [view removeFromSuperview] => view's retainCount = 1
4. [view release] => view's retainCount = 0

Reference
IPhone Memory Management
IPhone Memory Management Tips
Apple Document

2010年7月15日 星期四

[C++] How to implement property in C++

Introduction

In the past, I used property to develop .NET program frequently.
But in Java or C++, I must use get/set method to access private member in Object-Oriented Programming.
I like to use property not get/set method!

Background

Startand C++ dose not support property statement, so programmers need to declare get/set method to access private member.
First programmers should understand template and function point.
I found a sample code from google, that use template and function point to solve type and access get/set method.
This solution is not good, because use a class and function point to access will reduce performance.
Directly use get/set method is better.

Source Code
template<class _Prop_t,class _ObjClass_t>
class Property
{
private:
typedef _Prop_t (_ObjClass_t::* _pmGet_t)() const;
typedef void (_ObjClass_t::* _pmSet_t)(_Prop_t);

_ObjClass_t& m_objInstance;
_pmGet_t m_pmGet;
_pmSet_t m_pmSet;

public:
Property(_ObjClass_t& objInstance, _pmGet_t pmGet, _pmSet_t pmSet)
: m_objInstance(objInstance), m_pmGet(pmGet), m_pmSet(pmSet)
{}
operator _Prop_t() { return (_Prop_t)(m_objInstance.*m_pmGet)(); }
void operator =(_Prop_t value) { (m_objInstance.*m_pmSet)(value); }
};



Download
Sample Code

2010年7月12日 星期一

[.NET] ArrayList,Hashtable,Dictionary compare

Introduction
Sometime we need to save some const infotmation in Collection(ArrayList/HashTable in .NET Framework), and get some information from an indepentdent id.
Suppose you do not understand the data structure, maybe you will using array or arraylist to save const, then coding search algorithm by yourself.
If your const is excessive, maybe the program performance will be reduce.

Background
In my job, I have a event log manager, a event resource file and a event id definition.
I will load resource file used by event log manager, and the event will be save into an ArrayList object in memory.
Then I will add an event log by event id, the event log manager will return a event log where search from ArrayList everytime.
But in my program, add an event log is a repetitive behavior, so I think that maybe I can use a more efficient solution to improve it.


Comparation



I will use ArrayLit/HashTable/Dictionary to compare the search algorithm's performance.

I will test it on Windows XP and Windows CE 5.0 Emulator.
I have 2048 event log and these are non-continuous data.
private void btnArrayList_Click(object sender, EventArgs e)
{
int t_ulStartTime = AccurateTimer.GetTimeTick();
for (int i = 1000; i < 42880; i++)
{
m_event.AddEventLogWithArrayList(i);
}
int t_ulEndTime = AccurateTimer.GetTimeTick();
double t_r8PassedTime = (double)(t_ulEndTime - t_ulStartTime) / (double)1000.0;
MessageBox.Show("ArrayList spend time:" + t_r8PassedTime);
}

private void btnHashTable_Click(object sender, EventArgs e)
{
int t_ulStartTime = AccurateTimer.GetTimeTick();
for (int i = 1000; i < 42880; i++)
{
m_event.AddEventLogWithHashtable(i);
}
int t_ulEndTime = AccurateTimer.GetTimeTick();
double t_r8PassedTime = (double)(t_ulEndTime - t_ulStartTime) / (double)1000.0;
MessageBox.Show("Hashtable spend time:" + t_r8PassedTime);
}

private void btnDictionary_Click(object sender, EventArgs e)
{
int t_ulStartTime = AccurateTimer.GetTimeTick();
for (int i = 1000; i < 42880; i++)
{
m_event.AddEventLogWithDictionary(i);
}
int t_ulEndTime = AccurateTimer.GetTimeTick();
double t_r8PassedTime = (double)(t_ulEndTime - t_ulStartTime) / (double)1000.0;
MessageBox.Show("Dictionary spend time:" + t_r8PassedTime);
}




In my test, I found Hashtable's performance is best.
And I found the Hashtable is better then Dictionary.
If key is not exist in Dictionary, it will throw a System.Collections.Generic.KeyNotFoundException.
It will reduce the program's performance, and the generic in C# without a good performance, so I don't use it.

Reference

An Extensive Examination of Data Structures Using C# 2.0
Sample Code:Test Hashtable and ArrayList

2010年7月4日 星期日

[.NET] How to implement rotate image in user control.

Introduction
Sometimes we need to rotate image in user control.
I override OnPaint method, and use Graphics.RotateTransform to rotate image.

Source Code
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.Default;
Rectangle rect=new Rectangle(0,0,this.Width,this.Height);
PointF center=new PointF(rect.Width/2,rect.Height/2);

float offsetX=0;
float offsetY=0;
offsetX = center.X - DoorWidth / 2;
offsetY = center.Y - DoorHeight / 2;
picRect = new RectangleF(offsetX, offsetY, DoorWidth, DoorHeight);
PointF Pcenter=new PointF(picRect.X+picRect.Width/2,
picRect.Y+picRect.Height/2);

e.Graphics.TranslateTransform(Pcenter.X, Pcenter.Y);
e.Graphics.RotateTransform(-m_i4Angle);

e.Graphics.TranslateTransform(-Pcenter.X, -Pcenter.Y);
if (m_bIsOpened)
{
int t_i4doorWidth = (DoorWidth - DoorOpenWidth) / 2;
RectangleF picRect1 = new RectangleF(offsetX, offsetY, t_i4doorWidth, DoorHeight);
e.Graphics.FillRectangle(new SolidBrush(m_OpenColor), picRect1);
RectangleF picRect2 = new RectangleF(offsetX + DoorOpenWidth + t_i4doorWidth, offsetY, t_i4doorWidth, DoorHeight);
e.Graphics.FillRectangle(new SolidBrush(m_OpenColor), picRect2);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(m_CloseColor), picRect);
}
e.Graphics.ResetTransform();
}



Image

2010年6月27日 星期日

[.NET] How to create unit test with Visual Studio 2005

Introduction
If we want to do unit test, we can use Visual Studio Test Project to implement it.
And Visual Studio give us a very easy tool to implement unit test.
This article will demo it.

How to create Unit Test

First, we need to create a dll project, I named XDXD.
And create class XDXD and implement this class.


Then use Test Project to Add a new Unit Test.

The wizard will dispaly XDXD class's properties and methods.

Check XDXD class then click OK.




Visual Studio will create a XDXDTest.cs file and generate Unit Test code.

[IPhone] Observer with Game Development

Introduction
When I develop my game project. I use a global timer to update game scene, and game scene will update all game roles in game scene if need.
Background
After study observer, I think game scene is a observable and it can notify game role to update.
So I implement observer pattern in my game.

UML


Observer Code

class Observable;
class Observer : public NSObject
{
private:
// --- Add private member --- //
public:
// --- Add public member --- //
Observer();
virtual ~Observer();

virtual void Update() = 0;
};

typedef set<observer*> SET;

class Observable : public NSObject
{
private:
// --- Add private member --- //
SET m_observers;
public:
// --- Add public member --- //
Observable();
virtual~Observable();

void RegisterObserver(Observer *o);
void RemoveObserver(Observer *o);
void NotifyObservers();
};
void Observable::RegisterObserver(Observer *o)
{
m_observers.insert(o);
}
void Observable::RemoveObserver(Observer *o)
{
m_observers.erase(o);
}

void Observable::NotifyObservers()
{
SET::
reverse_iterator index;
SET::
reverse_iterator end = m_observers.rend();
for(index = m_observers.rbegin(); index != end; index++)
{
((Observer*)(*index))->Update();
}
}

2010年6月26日 星期六

[.NET] StackTrace with Exception

When a programmer develop .NET, he can use Exception.StatckTrace to get stack trace information.

Represents a stack trace, which is an ordered collection of one or more stack frames.

MSDN Remark has some information:

StackTrace information will be most informative with Debug build configurations. By default, Debug builds include debug symbols, while Release builds do not. The debug symbols contain most of the file, method name, line number, and column information used in constructing StackFrame and StackTrace objects.

using System;
class Orz
{
public static void Main()
{
try
{
XD();
}
catch( Exception e )
{
Console.WriteLine( "System.Exception stack trace = \n{0}", e.StackTrace );
}
}
static void XD()
{
throw new Exception( "XD() has some error" );
}
}


Output:
System.Exception stack trace =
at Orz.XD()
at Orz.Main()

2010年6月23日 星期三

[IPhone] iphone game develop concept

If we want to develop game on iphone, we must use iphone sdk to control iphone device, see this figure 1.(Reference from Iphone game development)

Game is a state machine, user input data can change state, game state depend on game logic.
Example:
User touch panel to move game role to touch point.



if(role location != touch location)
{
role move to touch location;
}

if(role location == touch location)
{
role stand at touch location;
}


Figure 1.


But I think that user input data is from iphone device(touch panel).


Figure 2.


When implement a game, we will use a Main Loop to update game logic and render game screen. Use HandleEvent to implement user input, update to change game scene and role state, render to update game screen.


void main()
{
while(GAME_PLAY)
{
HandleEvent();
Update();
Render();
}
}


Figure 3.



In my CloudBox, I use UIView and UIImageView to implement game, so my render function is invalid. I use draw to addSubView once.


void main()
{
Draw();
while(GAME_PLAY)
{
HandleEvent();
Update();
//Render();
}
}


Figure 4.