Showing posts with label Technical Logs. Show all posts
Showing posts with label Technical Logs. Show all posts

Thursday, October 14, 2010

REPLACING THE CONTENT MANAGER API: PRELUDE

As I briefly mentioned in one of my previous posts, for a period of time (close to 2 years, now) I have been developing my own API to manage content as a replacement for the one delivered as part of the XNA Framework.

Why? At first I was trying to circumvent the limitations of the latter related to its inability to properly handle the Dispose operation. And while doing so, I realized -when I checked the source code of the original with “Reflector”- that there was room for improvements (with a redesign).

After almost two years of development as part of my own XNA-based videogame engine (being the latter still in endless development), I decided to redesign my content manager as an independent module so that it can be used with XNA without the need to plug my engine (neither in whole nor in part).

I will not release the source code of my API, so in the next installments in this series of articles I will be discussing publicly what my API has to offer, so that anyone can read it, focusing on The-What rather than on The-How; thus, I will be mainly presenting features and results (I do indeed know, yes, “what a bummer!”).

So, what’s coming next? On part 1 (and most likely part 2 also) I will be introducing my API, explaining differences with the built-in one, and after that I will start to talk about obtained results (yes! With numbers, screenshots and such) for the different platforms I tested.

‘till next time,
~Pete

> Link to Spanish version.

Friday, September 10, 2010

GETTING A REFERENCE TO A METHOD-CALLING OBJECT IN C#

Ok, after taking a month off from any blogging activity, I guess is time to catch up and blog again. And I believe there is no better way of doing so than to write an article explaining a way to get a reference to the object that calls a specific method.

For the last two years or so, I have been working hard on a new Content Manager replacement API for the XNA Framework to use on my own “never-ending” game engine (I will blog about this later on). In some early stages of development I found a way to solve this referencing burden that have been creating headaches to many devs, globally (being me, one of them, for a long time).

Although I must admit that at some point on the development cycle of my API I decided to abandon this workaround, after reading one of the articles mentioned by Shawn here (guess which one), I believe it’s a great opportunity to talk about it.

A little history … before founding this solution I tried everything: from attempting to use –with no luck- the info held in StackFrame instances and even delegates to finally “quit” and use a naive approach as passing the caller as a parameter in the signature of an operation. But, then came .NET Framework 3 and extension methods to the rescue!

Please bear with me that the example presented in this article is just a simple one to show how to use it, but believe my words when I say that it can be extended to complex scenarios.

Having said that … if you want to know which object is calling a certain method of a class like (which may or may not be sealed):

  public sealed class MyCalledClass
  {
    internal bool JustReturnTrue(int myParameter)
    {
      return true;
    }
  }

Being the caller, say, a specification of the following class:

  public abstract class MyCallingClass
  {
    public void Print()
    {
      Console.WriteLine("I am the object which is just about to call
         the monitored operation named 'JustReturnTrue' …"
);
    }
  }

Then all you have to do is to implement the following generic extension method for the types you want (in my example, “MyCallingClass”):

  public static class MyExtensionMethod
  {
    public static bool ExecuteOperation<T>
      (this T mycallingClass, int myParameter)
      where T: MyCallingClass
    {
      mycallingClass.Print(); // Replace it with your own stuff.
 
      return new MyCalledClass().JustReturnTrue(myParameter);
    }
  }

The trick here is to design and split assemblies and namespaces in a way that all instances of “MyCallingClass” cannot directly execute the “JustReturnTrue” operation (I leave that task as an exercise to the reader).

But there is one catch to watch closely, though. By doing this you are actually adding one more call (you know that), which is not generally a problem on Windows, but for the XBox 360 and all devices using the Compact Framework, it could turn out to be expensive if used lots of times on intensive or heavy tasks/loops.

But if you really need it when speed is not an issue or for operations where -for example- you need to set owners to something “automagically” behind the scenes and later assess whether an owner calls a restricted operation before executing it, then there you have it!

Just use it wisely …
~Pete

> Link to Spanish version.

Thursday, October 22, 2009

TWO NEW SAMPLES AT XNA CCO

You may be aware of this news, but just in case, I want to mention that two great new samples are now available on the site of XNA Creators Club:

Now, what’s great about them? Glad you’ve asked.

(I) Skinned Model Extension Sample

