08/28/07

Permalink 12:53:20 am, 754 words, Categories: RemObjects, Oxygene, .NET, Visual Studio, Mono, Cocoa, Mac

Partial Methods

Next to the big two new features shipping in Version 2.0.3 of Chrome ‘Joyride’ that we’ve already talked about in previous posts, there’s also one small but powerful new language feature that’s new as well: Partial Methods.

What are partial methods? I’m glad you asked. Partial Methods tie in with another related feature we have been supporting for a while now (are, in fact, supporting for .NET 1.1 as the only language i know of) that you are probably familiar with: Partial Classes. Partial classes allow to split the definition of a single class across multiple source files. From looking at the code, each partial looks like a complete class on its own, but at compile time, all parts will be combined into a single class. Because the separate parts form the same class, members defined in one of the parts are accessible from any part.

Partial Classes come in handy for many scenarios, the most commonly seen being the combination of one auto-generated and one user-written file, as used by the form designer, strongly typed data sets, XAML, and other technologies. One code file is generated by a tool and will usually not be touched by the user (might in fact get overwritten regularly) while the user provides a second code file to add her own members to the same class. But even in hand-written code, partial classes come in handy to split large classes into more concise section - for example our own CodeDom implementation uses separate partials to implement different aspects of the code generator - one deals with actual codegen, one contains methods relating to ASP.NET compilation, etc.

Ok, enough about classes, where to partial methods fit in?

Simple: partial methods allow one part of a partial class to define an empty method stub, without providing an implementation. Another part of the class can then choose to (or choose not to) provide an actual method body.

Let’s look at an example. A partial class generated by some tool might define the following:

type
  Foo = partial class
  private
    method Initialize; empty; partial;
  public
    constructor;
  end;

Note how the Initialize method is declared with both the empty and partial keywords. This method is a partial stub that provides no actual implementation - but still, it exists inside the class, and can be called from any of the partials. In this case, it sees likely that the constructor would probably call Initialize at some stage.

A second partial for the Foo class could now go ahead and provide an implementation for the method, by declaring

method Initialize; partial;

Note how the empty keyword is omitted this time, and a full method body will need to be provided in the implementation section - just as for any other method. Any call to Initialize() - from within either part - will then, of course, invoke the provided method implementation.
What happens if no partial provides an implementation for the method stub? Easy: any and all calls to Initialize() will be eliminated by the compiler, and it will be as if the partial method never existed. Thus, a partial method that does not provide an implementation has no runtime overhead, making partial methods an ideal candidate to provide entry points that might or might not be filled.

Now, where are partial methods used in real life?

In Chrome, there are currently two technologies that use partial methods, one shipping in 2.0.3, and one not yet.

Available now, the new Cocoa# template i wrote about before uses partial methods to expose events. Chrome provides a custom tool that generates code from a .NIB (short for NeXT Interface Builder) file that contains the User Interface definition for a Cocoa application. For any events defined in the interface, partial method stubs are provided that the developer can that provide implementations for, if he wants to handle the event. In addition, a third partial will be added to the template for 2.0.5, exposing certain standard events available system-wide from the Cocoa framework but not defined in the .NIB

Secondly, and not yet available but shipping in a future release, code generation for LINQ to SQL will rely on partial methods to provide hooks in the auto-generated code that the user can extend. Due to the zero-overhead nature of partial methods, these hooks can be provided without affecting the runtime behavior - code for them will only be executed if the user provides an implementation.

Oh, and of course there’s also full Code Completion for partial methods, showing you available (and not yet implemented) stubs:


08/24/07

Permalink 08:10:58 pm, 792 words, Categories: Oxygene, .NET, Visual Studio

Shine that Silver Light On Me

Getting back to some more Windows/Microsoft features after our brief excursion into Mac territory (no worries, we will get back there too, and soon), we’re shipping full Silverlight support in Chrome ‘Joyride’ 2.0.3 just now. Full support means we’re providing everything you need to build Silverlight 1.1 Alpha apps in Chrome and Visual Studio 2008 - project templates; XAML editor with IntelliSense support; MSBuild support - the full shebang.

Let’s run thru creating a small Silverlight app to see what’s involved!

