31. January 2009 by Mads

The other day I were reading some great articles about creating a game step-by-step by Joel Neubeck. I looked at the source code and saw that he were placing his sprites different then what I have seen before. I wrote a comment to Joel on his blog. You can read it here.

Untill now I have only seen samples, and have also only done it this way myself, of placing sprites using a Canvas and the attached properties Canvas.Left and Canvas.Top. This have worked fine for others and for me.

By looking at Joels source code I saw that he were using a Grid as his container to hold his sprites and the a TranslateTransform to place them on the Grid.

Well, I know, the outcome is the same, but it made me think if there actually were a performance difference. So I desided to do a little test my self. I build two small Silverlight applications, both with the same content - balls bouncing around. One is using a Grid as the container and the other a Canvas.

image

You can see the samples live here:

Canvas sample

Grid sample

You can download the source code from here.

To me they look exactly the same. As you can see, if you run Firefox, that I have enabled the FrameRateCounter and have set the mas framerate to 9999. On my computer these are pretty much the same all the time. In Chrome I can see the memory useage of the silverlight plugin and that seems to be the same as well.

  • So, are they actually performing the same or am I testing this the wrong way?
  • Do you have any better way of testing this?
  • Does it perform differently on your computer?

Please let me know, as I think this is very good to know for all us game developers :)

20. January 2009 by Mads

Watch it LIVE right now at: http://www.pic2009.org/page/content/live

Guess alot of people are watching, but it runs smooth, well done Silverlight.

14. January 2009 by Mads

This post is about the unlocking process of a iPhone 3G from Telia in Denmark. It's about the legal unlocking process that you have the right to in Denmark after 6 months. The post will be in danish.

UPDATE: Der skete en fejl på min server her sidst på dagen, faktisk en fejl-40 :(. Det resulterede desværre i at alle kommentarer på mit nyeste indlæg, dvs. det her er væk. Jeg beklager.

Så kom 6 måneders dagen for den aften/nat vi var nogle der lå i kø på Strøget i København for at få en sort plastik dims kaldet en iPhone 3G.

Jeg ringede igår (12.01.2009) til Telia for at høre om jeg kunne få min iPhone unlocked da jeg mente det måtte være ved at være tid. Han oplyste at det "idag" (12.01.2009) var dagen hvor bindingen udløb, hvilket gjorde at jeg ville kunne få min mobil låst op, gratis, imorgen(13.01.2009). Så jeg måtte vente. Begrundelsen for hvorfor d. først kunne låses op fra d. 13.01.2009, var at bindingen udløb d. 12.01.2009 og jeg derfor kunne få den låst op dagen efter.

Idag ringede jeg så der ind igen. Jeg skulle oplyse mit IMEI nummer, som findes ved at gå ind i Indstillinger -> Generelt -> Om. Personen i kunde service fortalte mig at jeg skulle gå hjem og gendanne min iPhone via iTunes og så skulle det fungere. Hun gjorde opmærksom på at alle data ville gå tabt, disse kan dog genskabes med den indbyggede backup i iTunes. Derudover fortalte hun at det først ville virke om et par timer. Jeg var alligevel på arbejde så det passede mig fint, da jeg alligevel først var hjemme om aftenen.

Et par minutter efter jeg havde snakket med kunde service fik jeg følgende SMS.

clip_image002

Da jeg kom hjem satte jeg iPhonen til iTunes og gjorde som der stod i SMS'en og som hun havde sagt i kunde service. Her er lidt screens.

clip_image004

clip_image006

Jeg har pin kode på mit SIM kort, så denne var reel nok, selvom jeg dog lige hurtigt tænkte "F***!!!" da jeg så "error" billedet. Det er det sidste man har lyst til at se når man gendanner/firmware updatere. Jeg tog stikket ud, skrev min pin kode og satte mobilen til iTunes igen.

Efter lidt tid kom følgende billede frem.

clip_image008

Så bliver man glad når man ser dette :)

Efterfølgende skulle jeg gendanne fra den indbyggede backup, som nævnt tidligere. Det er meget nemt, jeg trykkede bare fortsæt på nedenståenden billede.clip_image010

Efter ret langtid var den dog og alt var synkroniseret så min telefon var som før. I hvert fald ser alt ud til at være som det var før, undtaget at mine apps er rykket lidt rundt, men det er til at leve med. Mine kontakter, SMS, kalender, billeder osv. er der præcis som før. Jeg har dog ikke afprøvet den særlig meget efterfølgende, da jeg kun lige har låst den op, men det ser ud til at være iorden.

Jeg har efterfølgende prøvet at sætte min kærestes SIM kort(Telmore) i min iPhone og det ser ud til at virke umiddelbart.

clip_image012

Dog undre det mig lidt at der står TDC Mobil, troede egentlig der skulle stå Telmore? Men lige meget hvad, så står der ikke Telia og det er det vigtigeste lige pt.