The first sample shows you how to extend the original Skinned Model sample so that:

  • You can “move” a part of a skinned model independently of an animation sequence (like in this case, the arm and or head),
  • You can position objects relative to a specific bone (in this case, a bat), and
  • You can properly attach bounding geometry to the animated model (in this case, spheres).

The code is a great source of technical knowledge regarding the skinning technique for programmers but, thanks to some minor glitches in the skinned model, they can also learn how cumbersome and picky are the processes of (not only modeling and unwrapping but) rigging, skinning and animating a 3D model, so that it looks ok in each and every (expected) situation before going gold.

First screenshot:

As you can see here, when you move the head one of the vertices remains (almost) still, which means that either it wasn’t attached to the neck's bone at all or, if it was, then its “weights” should be readjusted.

Second screenshot:

It seems that the part of the belt marked above in orange moves along with the hip whilst the rest of the belt moves with the torso. And so, the walking animation, even if it may behave as expected, looks kinda weird.

This is likely not relevant for programmers -being the programming part the only/main purpose of the sample itself, but for indies like me that tend to develop all parts of a game “in solo mode”, its a fabulous example of some of the headaches they are going to deal with on the artistic side of things.

(II) Primitives 3D Sample

The second one presents the set of classes you will need to create a cube, a sphere, a cylinder, a torus and the famous teapot!

These primitives are usually found in most famous modeling apps, among others, like 3D Studio Max or Maya.

You may wonder: why the teapot is considered a primitive? Well, thanks to the type of powerful operations used to create it, procedurally: bezier-curve calculation! Nice one, indeed …

One suggestion for the cylinder:

In case some of you want to create the triangles that conform each cap of the cylinder so that they lay out uniformly around a centered vertex, instead of towards one side -as shown above, then you’ll have to replace the following method in the “CylinderPrimitive” class:

/// <summary>
/// Helper method creates a triangle fan to close the ends of the cylinder.
/// </summary>
void CreateCap( int tessellation, float height, float radius, Vector3 normal )
{
  // Create cap indices.
  for ( int i = 0; i < tessellation - 2; i++ )
  {
    if ( normal.Y > 0 )
    {
      AddIndex( CurrentVertex );
      AddIndex( CurrentVertex + ( i + 1 ) % tessellation );
      AddIndex( CurrentVertex + ( i + 2 ) % tessellation );
    }
    else
    {
      AddIndex( CurrentVertex );
      AddIndex( CurrentVertex + ( i + 2 ) % tessellation );
      AddIndex( CurrentVertex + ( i + 1 ) % tessellation );
    }
  }
 
  // Create cap vertices.
  for ( int i = 0; i < tessellation; i++ )
  {
    Vector3 position = GetCircleVector( i, tessellation ) * radius +
                       normal * height;
 
    AddVertex( position, normal );
  }
}

So that, instead, it looks similar to:

/// <summary>
/// Helper method that creates a cap laying out triangles around a centered vertex.
/// </summary>
void CreateCap( int tessellation, float height, float radius, Vector3 normal )
{
  // Add a vertex in the center of the cap.
  AddVertex( normal * height, normal );
 
  // Create cap indices, taking into account the centered vertex (that is why
  // we use "CurrentVertex - 1" as the first element of the corresponding index).
  for ( int i = 0; i < tessellation; i++ )
  {
    if ( normal.Y > 0 )
    {
      AddIndex( CurrentVertex - 1 );
      AddIndex( CurrentVertex + ( i + 1 ) % tessellation );
      AddIndex( CurrentVertex + ( i + 2 ) % tessellation );
    }
    else
    {
      AddIndex( CurrentVertex - 1 );
      AddIndex( CurrentVertex + ( i + 2 ) % tessellation );
      AddIndex( CurrentVertex + ( i + 1 ) % tessellation );
    }
  }
 
  // Create cap vertices.
  for ( int i = 0; i < tessellation; i++ )
  {
    Vector3 position = GetCircleVector( i, tessellation ) * radius +
                       normal * height;
 
    AddVertex( position, normal );
  }
}

Being the result:

This isn’t critical at all, but for the sake of (better) unwrapping -and even of creating more “sections” (rings) on each cap, programmatically- 2 centered vertices and a few more triangles come in handy without hurting performance.

Code on!
~Pete

 

> Link to Spanish version.

Sunday, July 26, 2009