First, to start off, you will need three prerequisites installed to follow along: Visual Studio 2008 Beta 2, Silverlight 1.1 Alpha Refresh and Silverlight Tools Alpha for Visual Studio 2008 (all available here). Also, of course, you will need at least version 2.0.3 of ‘Joyride’.

Bring up the New Project dialog of Visual Studio and open the Chrome folder to notice the new “Silverlight” folder beneath. We provide two templates for Silverlight - one for a general project, and one for a Class Library that (similar to plain .NET library projects) will allow you to write classes and controls to share between different projects. For now, let’s go with a plain “Silverlight Project”, and call it SilverChrome.

The new project opens, and you will see some familiar and some unfamiliar things. Firstly, the reference list includes some assemblies you don’t know from .NET, such as an an ominous “agclr” which implements the core Silverlight classes, but also familiars such as mscorlib and System.dll with the .NET classes you know and love.

Next, there’s a Page.xaml file, with a nested Page.xaml.pas code file. This might look familiar if you worked with WPF before as it uses a similar (but not completely interchangeable) concept. Basically, the XAML file will represent the visual appearance of our Page, defined by by XAML tags that represent classes (i many cases familiar from WPF, such as Canvas, …, etc). This file will be processed at runtime from by the Silverlight runtime to create your page and its contents. The so-called Code-behind file instead contains Chrome code that will be compiles within Visual Studio and deployed as .dll file. As such, the code can leverage all the features of Chrome, and call any standard or third party .NET classes that are available for the Silverlight runtime. In essence, all your expertise in developing with Chrome and .NET will apply directly to writing code that will run within the Browser, now.

Of course it goes without saying that, as with any Chrome project, you can add additional source files to the project and write any code you please. No more reliance on JavaScript or Flash’s Action Script to implement rich web clients!

Finally, there’s an HTML page in your project that will host your Silverlight page for testing purposes - although for final deployment you’ll most likely embed the Silverlight page into your existing website (much like you might do with a Flash control, now) - as well as two JavaScript helper files that perform the task of actually loading the Silverlight runtime.

Let’s press Ctrl+Shift+B (Build) now and navigate our favorite browser to TestPage.html to see - an empty white page!

That’s right. Our Silverlight page is working fine, but it’s of course not doing anything, because we’re just providing an empty XAML file. Let’s go back now ad add some functionality. First open the Page.xaml file and enter the following tag with the <Canvas>. Try typing instead of copy/pasting it, to see that you get full intellisense for available classes and properties:

<TextBlock x:Name="ClickMe" Text="ClickMe" MouseLeftButtonUp="OnClick" />

Next, open the Page.xaml.pas code-behind file, and add the following method. Note how we can refer to the ClickMe TextBlock in code, even though the only place it is actually defined is the XAML. What’s happening here is that the Silverlight build process generates code from the XAML file during compile, and injects this into the project as a partial class for Page. If you ever want to look a that code (for example to investigate a confusing error message), you can find it in a file named Page.g.pas in the ./obj folder.

method Page.OnClick(sender: Object; e: EventArgs); 
begin
  ClickMe.Text := 'Clicked';
end;

Once done, press Ctrl+Shift+B to rebuild, switch back to your browser and refresh the page. You can now see our “Click Me” TextBlock in all it’s glory - and click it to make the magic happen!

(Some additional gradients and font styles added for effect ;-)

And look, it even runs in Firefox on the Mac, making the above the very first line of Chrome code ever run on a non-Widows system without Mono!

08/11/07

Permalink 02:56:35 pm, 1011 words, Categories: RemObjects, Oxygene, .NET, Visual Studio, Mono, Cocoa, Mac

Adventures in Mac World - Part 1

I needed to get myself a new laptop, and after much deliberation decided to treat myself to a Mac, for a variety of reasons, not the least of it being that i was curious about the Mac platform and wanted an option to test our products on Mac OS X - including Chrome and our Mono libraries, but also the new FPC support we have been shipping in ‘Vinci’, as well. At the very worst, i figured, the MacBook Pro would make a great Vista machine if i found i really couldn’t stand Mac OS.

As it turns out, i’m very happy with Mac OS X so far, and liking it quite a bit. And the new VMware Fusion (conveniently released the day before my MBP arrived) makes it easy to fall back to Windows apps - such as Visual Studio or our internal BugClient - where needed