Men altså alt i alt, en meget nem og smerte fri oplåstning, dog stadigvæk meget mere besværlig end den normale process som bare klares med at indtaste en kode og en genstart at telefonen. Men så'n vil Steve Jobs åbentbart ikke have det.

Enjoy :)

8. January 2009 by Mads

Microsoft just published the source code for the controls that ships with the Silverlight 2.0 runtime. This means that you can now create your own versions, which means that you can modify them and fix bug (if any) of the real "native" silverlight 2.0 controls.

Sweet!

See more at SilverLite

6. January 2009 by Mads

I just saw Andy Beaulieu's post about dynamically chaging the endpoint for a WCF service. It's a good post, I just wanted to share how I have solved this problem in my current project.

The problem with Andy's solution is that it not that dynamic.

  • What if the schema change (https)?
  • What if the port change in the final distination environment, so you can't use the "Use specific port" like in VS?
  • What if the path/url for the WCF service is different at the distination environment?

These are the problems that Andy's solution don't solve and I actually have in my current project. Well, I have some of them, but my solution here should solve all of the above.

First, besides my solution is able to change the url/endpoint dynamically, it's also able (or actually required) to take the path to the WCF in as a InitParameter. Please note, that we are taking a relative path from the root here. Which means something like /Services/PeopleService.svc. Somethings that start with a /. This tells the browser that we want to start from the root of the current domain.

So besides solving the problems stated above, my solution also shows how you can send in the relative path for the service as a InitParameter. It's not rocket science, but good to know.

Let's start in App.cs

private void Application_Startup(object sender, StartupEventArgs e)
        {
            //Insert InitParams into Global Resources
            foreach (string key in e.InitParams.Keys)
            {
                this.Resources.Add(key, e.InitParams[key]);
            }

            this.RootVisual = new Page();
        }

We start out by taking all the potential InitParams and put them into the global Resources for the application. You could also just pass the Dictionary to the Page class, but I'll do it like this in this case as I need to access the resources from different places in the application.

If we look in the web project in the HTML we see how and what we pass in here: Default.aspx

<asp:Silverlight ID="Xaml1" runat="server" 
Source="~/ClientBin/Dummy_WCF_Application.xap" 
MinimumVersion="2.0.31005.0" Width="100%" Height="100%"
InitParameters="DummyServicePath=/Services/DummyWCFService.svc" />

Ok, so now we have the initparams inside our silverlight application inside the resources. Let's use it to set the endpoint of our application. This can be done anywhere you like, in my case I just have a DataProvider class and this is where my code is: DataProvider.cs

I applogize up front for the code looking a little wierd. I had to press the code together and on new lines where it isn't logical or correct. It's only for the code to be able to fit to the width of the page here.

public class DataProvider
    {
        public event EventHandler<DataResult> GetDataCompleted;

        private WCFServiceClassName service;
        private const string DummyServicePathKeyName = "DummyServicePath";

        public DataProvider()
        {
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            EndpointAddress endpointAddress;

            if (App.Current.Resources.Contains(DummyServicePathKeyName )
                && !String.IsNullOrEmpty
(App.Current.Resources[DummyServicePathKeyName ] as string)) { string relativePath =
App.Current.Resources[DummyServicePathKeyName ] as string; string completePath = App.Current.Host.Source.Scheme
+ "://" + App.Current.Host.Source.Host + ":" + App.Current.Host.Source.Port + relativePath; endpointAddress = new EndpointAddress(completePath); service = new ChannelFactory<WCFServiceClassName>
(basicHttpBinding, endpointAddress).CreateChannel(); } else throw new Exception("Missing init param named: \"" + MapServicePathKeyName
+ "\" which is a relative Url to the WCF service."); } }

This is not a completely working sample, as I have removed curtain things to keep it simple. The most important part if the code above is actually this:

string relativePath = App.Current.Resources[DummyServicePathKeyName] as string;
string completePath = App.Current.Host.Source.Scheme 
+ "://" + App.Current.Host.Source.Host + ":" + App.Current.Host.Source.Port + relativePath;

Here we create the actual complete url used to access to WCF service with.

App.Current.Host.Source.Scheme: Returns https or http

App.Current.Host.Source.Host: Returns the host ex. "laumania.net" or "silverlight.laumania.net" if you were on a subdomain.

App.Current.Host.Source.Port: Returns the port number, typically 80, but could be anything actually. If the scheme were https the port would normally be 443 etc.

The code above would generate a url, if ran on this actual page:

http://laumania.net:80/Services/DummyWCFService.svc (The link wouldn't work here, as I don't have that service :) )

Now you should be able to make your own WCF service that you can change the endpoint of, in code.

Please let me say that Andy's solution isn't wrong and it will work just fine in most scenarios, it's just different than mine, so I wanted to share this solution too. Hope you find it usefull, maybe in combination with Andy's?

Enjoy!