HOW TO FIX LOCAL ISSUES TO CONNECT YOUR XBOX 360 TO THE XBOX LIVE SERVERS

A few weeks ago I had to reset my router because Windows Vista was giving me problems with my desktop’s wired LAN & WAN connections (note: problem fixed when I upgraded to Windows 7).

The thing is that when I re-configured my router using the file with the last-saved settings, my XBox was having problems when attempting to connect to XBox Live’s channels (both, arcade and indie). In fact, from time to time I used to receive messages saying my connection got lost due to errors 80072741 and so on (as you will see in a moment, I just forgot to persist to disk the proper configuration values of my router. Sigh!).

When that happens, and assuming that the XBox Live Team isn’t working on the servers(testing, updating, etc.), then something wrong must be happening on your side (like in my case).

So, what could be possibly wrong?

  1. Your router is broken,
  2. Your router has a faulty/corrupt firmware,
  3. You’re connecting your XBox 360 using a faulty wire,
  4. Your 360 cannot retrieve a local IP address from the router,
  5. Your router’s firewall is preventing your 360 from connecting to the Internet,
  6. Your router is performing some strict or moderate Network Address Translation tasks (NAT),
  7. You get some weird error messages and or lose connection when playing some games online on multiplayer mode, and
  8. Other connectivity problems.

If one, a few or some of these happened to you, then maybe the following tips could help to solve the issues with your connection. Meaning? No solution guaranteed.

SO USE THESE TIPS AT YOUR OWN RISK!

Now that you were warned, read on carefully …

Your router is broken.

Buy a new one in case it’s not easy or worth repairing. In the meantime you can try to connect directly through your (DSL) modem.

Your router has a faulty/corrupt firmware.

Go to the manufacturer’s support page, download the latest firmware for your router’s model, and update it (first, read your router’s manual to find out how to do the update).

You’re connecting your XBox 360 using a faulty wire.

Just change the latter and try again.

But what if I’m using a wireless connection? Then check your router’s wireless settings, like, say the security method and password.

Your XBox 360 cannot retrieve a local IP address from the router.

First check your network settings on your XBox 360: whether you want to get a dynamic or static IP address, the values for primary and secondary “Domain Name System” (DNS) addresses, the IP address of the gateway, etc.

Now, check on the router the maximum number of connections allowed at the same time. Maybe you are already using all of them.

If the router is currently providing a “Dynamic Host Configuration Protocol” service (DHCP), then any computer, console and or LAN/WAN device may be configured to attempt to get an IP address from the router, dynamically.

This should work fine with your XBox 360 console for supported routers, but in case it doesn’t, just configure the console to get a static IP address.

Which one? Well, simply put, an IP address that you know other systems won’t normally use (for instance, if you have two computers and your console and you are allowing, say, 8 connections, then set the last one as the static one for your console and you’ll probably do just fine).

In order to set a static IP address, on the 360’s Dashboard browse to “System –> Network Settings –> Edit Settings”, and then enter:

  • The static IP address for the console,
  • The Subnet mask (same than the one set in the router),
  • The Gateway IP address,
  • The Primary and Secondary DNS addresses.

Try the connection again, and if everything goes well, your 360 now should have access to the LAN.

Your router’s firewall is preventing your XBox 360 from connecting to the Internet.

Having access to the local network doesn’t mean that the router has also granted access to the Internet. Sometimes, the firewall of your router stops any attempt of your device and or a set of IP addresses to reach the Internet.

If that is the case, then check all security rules set on your router. Most routers allows you to specify either each IP you want to allow access to the Internet, a range of IP addresses and even your devices’ “Media Access Control” addresses (MAC).

Since at home, in my case, the number of devices that connect to the Internet is low, I just specify each MAC address and presto!

It may also happen that Internet access is only available to certain days and hours per day. So you should check those rules, too.

Your router is performing some strict or moderate NAT tasks.

This is one of the most popular issues when an XBox 360 console attempts to establish a secure connection with the XBox Live’s servers.

In short, not all ports and protocols needed to establish an optimal communication are (properly) set.

Ok … uhh … what?

Do the following: test your 360’s connection to the LAN, the Internet and finally Live’s servers, and if you get the result that two out of three work fine, being the latter the one that “partially” fails, then your router’s NAT functionality is not “Open”.