One of the first things i tried, naturally, was to install Mono and Chrome and test the command line compiler and apps. But running the FileFind sample got boring after a few minutes, and i wanted to try some more exciting things, such as creating a proper Mac OS GUI app. The first obvious choice was, of course, WinForms, which i am familiar with and is by now well supported by Mono, as well. After figuring out i had to manually install X11 off the Mac OS CDs, WinForms apps ran well, however, they did not really feel “native Mac” - no icon in the dock, no proper top menu, etc.

It turns out, to get proper Mac OS X feel from a Mono app, the only real choice is to use Cocoa#, the managed wrapper for Apple’s standard UI framework. Documentation on Cocoa# is next to non-existent (and the bit i did find was hopelessly out of date and wrong), after with a bit of experimenting, it all worked surprisingly well.

Setup

To get started, let’s look at the tools and software that’s required. I’m running Mac OS X 10.4 (Tiger) and also installed Xcode Tools (which might or might not be pre-installed on your Mac; if not, you can install it using the “Optional Components” setup found on the Mac OS X install CDs). Lastly, on the Mac side, you will need Mono 1.2.4 for Mac OS (available here).

To make development easier, i also installed Chrome with Visual Studio inside VMware Fusion, and installed Mono 1.2.4 for Windows (also available here), so i can directly link against Mono from inside Visual Studio.

Mono for Windows does not deploy the Cocoa# dll (which soft of makes sense, since it won’t work under Windows), but i manually copied it over so i can use it from Visual Studio. You can find cocoa-sharp.dll in

/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/cocoa-sharp

on your Mac and simply copy it over to

C:\Program Files]Mono-1.2.4\lib\mono\cocoa-sharp

Note that the the cocoa-sharp.dll found i the above folder most likely is a symbolic link, which VMware Fusion apparently cannot directly copy to the VM directly via drag and drop; you might need to follow the link back to the real file.

Getting Started

If you’re running Chrome ‘Joyride’ 2.0.3 or later, you will find a new ready-made template for Cocoa# in the New Projects dialog (in the MonoChrome subfolder). Use this template to create a new project.

Working with Cocoa# will require a lot of switching back between Mac OS and the Windows VM, so rather then copying the project back and forth frequently, i suggest creating it in the shared folder that VMware Fusion created for you, sharing your Mac home directory. In my case, this was mapped to drive Z:\ under Windows, and mapped to my ~mh folder, Mac Side.

First thing after creating the project, you will notice a few unfamiliar files - a .ICNS file containing the application icon, and a .NIB folder containing the Cocoa interface definition that describes the UI of your application. Visual Studio will not be able to edit the files in this folder (except in text or binary mode, which is quite useless), but fortunately Interface Builder, provided as part of the Xcode Tools, can.

So, switch back to Mac OS, locate your project folder in Finder and double-click the Interface.nib (you will notice that Finder treats the entire folder as a single file, a so called “package”, even though in Visual Studio it appears as a folder) to open Interface Builder:

As you see, Interface Builder opens with four windows:

  • A design surface for your application’s main form
  • A designer for the application menu
  • The Toolbox
  • The project window containing all elements defined for your UI.

Going into the details of designing Cocoa GUIs would go beyond the scope of this text, so lets simply drop a text control on the form and double-click it to change its caption to “Hello World!”, and also double-click the “NewApplication” in the main menu to change it, too, to “Hello World”, the name of our project.

Being happy with the UI, do File|Save (⌘S) and switch back to Visual Studio. There’s not really anything we need to do in code for our simple Hello World, so just do a Build|Build Solution to compile the project.

We’re almost ready to run now; as a last step, we need to package our project as a Mac .APP application, so we can run it. To do this, open a Terminal window, and navigate to your project’s bin/Debug folder (ie ~mh/Hello World/bin/Debug in my case), and run the following command:

macpack -m:2 -n:HelloWorld -a:HelloWorld.exe -r:Interface.nib -i:App.icns

As a result, a HelloWorld.app (this again is a package folder that Finder will treat as a single file) will be generated, which will behave like any other Mac app - you can deploy it to the Applications folder, drag it to the Dock and, of course, double-click it in Finder to launch it:

 

marc hoffman

Chief Software Architect &
Spare-time Photographer

mh

Links

Twitter (experimental)

  • loading...
follow me...

Navigation

Search

XML Feeds 

Who's Online?

  • Guest Users: 19

Flickr