In fact, if that is the case, you can connect to Xbox Live but the connection is not optimal for cases when you want to play, chat, talk and even accept a friend’s invite online.

In order to configure the ports and protocols needed to establish a “sound” connection to the XBox Live services, you either:

  • Place your console in the “demilitarized zone” (DMZ), or
  • Manually configure the specific values using “Port forwarding”.

Note: in order to do one of these, you must first set a static IP address on the console.

DMZ means, in short, that you open all ports and protocols in order to communicate to a certain device with a specified IP address. So your device is placed inside an unsecured zone or if you prefer an unrestricted area. DMZ is too risky!

The alternative (the one I prefer): to manually set only the pair of ports & protocols actually needed for the connection for a certain device with a static IP address (in this case, your 360’s IP address).

All you have to do in the latter option, is selecting the “Port Forwarding” tab in your router and the setting something similar to:

  • Applications name (say, “XBox360Live”),
  • Each port range (“from 80 to 80”, and so on),
  • The accepted protocols (UDP/TCP/Both),
  • The local IP address (that is, your 360’s static IP address value), and
  • Check “Enable” (or whatever option you need to activate the rule).

Read this article in order to know which ones you must set.

As I said at the beginning of this post, the above-mentioned issue was the one preventing my 360 console from connecting to Xbox Live, properly. In short, the configuration file I had saved long ago as a backup didn’t include these settings. Fixed!

Now, continuing with the topic …

Optional: some recommend (I don’t) that when you receive the error code 8007274c, unchecking an option similar to “block anonymous Internet requests” on your router’s firewall may help. Plus, in some cases, clearing your console’s cache (warning: doing the latter will also erase all software updates! You will have to load the updates again) and or verifying that the proper DNS values are set.

By the way, port forwarding only works for one application at a time, which means that if two applications on the LAN attempt to get access, say, to the Internet using the same port, a conflict occurs and if your router cannot resolve the situation, connectivity gets affected … maybe your 360 is one of the devices in conflict!

If your router’s firewall has a log, check it to see which device and application is the source of the conflict. You can also try to check the log of your devices’ respective firewalls –if any.

If you cannot identify what’s causing the port conflict, I guess that turning off all devices but the 360 console, should fix this connectivity issue, so you can play some games online again.

You get some weird error messages and or lose connection when playing some games online on multiplayer mode.

If you do have a valid Live Gold Membership, then this is somewhat related to the port issue.

Some games need a few ports open for certain protocols (TCP/UDP/Both), which differ from the ones listed here.

Again, if you don’t want to set (the IP address of) your console on DMZ, then you should manually set both, port plus protocol, for that game.

Ok, how can I know which pair should I set? Well, you can either do an Internet search to find out or visit sites like http://www.portforward.com/, which have a lot of info in this respect, for a list of routers and services (including 360’s connections).

Other connectivity problems … plus fixes?

Say, your router must support a minimum MTU (“Maximum Transmission Unit”); in case of XBox Live that is: 1364. Or your ISP’s DSL modem is not good enough (request a change).

It would be great to know both, the problem you experienced when connecting your 360 to XBox Live and, of course, the fix.

Well, this is it. I hope you find this info useful.

Enjoy your games!
~Pete

> Link to Spanish version.

Monday, April 27, 2009

INVARIANCE, COVARIANCE & CONTRAVARIANCE

Lately, the world of C# developers is wondering about the the meaning of two unusual words: covariance and contravariance.

There is a bunch of articles out there right now attempting to explain the concepts behind those words mainly by example, and why they matter more for the upcoming version 4.0 of C#.

To mention just a few articles on this topic:

Since this subject is new for many, plus, and let’s be honest here, it is NOT THAT easy to understand at first sight, I have decided to add my two cents by writing yet another article -explaining the way I understand it- with the hope it will eventually help others to also dig it once and for all.

Ok, enough introduction! Let’s jut begin …

From a design point of view, whenever we want to refer to inheritance, we would have to use words like “generalizations” and “specifications”. But in practice or in terms of implementation, we do use the word “inheritance” itself, plus the following two words: “based types” and “derived types”.

In what follows, I'll use the latter group of terms for the sake of easier understanding. So let’s start with some basic concepts, shall we?

(I) Basic Grounds

In theory, when talking about reference types, it is stated that a base type is bigger than a derived type because it can hold either an instance of its own type or an instance of all its derived types.

Therefore, a derived type is smaller than its base type because the former cannot hold an instance of the latter.

This is usually referred as T >= S, being T the base type and S its derived type. For instance,

Object >= String

Now, we are dealing with covariance when the reference to an object is declared as its real type or to one of its base types (and by “real” I mean the type used to create an instance of it, for example: “new Foo()”).

In other words, a derived type is covariant with its based type since the direction of attribution –and in what follows I will refer to this as “movement”, going from a derived type to a base type is thus allowed to happen.

Following this rationale, we are therefore dealing with contravariance when the “movement” goes along the opposite way.

And this is probably the most difficult concept to picture. Let’s hope this example clarifies it: if you have a delegate that, say, takes a string as an input parameter and returns a bool, then you can pass a method that takes an object as an input parameter and returns the same type, in this example: a bool. Why? Because if you can deal with a derived type within the expected method then you can also deal specifically with one of its base types (we will see an example of this later).

Finally, there’s a third concept: if “no movement” is allowed to happen, then we are dealing with invariance.

For instance, to prevent conflicting variance, mutable arrays “should” be always invariant on the base type. If you are creating an array of objects then you shouldn’t be able to insert, say, a string in that array (covariance). And thus, contrary, if you’re creating an array of strings you shouldn’t be able to remove an instance of an object from it (contravariance).

Thus, from object >= string, we could then infer that object[] >= string[], ONLY IF both arrays were immutable.

All the above-mentioned explanation is in line with Liskov’s Substitution Principle, specially in the sense that the way an object is referenced in a program must never alter any of its (“desirable”) properties.

(II) The Problem

In a static language like C#, “type-safety” implies that the compiler is capable of catching “casting” errors in the code at compile time.

As explained above, mutable arrays should be invariant to enforce type-safety. But this is not the case for arrays in C#, which are covariant on the base type. Puzzled? Then read the next paragraphs.

This means that “an error” in the source code that should be always caught by the C# compiler has been turned into an exception that can only be detected at runtime by the CLR!

Why? To answer this question and from now on let’s define three classes, which many seems to like to use in code samples on the subject, lately: Animal, Cat and Dog, being Cat and Dog both derived types of the same base class: Animal.

Well? You can always allow to store a Cat in an array of Animals, but with array covariance the real type to store could be an array of Dogs.

Take for instance the following code:

   1: Animal[] animals = new Dog[10];
   2: animal[1] = new Cat();

What do you expect it will happen in the above code? Possibly the compiler will detect an error here, right? Right?!

Wrong! Believe it or not, this code only throws a runtime exception instead of an error at compile time, on any version of C#!

If this is wrong, why is it allowed, then? Because the compiler knows that both derived-types are Animals, and therefore implicit casting is allowed for an array declared to expect Animals, even though the actual instance of the array is declared to contain a whole different derived type with a common base type (in the above code: Dog[10]).

Remember that in C# there is implicit casting from a derived type to its base type because it’s a type-safe operation, but the same does not apply the other way around. And thus, you must always use an explicit cast to convert a based type back to a derived type.

Unfortunately, this problem exists in C# since version 1 and will remain for version 4 (shhhhh! … don’t say it loud, but it’s a Java-related thing).

But let’s move further to what will do change …

In the previous section I talked about delegates. Well, in C#, delegates are covariant for return reference types and also contravariant for reference-type parameters. Puzzled again? Just read on …

Continuing with this animal thing, let’s take a look at the following example for covariance:

   1: public delegate Animal MyDelegate(int i);
   2:  
   3: MyDelegate myDelegate = new MyDelegate(MyMethod);
   4:  
   5: public Cat MyMethod(int i) { … }

If the declared delegate prompts for a method waiting for an Animal as a return type, the compiler knows that a Cat is an Animal and due to implicit casting from a derived type to its base class, you can pass a method that receives an Animal.

However, the opposite is not true. If the return type is a Cat, you cannot pass an Animal instead without an explicit cast to a Cat type. Why? Due to the fact that an Animal object could have really been created as a Dog!

Now, let’s move onto an example for delegate’s contravariance for parameters:

   1: public delegate int MyDelegate(Cat myCat);
   2:  
   3: MyDelegate myDelegate = new MyDelegate(MyMethod);
   4:  
   5: public int MyMethod(Animal myAnimal) { … }

If a declared delegate prompts for a method that expects a Cat as a parameter, then you can deal with its base class. Why? Because a Cat is an Animal and by inheritance you know how to deal with it as an Animal. So anything that can be assigned like a Cat can be passed and treated specifically as an Animal with type-safety, as long as the declared delegate and the passed method, both return the same type (in the example above, an integer).

Understood. But why is this contravariance? We are in fact reversing the direction of attribution since we are passing a method that takes an Animal as a parameter to a function pointer (or delegate) that expects a Cat as an argument.

Remember the definition for contravariance? We are passing a bigger type to a smaller type, here. So we are reversing the direction of attribution.

As with the example for covariance, the opposite is not true. If the delegate expects an Animal as a parameter, you cannot treat it as a Cat in the passed method, since again there is no guarantee at all that the passed Animal parameter is a Cat. It could be a Dog, instead.

A great example to fully understand this is related to two delegates expecting methods with the MouseEventArgs and KeyEventArgs parameters; they could refer instead to one method expecting a parameter of the type EventArgs. Meaning? In that situation, in both cases the same behavior is expected. So, as you wouldn’t care about the added functionality on the two “derived” classes, you could just deal with both arguments equally using the base type in common.

Ok, if this does work for delegates in current versions of C#, where’s the problem to solve then? Well, the above-mentioned rule is not applicable when storing generic delegates, which are always invariant in C# 3.0, for both the parameter and return types (and the same applies to interfaces).

Two examples:

  • You cannot return a IEnumerable<string> if the method returns IEnumerable<object> (that would be covariance), and
  • You cannot use an Action<object> delegate to replace an Action<string> delegate (that would be contravariance). Please bear in mind that I’m referring here to assigning, say:
   1: Action<Cat> myDelegate = new Action<Animal>
   2: ( myAnimal => myAnimal.DoSomethingWithTheAnimal() );

And not to something like- which of course does work just fine:

   1: Action<Cat> myDelegate = MyMethod;
   2:  
   3: public void MyMethod(Animal myAnimal) { … }

And yes, please! Try it with C# 3.0 if you are in doubt of my words.

(III) The Solution

So, what's all this fuzz with the new added use to the existing reserved words "in" and "out" in the upcoming C# 4.0?

For reference types:

  • in = contravariance (only passing arguments),
  • out = covariance (only returning types).

From the examples above:

  • Covariance: IEnumerable<T> will become IEnumerable<out T>, so a delegate declared to return a IEnumerable<object> will in fact be able to return an IEnumerable<string>, and
  • Contravariance: with Action<in T>, you will be able to assign an Action<object> delegate whenever you expect an Action<string> one.

I advice you to check the articles listed at the very beginning of this post for complete code samples on the subject.

Phew, this is it! As you can see, the theory behind these concepts is not that easy to understand but it’s neither that difficult, so I really hope you have found this explanation useful to finally accomplish that task.

‘till next time,
~Pete

> Link to Spanish version.

Wednesday, March 25, 2009

IE8 & ADOBE FLASH PLAYER FIX

[ If you deem this article as helpful, please consider downloading my game "Just Survive XP" on the Appstore (free for a limited time):

=> http://itunes.apple.com/app/just-survive-xp/id461876025 ]

Yesterday, I wanted to watch a video on Youtube when suddenly, to my surprise, I just found the following message, instead:

Hello, you either have JavaScript turned off or an old version of Adobe's Flash Player. Get the latest Flash player.

Since Javascript was enabled, in order to check whether this was a problem of Youtube's site only, I browse to other sites that I know use flash tech to find that I was really unable to watch any Flash content. They all prompted me to download and install the latest version of Adobe Flash Player.

So I visited Adobe's site and tried to get the latest Flash Player online. The key thing is that after installing the add-on, the movie clip that always appear on the site saying that your installation was successful didn't appear at all. Strangely, by refreshing the page -by hitting the F5 key- it did appear. Weird.

So I said, maybe this was just a minor glitch, and opened the video page on Youtube. Unluckily, that nasty message appeared again.

This time, I opened the "Tools" menu of IE8, and selected the "Manage Add-Ons" section. There, I found that the "Shockwave Flash Object" add-on was in fact installed and the version was correct, so I tried to "reset" it by disabling the component, closing the browser, re-open it and finally enable the add-on. No luck!

One final desperate move: just in case, I just opened the following menu on my browser:

"Tools -> Internet Options -> General -> Delete"

and deleted everything. Then, I downloaded the offline installer of Adobe Flash Player from the following link:

http://www.adobe.com/support/flashplayer/ts/documents/tn_19166/Install_Flash_Player_10_ActiveX.zip

And finally, I closed the browser and executed the installer (btw, since the offline installer does the task of uninstalling any previous version of the add-on, I skipped that part and let it do it for me).

When the process ended, I just reopened IE8, visited Youtube again to find this time that everything simply worked just fine!

I don't know if this workaround will work for you, but if you happen to experience a similar situation then just give it a try.

Well, that's it for today. I hope you find this post useful.

Stay tuned,
~Pete

> Link to Spanish version.

Monday, March 23, 2009

WIN OS REBOOT FAILS AFTER INSTALLING IE8

Yesterday I was installing the final version of Internet Explorer 8 on my Windows Vista Business machine and everything went fine until the OS prompted me to reboot.

As this is generally a usual request for new installations of IE, I just pressed the "Reboot" button with confidence.

Here was the inflexion point of my installation experience: after the machine rebooted, and the POST checks succeeded, the monitor's screen got completely blank and the main hard drive just stopped working!!! Not sound, no flashing lead, nothing.

Meaning, the OS was unable to boot; and trust me on this: turning the machine off and on after a while, didn't help at all.

If this happens to you, just don't panic. For some unknown reason -at least, for us mere mortals- the "Master Boot Record" (MBR) of your HDD may have been somehow overwritten during IE8's installation.

Maybe using the installation disks of your OS could work, by selecting the "Repair" option and then let the tool do its magic. But in my case, I used a shorter path.

I cannot assure the method I will describe will work for you; I can only state that it did work for me, therefore USE THE METHOD AT YOUR OWN RISK!

You have been warned now, so read on:

To solve this situation you don't have to reinstall your windows OS (since it's still there on the hard drive); the only thing that you have to do is find a way to write the proper MBR again to your HDD.

To accomplish this task, I searched for an old tool called Max Blast, which I used to execute when I wanted to prepare a HDD (Maxtor or Seagate) for a new Win OS installation or "sort of" repair a faulty disk. In this particular case, my main HDD was a Samsung one but I tried my luck, anyway.

I found on my archives an old Floppy Disk with version 4 of Max Blast, so I used this disk to try to reboot the system.

Then, when Max Blast executed I entered the section named "Maintenance Tools" of the main menu and then selected the option "Update MBR". After choosing the target HDD and waiting for the process to end, I finally rebooted my machine to witness that it fully worked!!!

Windows Vista was booting up again and IE8 was completely installed. Everything just got back to normal. And it only took me like 3 minutes or so to fix.

Well, this is it. I hope you find this post useful ... if you ever happen to find your-self in a situation like this :(

'till next time!
~Pete

> Link to Spanish version.

Monday, November 17, 2008

XNA & EXTENSION METHODS 3

With this third article, I'm closing my introductory series to the world of Extension Methods and XNA.

At first, this article was meant to focus on how to extend the Random class to get new colors, but Ziggy, in his article entitled "Particles Using LINQ" -worth reading, btw- has clearly shown how to achieve this so I will take that great article as a starting point to go a bit deeper in the discussion on the matter.

If you see Ziggy's method named "RandColor" -which from now on I will refer to it as "NextColor" to be in line with the Random class, he's showing one of the new features of the XNA Framework 3: when using floats there's no need to first create a Vector3 in order to then create a Color, anymore.

In previous versions of XNA, to use floats in order to create a color, you would have declared:

public static Color NextColor(this Random rand)
{
    return new Color(new Vector3(rand.NextFloat(), rand.NextFloat(), rand.NextFloat()));
}

But from the XNA Framework 3 and on, this also works:

public static Color NextColor(this Random rand)
{
    return new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

Now, if you see the Particle2D class in the above-mentioned article, you will notice the field named "Color", which is declared as an variable in uppercase; a new extension method could be created for it, as follows:

public static void NextColor(this Random rand, out Color color)
{
    color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

Thus, we can use it within the Update method in the referred example to replace this line:

p.Color = rand.NextColor();

By this new line:

rand.NextColor(out p.Color);

Since the type Color is a struct, the advantage of using the latter over the former could be generally deemed as marginal, but eventually you may get to the situation when even the slightest improvement in your code is desired, specially when you're targeting the compact framework.

New question: what if you followed the design guidelines of C#, declaring the color field in lowercase as a private field and instead, a public getter and setter was included in that class, in the form of a public property named "Color".

In that case, the new overloaded method cannot be used since Properties and Indexers cannot be passed as out/ref parameters. Why? Well, just remember that when you're using properties and indexers you're not directly dealing with variables but methods. In that particular case, the first implementation -that is, the one included in Ziggy's article- is the best solution.

Let's face it! You could be tempted to pass the existing instance of Particle2D as "ref" to sort out the above-mentioned constraint, as follows:

public static void NextColor(this Random rand, ref Particle2D particle)
{
    particle.Color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
}

It should compile ok BUT ONLY if you're NOT PASSING to that method the temporary variable created by a foreach loop -as opposed to the base example. This operation is just NOT ALLOWED for the iteration variables of foreach loops. My advice here is simple: avoid this tempting implementation and as I said before just use the one presented by Ziggy. Generally, the simplest solution is the correct one.

One side note: in case you're new to C#, it's important to notice that in this case we are using "ref" instead of "out", since we need an existing (that is, a non-null) instance of the class in order to assign the new color. Otherwise, by using "out" we should have to create an instance of type Particle2D from within the extension method BEFORE assigning the new color to it.

Now, let's move onto an interesting situation. What if:

  1. We are not and will be not inside a foreach loop,
  2. We don't want to expose the whole Particle2D to the extension method, and at the same time
  3. We need to use this method for as many classes that have declared setter properties for colors?

If that is the case, then you should take a look to this implementation:

public interface IColor
{
    Color Color { get; set; }
}
 
public static class HelperMethods
{
    ...
 
    public static void NextColor<T>(this Random rand, ref T instance)
        where T : class, IColor
    {
        instance.Color = new Color(rand.NextFloat(), rand.NextFloat(), rand.NextFloat());
    }
}

As you can see, we are hereby combining the power of Generics with Extension Methods.

But, why the "IColor" constraint? What we are saying here is simple: only types that implement the Color property can call this extension method. And those non-null instances passed to the method as a parameter (remember we are using the "ref" word here) will be handled as IColor types.

Ok, but why the additional "class" constraint? Tricky one. As a corollary of the previous constraint, if we do not specify that only classes are accepted as parameters, then structs can be also passed when calling the method, and for that they will have to implement the IColor interface ... Meaning? ... Tic tac tic tac ... Yeap, boxing. Ugh! That nasty word. Handling structs through interfaces causes boxing. Chilly, isn't it? Now you know it, in case you didn't.

To sum up, as you can see Extension Methods are quite handy, but you have to use them with care if you want to avoid getting into a design trap. As usual, not all the situations can be solved the same way, even though at first it sounds logic to you. You may find your-self saying "Whaaat? Buy whyyy? ...". So, I hope these examples show you what to use and when and what to avoid and why.

Some final thoughts about Extension Methods:

  1. They are great for usual tasks: believe it or not, two common types where I always find my-self repeating usual tasks are TYPE and RANDOM classes, but this feature can be used with as many types as you need,
  2. They are ituitive to use: before this functionality was introduced to the .NET Framework, one usually used to write a static class filled with helpers; please don't misundertsand me, you still have, but now those helpers are presented in a more intuitive and user-friendly way. With Extension Methods, you don't have to look for the methods "by browsing" the static class were you declared and implementem them; instead, you just look on the instances of the types you are using. And last but not least,
  3. They comply with design principles: as said in my first article in the series, we are not breaking any design principles, since we have no direct access to private members of the "extended" types.

In short, if you use Extension Methods with care and wisdom, they can be a true friend at the time of coding your XNA-based game or application: they simply help you extend any types with new methods AS IF these where originally part of those types, what in turn can be handy, for instance:

  1. When you don't want to create a specification of a class, or on the other hand,
  2. When you want to put more functionality into a sealed class somehow -to some extent, of course.

So go ahead, try Extension Methods and share what you find with the XNA Community. It would be great and fun to know what you are using them for!

Well, I hope you have found this series useful. Constructive comments and suggestions are always welcome.

Cheers!
~Pete