You are browsing the archive for MonoDevelop.

Profile photo of marc

by marc

Delphi Prism 2011 has RTMed

May 23, 2010 in .NET, Elements, MonoDevelop, Oxygene, Visual Studio

Last night, we ran the RTM build of the latest Delphi Prism release.

Delphi Prism 4.0.23.741 is the result of over a year of work from the team here at RemObjects, and marks the probably single biggest release we ever have done, since ‘Chrome 1.0″ shipped back in the spring of 2005.

The Road to a New Project System

The funny part is that the biggest new feature is one that most users will not notice, or take for granted – and that is  a complete rewrite of the core IDE integration engine. You see, back when we first shipped the product, Visual Studio .NET 2003 was the latest version of Visual Studio, and the way to integrate with that was cold, hard C++. We didn’t like it, but we had no choice. We tried to implement large parts of our IDE smarts (code model and code completion, these sorts of things) in managed code, but the crucial parts that talked to Visual Studio, the parts that were the most difficult, were done in C++

With Visual Studio 2005 and later 2008, Microsoft introduced the option to create full project systems in managed code, but for one reason or another, we never made the switch. The thing was working, after all. and we had better things to do with our time, like adding new features.

With Visual Studio 2010 looming ahead, and with integration into MonoDevelop also starting to look like more of a possibility, we finally made the plunge last year, after the Spring 2009 release was out the door, and started serious work on the new project system. We did a lot of refactoring, to separate VS-specific code from generic code, with the goal to be able to share as much code as possible between IDEs, and have as little IE specific code for Visual Studio or MonoDevelop, as we could get away with.

This all progressed great, but as the August 2010 release date was approaching, we realized there was way too much work ahead of us, too many Ts to cross and Is to be dotted for us to deliver a quality release based on the new code, so we rowed back, and in a branch of our VSN repository combined the old “May 2009″ IDE code base with the latest compiler, to ship the August release, “Delphi Prism 2010″. At the same time, work went on in the main trunk, on the new project system, which we are now shipping, half a year later after having waited for MonoDevelop 2.2.2 and Visual Studio 2010 to finalize.

So, the big feature for this release, as far as we are concerned, is that you don;t really see a difference between this release and the last, but that Delphi Prism is seamlessly integrated into two brand new IDEs: Visual Studio 2010 and MonoDevelop.

Visual Studio 2010

Along with Visual Studio comes of course a host of new features – i’m tempted to say ‘for free” when of course many of these have been a lot of work under the hood, for us. There’s support for the new Silverlight 4, better WPF support and – most importantly, the new .NET 4.0 runtime, which allowed us a lot of new and advanced compiler features, from Dynamic Types over Tuples and Big Integers to obscure (but cool) things such as generic co- and contra-variance.

There’s also things that truly do come for free with the new IDE, such as new new WPF based code editor (which is very nice to use and due to WPF’s smooth (and dare i say Mac-like) font rendering very easy on the eyes. There’s also the new Visual Studio debugger, which as been vastly improved in many areas, not the last of which the debugging of multi-threaded programs. The list goes on – just search for what’s new in VS2010, and the vast vast majority of what you’ll find will apply to the new Delphi Prism.

Of course Delphi Prism 2011 will install into an existing version of VS2010, or come with and install its own copy of the Visual Studio 2010 Shell, if you don’t own VS2010 yourself. (Delphi Prism 2011 will also still install with Visual Studio 2008, if present, but it won’t bring it’s own copy. If you need both VS2008 and VS2010 on a fresh install, you can install the August 2009 release, and then upgrade to the new version, to get both Shells)

MonoDevelop

But wait; Visual Studio is not where it ends. Delphi Prism 2011 also supports MonoDevelop 2.2, on both Windows and Mac OS X. When you run the Delphi 2011 installer, it will automatically detect MonoDevelop (if present) and offer to register with it, or offer to freshly install MonoDevelop 2.2.2 for you, if you don;t have it yet.

So you can choose to use either VS, MD or both IDEs, depending on your preference.

For the Mac, we have a separate distribution of MonoDevelop.app that includes Delphi Prism; this will be a .zip file on your ISO or DVD that you can simply unzip on your mac and copy to the Applications folder.

On both Windows and the Mac, Delphi Prism integration into MD will give you the full development experience that MD has to offer. This includes the Gtk# visual designer on Windows (the MonoDevelop guys don’t yet support that on the Mac, i’m afraid), integration with MonoTouch (if you own a copy) on the Mac, and so on.

Of course MonoDevelop as an IDE is still very young, so compared to Visual Studio there is still a lot of catching up that needs to be done, both on the IDE itself, and on the more advanced IDE features that Delphi Prism supports. Our goal for this release was to provide a basic set of functionality that allows you to start working and be productive in MD. Over time, we’ll work on feature parity with VS, bringing more of the advanced features (such as “Paste C# as Oxygene“, or the Oxfuscator integration) over.

We’ll also be working on adding support for Linux as third MonoDevelop platform to Delphi Prism.

What Else?

Of course there’s a lot more to Delphi Prism 2011 than “just” two brand new IDEs. I finalized the official change log for this release a couple days back, and amazed to see that we have close to 400 bug fixes and minor improvements thru-out the product (and that does NOT even include any fixes and enhancements that happened witjhin the product cycle [such as, any “fix” related to VS2010 or MD support, which never shipped before]. that’s just fixes and improvements over the previous August 2009 release.

There’s also roughly 30 major new features (such as for example new Expression types, MacPack Integration, a cross-platform helper library for Mono) and 30 less major but noteworthy  enhancements (such as enhanced functionality in Cirrus, compiler optimizations, framework multi-targetting or support for T4 template files).

What’s Next?

The next release of Delphi Prism is already looming ahead, this fall alongside the new RAD Studio. Because  the current release was such a major milestone (and is shipping such a vastly new codebase, for the core IDE integration), we’re planning for that next release to be a pure maintenance and bug-fix release only. To start with, our team here at RemObjects will take a week or two off to recover from the rush of getting such a major release out the door.

After that, we’re planing to get back to a regular cycle. We want to release weekly new beta releases (as we have done over most of the course of this past beta cycle), combined with monthly “stable” releases that focus on  fixes and improvements in various areas of the product. The idea is that (if you join the beta program – and remember, every Delphi Prism customer is welcome to join, and we’d welcome your feedback),  you have the choice of frequent latest builds, or regular “production level” builds, as we move from the current release towards the August 2010 one.

When can You Get it?

As mentioned at the beginning, the RTM build was signed off to the team at Embarcadero yesterday. The team in Scott’s Valle will go thru some final QA cycles and prepare for the distribution to customers. If all goes well, i’m told the new release should be in the hands of people within about a week, both as new public trial, and as free update to all customers with Software Assurance (you do have Software Assurance, right!?).

Even if i were to just link to the direct download, for this release you will need a new serial number, which you should receive from Embarcadero in time.

 

Thanx for reading, and i hope you’ll enjoy Delphi Prism 2011 as much (if not more ;) as we have enjoyed creating it. Let us know what you think, either here, via email, or on the ongoing beta program.

Delphi Prism in MonoDevelop at a glance

March 29, 2010 in .NET, Elements, Linux, Mac, Mono, MonoDevelop, Oxygene, Platforms, RemObjects, Tools, Windows

Our beta users (marc already did mention you can apply for the Prism beta here, didn’t he?) are already playing around with this for some time now, and we are going to ship it with the upcoming release: the Delphi Prism MonoDevelop integration. Marc already mentioned this some time ago and a lot has happened since then. This article should give you a ‘what is it and how could I start?’ introduction into Delphi Prism in MonoDevelop.

MonoDevelop LogoMonoDevelop is a free and open source .NET IDE. and has its roots in the also free and open-source SharpDevelop .NET IDE. With SharpDevelop still being a Windows-only IDE using Windows Forms, MonoDevelop (or in short MD, as we call it internally) was ported to Gtk# and massively extended in regards to cross-platform compatibility. It is now able to work smoothly on Linux, Mac OS X and, of course, Windows. You can use your solutions from Visual Studio with MD and vice versa, so you are able to have a single source solution for different platforms.

With the Delphi Prism MonoDevelop integration we target mainly the Mac and then Windows. For Windows we have the Visual Studio integration and we ship the Visual Studio Shell which is, in fact and to be honest, a far more comfortable and powerful IDE. That said: Of course we want to make sure that MonoDevelop on Windows (MD/Win) also works like a charm, but MD/Mac is of a higher priority because you don’t have an alternative IDE there.

The MD/Mac flavor of our MonoDevelop integration comes in form of a complete Mac application. It looks like it’s the original MonoDevelop, but additionally contains our Delphi Prism plug-in. That means you will have to install the MonoDevelop prerequisite by yourself (which is Mono >= 2.4). You can grab it here.

After startup, the Delphi Prism will tell you that it is not licensed and ask you to register your license (if you don’t have a Delphi Prism license yet you can get your copy and a 30-day trial key from the Delphi Prism download page).

When selecting “Start a new Solution” you have several options: The first one is a Console application, but you also have the choice to work with ASP.NET projects, create iPhone or iPod touch applications (be sure to have the iPhone SDK and at least the Trial of MonoTouch (http://monotouch.net/) installed for this) and you can build Moonlight applications (the Mono alternative to Silverlight).

For this article we’re going for an iPhone application. Not because we want you to go and buy you into the iPhone Developer Program and additionally buy MonoTouch from Novell, but just because it’s a neat thing to show ;)

In this dialog you see the options I set for the Hello world iPhone application. Be sure to meet the requirements (MD prereqs, iPhone SDK and MonoTouch) if you want to follow this article in code yourself. The next thing you’ll see is the MD editor with the project opened and ready to start.

We’re not going too deep into the MVC approach of the iPhone development, which is also the key to general Cocoa development, but you need to know that the UI is separated from your code. Unlike in Delphi or Windows forms where controls dropped on the form are automatically properties of your form class, you need to define which controls and events (called Actions) are visible to your code using defined classes.

The first thing we’re creating is the GUI. No demo without a ‘Hello World’, so we simply want to display the text entered in a text box on a label when the user presses a button. In the ‘Solution’ part of the MonoDevelop IDE to your left we expand the project and double-click on the ‘MainWindow.xib’ file. This should launch a program called ‘Interface Builder’ which belongs to the iPhone SDK. The .xib file is somewhat compareable to .dfm files you know from Delphi or like .Designer.pas files which define the layout of a Windows Forms form. The following part of designing the GUI and connecting the outlets and signals is in fact the most difficult if you never worked with interface builder. Because of that I also created a short video of this walk-through so that you have the chance to actually see what I’m going to describe now.

S1.png

On the ‘Library’ window you select the ‘Objects’ part on top and use the search box on the bottom to search for a ‘Toolbar’. Take it and drop it on the window and let it dock on the top. Then do the same for a ‘Text Field’ and a ‘Label’. You can drag them to the width that pleases you. Now that all controls are in place it’s time to make them accessible. In the ‘Library’ Windows please select ‘Classes’ on top and type ‘App’ in the search box. Then you can select the ‘AppDelegate’ class which is the interface between our application code and the GUI. Still in the library window select ‘Outlets’ in the lower half. We’re going to define accessors to the text field and the label now by clicking on the ‘+’ below the listed outlets and enter text and repeat that for label. Now we’re going to make our click event accessible by selecting ‘Actions’ instead of outlets and add the action ‘onClick:’ (mind the colon!) to the AppDelegate class.

The next task is to connect our outlets and the action to the controls. To do this, you simply select the toolbar button (labeled ‘Item’) in the window. In the property window you select the connections (white arrow on blue circle). There is an area called ‘Sent actions’ with an entry for ‘Selector’. Use the mouse and click in the circle to the right and drag this on the yellow ‘App Delegate’ box in the ‘MainWindow.xib’ window. On dropping you are able to select the action you want to link with the sent ‘selector’ action of the item. For both the text field and the label drag the ‘New referencing outlet’ circle on the App delegate and link them to the text and label outlets we defined before. Now you can press Apple+S to save the MainWindow.xib file.

MonoDevelop generates the code behind for us automatically. Please open the ‘MainWindow.xib.designer.pas’ file (expand the ‘MainWindow.xib’ node in your solution to find it) to have a loot at the generated code. Locate the

method onClick(sender: MonoTouch.UIKit.UIBarButtonItem); partial; empty;

line and copy it (withouth the empty;). Pase that in the ‘private’ section of the ‘AppDelegate’ class in the Program.pas file and double check that the empty; part did not get pasted too. This is the method that get’s called when the event (sorry, Signal ;-) ) fires from the GUI. In the implementation part complete the partial method and fill in it’s body:

method AppDelegate.onClick(sender: UIBarButtonItem);
begin
  label.Text := textbox.Text;
end;

In fact that’s all. Compile the project using the building blocks icon in the toolbar of MD (or by pressing Apple-B). Your code will be compiled into an assembly and the assemblies then will automatically be compiled in to native code for the iPhone by the MonoTouch compiler. When clicking on ‘Run’ or ‘Debug’ the iPhone simulator application should pop up and run our Hello world application:

S2.png

As you can see building an application for the iPhone using Delphi Prism is not only working, but you can make use of the full Cocoa API the iPhone SDK is offering you. Of course this only works if you have the iPhone SDK and MonoTouch, but to develop for the simulator as we just did, the free version of both is enough. You would only need to pay for the Apple developer program membership and for the MonoTouch licence if you’re going to deploy your programs on a physical device. In other words: Unless you want to start selling your application and earn money in return, you can work for free.

Here you can watch a little video that shows how the application was build:



Download this Video: as mp4 or in open ogg format.

This was a first feature preview of Delphi Prism in MonoDevelop and we hope you like it and stay tuned for more.

Sebastian

Profile photo of marc

by marc

Episode 39 of the Podcast at Delphi.org

March 19, 2010 in .NET, Cocoa, Elements, Mac, Mono, MonoDevelop, Oxygene, Podcast, Visual Studio

It’s been a long while, but Jim and i finally found the time again to sit down and record a new episode of The Podcast at Delphi.org, talking about the upcoming Delphi Prism 2011 release, software development for the mac using Mono, and a lot more. It’s been great to be back on air, and we’ll hope to make this a more regular thing once again. In the mean time, i hope you’ll enjoy this episode!

See the official post for this episode at Delphi.org. Or subscribe in iTunes or via the RemObjects on Air feed.

(Via The Podcast at Delphi.org.)

Profile photo of marc

by marc

New Syntax for Extension Methods in Delphi Prism

February 17, 2010 in .NET, Elements, Mono, MonoDevelop, Oxygene, RemObjects, Visual Studio

Ever since Extension Methods have been introduced in .NET 3.5, we’ve been pondering on a proper syntax to allow developers to define their own. C# uses an awkward syntax where it uses the this keyword (C#’s equivalent of self) as name of the first parameter. But that felt wrong. For one, it’s a very C-like thing to do (having an obscure syntax that is not really discoverable or understandable, it ranks right up there with =0 for abstract methods in C++), for another, the fact that methods receive a self pointer as first parameter shoud be an implementation detail of the language (or runtime), not a syntax feature.

Another idea was to simply allow a new extension directive to be appended to a method declaration (similar to virtual or similar constructs). But that too felt wrong.

So what we did, for the time being, was to not provide any special syntax at all, and let people simply define extension methods “manually”, by applying the appropriate attributes. Given that extension methods are consumed (which we have always supported) much more often than defined, we figured this was a good enough compromise, for the time being.

Then, a couple months back, i was doing some language research, among with was watching the introduction video for Go, the new system language created by Google. While in general Go’s syntax felt, to me, like C/C++ beaten with the ugly stick (no offense), it introduced some nice concepts, and one thing that struck me was how easily Go allowed to declare new methods for a class.

This, i thought, was how extension methods should work like, in Prism. An extension method, ultimately, should not have to be part of some arbitrary class that has nothing to do with that method or with the class you are extending. Forcing extension methods into a class syntax is not proper Object Orientation – on the contrary, it’s an abuse of OO syntax. And why shouldn’t you be able to just go ahead and declare the method – without having to learn some awkward syntax or rules?

i decided you should, and after convincing Carlo to do the actual implementation, i am happy to let you know you that starting with the upcoming Spring release of Delphi Prism, you can now define extension methods by, well, just defining them.

Behold:

extension method Int32.Twice: Int32;
begin
  result := self*2;
end;

If we overlook the new extension keyword for now, this looks like a regular method on Int32 – which, essentially, it is. There is no need to define an awkward “self” parameter; you just specify the method name prefixed with the type – as you’ve done thousands of times when writing your own classes – and the compiler takes it from there.

Only the extension keyword indicates that Int32 is not really your own class, but that you’re extending a class defined somewhere else.

This new syntax should make it much more convenient and attractive to define new extension methods, when and where you need them – without all the overhead of a class declaration.

Of course this works on more complex types, as well; the following complete program prints the square of all numbers between 0 and 100 – not by squaring the numbers, but by squaring the sequence of numbers. (It also shows off two other new language features we haven’t talked about yet ;)

namespace ExtensionMethods;
 
interface
 
uses
  System.Collections.Generic,
  System.Linq;
 
extension method IEnumerable<Int32>.Squared: IEnumerable<Int32>;
 
implementation
 
extension method IEnumerable<Int32>.Squared: IEnumerable<Int32>;
begin
  result := for each value in self yield value*value;
end;
 
begin
  var values := for i: Int32 := 0 to 100 yield i;
 
  for each i in values.Squared do
    Console.WriteLine(i);
end.

Let me know what you think!

Profile photo of marc

by marc

Delphi Prism, M.D.

July 13, 2009 in Elements, Linux, Mac, MonoDevelop, Windows

Over the past couple months, a lot of progress has been made with getting Delphi Prism integrated into MonoDevelop. As mentioned before (and in our ROadmap), one of the “big” focuses in the current product cycle leading up to the August release next month has been a major refactoring of our internal IDE code, both in preparation for Visual Studio 2010 (Beta 1 of which which we’ll be supporting in August) and MonoDevelop.

So without further ado, below you will find the first ever screenshot of Delphi Prism being fully integrated into Mono Develop on the Mac:

Notice how we have a working Class Browser, Syntax Highlighting and Code Completion, as well as integrated building using MSBuild/XBuild.

Of course MonoDevelop is taking shape on Windows as well and of course (always has) runs on Linux, and Delphi Prism will integrate with it on all three platforms. Windows, i suppose, is the least exciting of these three options (after all, we already have Visual Studio, there), but having a native IDE running on either Mac or Linux should be a great boon for everyone using Delphi Prism to develop for these platforms.

So what’s the time line here, you’re asking? Good question! I cannot quite confirm a specific ship date, for two reasons. For one, while basic integration is working, there’s still a lot of Ts to dot and Is to cross. Lockdown for the August releases is imminent, so MonoDevelop definitely will not make it into that (also due to reason #2) – but then, hey, one new IDE per release should be enough, right?

Secondly, there’s still the remaining issue of MonoDevelop being licensed under GPL. The MD team, our team and a few contributors from the Delphi Prism community have done a great job moving this forward, but we still have some ~20 or so modules left that need to be rewritten before MonoDevelop is non-GPL and we can ship integration for it. Your help would be appreciated with this, so if you have some spare time, please check out our remobjects.public.oxgene.md-project newsgroup to see how you can help (or drop me a direct mail).

As far as our coding efforts go, i would think we should be ready to ship a preview of MonoDevelop support sometime between the August and November releases. i would also hope that come November, MD will be GPL-clean, and we can officially ship this in the November release of Delphi Prism*.

Also, what about Sharp Develop? To be honest, we’re undecided. While SharpDevelop (a Windows-only IDE for .NET and Mono) is closely related to MonoDevelop, it is different enough that supporting it would mean extra work. With MonoDevelop starting to look good on Windows now, we’re not sure if there’s much sense going thru the effort to integrate with SharpDevelop as well. What’s your thought on that? Can you see any benefits to SD support (that MD does not cover)?

*So if you’re buying RAD Studio 2010, not Delphi Prism standalone, make sure to get Software Assurance to be eligible for new features in November!

Compiling and running monodevelop from VS.NET

May 20, 2009 in Mono, MonoDevelop

I’ve been spending a bit of time on MonoDevelop this week and gathered this information to get going with MonoDevelop.

First of all, you need GTK:
GTK the “GTK# for .NET” binary (just install that)

Also you need this zip file for binaries, or grab them yourself:
ICSharpCode.SharpZip.dll (from mono 2.4/lib)
MonoDoc.dll (from mono 2.4/lib)
Mono.Posix.dll (from mono 2.4/lib)
MonoPosixHelper.dll (from mono 2.4/bin); this will need to be copied next to the MonoDevelop binaries
Mono.Addins.* (compiled version of http://anonsvn.mono-project.com/source/trunk/mono-addins)

Place these files in a directory and add a registry entry for them so VS.NET can find them:

(win64)
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\MonoBinaries]
@="D:\\Projects\\MD-checkouts\\bin"
(win32)
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\MonoBinaries]
@="D:\\Projects\\MD-checkouts\\bin"

Monodevelop itself can be fetched from:
http://anonsvn.mono-project.com/source/trunk/monodevelop

Then open the sln file in the source dir. Change the Configuration to DebugWin32 and go to Build/Configuration manager. Check all projects except:
GnomePlatform
MacPlatform
MonoDevelop.NUnit (unless you have nunit)
MonoDevelop.XmlEditor.Tests (unless you have nunit)
UnitTests (unless you have nunit)

apply this temporary change (fixed in GTK svn already):

Index: main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs
===================================================================
--- main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs	(revision 134437)
+++ main/src/core/Mono.Texteditor/Mono.TextEditor/TextEditor.cs	(working copy)
@@ -292,7 +292,7 @@
Gtk.TargetList list = new Gtk.TargetList ();
list.AddTextTargets (ClipboardActions.CopyOperation.TextType);
-			Gtk.Drag.DestSet (this, DestDefaults.All, (TargetEntry[])list, DragAction.Ask | DragAction.Default | DragAction.Move |Â DragAction.Copy);
+			//Gtk.Drag.DestSet (this, DestDefaults.All, (TargetEntry[])list, DragAction.Ask | DragAction.Default | DragAction.Move |Â DragAction.Copy);
imContext = new IMMulticontext ();
imContext.Commit += IMCommit;

Set the startup Project to Mono.Startup and run it.
When you get a “File in use” error during compiling after you ran it before, open the task manager and kill the mdhost.exe task.

Open source project website

April 2, 2009 in .NET, Cocoa, Delphi, Elements, Free Pascal, Linux, Mac, Mono, MonoDevelop, RemObjects, Tools, Visual Studio, Windows, Xcode

For a while we’ve been looking for a good way of working with the open source projects we’re working on but never could find a good community website that was simple enough to install and maintain, but had all the features we needed.

So now we setup a simple website at http://code.remobjects.com for 3 projects:

  • ShineOn the delphi/Win32 compatibility library for Delphi Prism
  • Pascal Script the free script engine for Delphi
  • C# to Oxygene a new (unofficial) project I’ve been working on for a while to convert C# code to Oxygene.

Comments on the website appreciated, it’s not definitive yet but I like it so far.

Delphi Prism AOP – Cirrus

February 6, 2009 in .NET, Elements, Mono, MonoDevelop, Visual Studio

In a future release of Delphi Prism later this year, we will be adding support for Aspect-Oriented Programming (AOP) through a new infrastructure we call “Cirrus”.

Delphi Prism’s AOP will make it possible to change the behavior of code, add or remove fields, properties, events or methods and even extra classes, by applying special kinds of attributes – Aspects – to classes or members.

Aspects are written in Prism itself, compiled into a separate library, and will be reusable by different projects. They will be fairly simply to write. To write an aspect, the developer would create a new class library, reference the RemObjects.Oxygene.Cirrus library, and create a new attribute class. This class should descend from System.Attribute, have a regular AttributeUsage() attribute to denote where it can be applied. The only difference from a regular attribute is that aspects implement one of the special interfaces, such as IMethodImplementationDecorator in the sample below, defined by Cirrus.

Aspect attributes will be loaded and instantiated by the compiler at compile time, and are given then chance to take very powerful influence on the code the compiler is generating.

In the example below, we are creating an aspect to decorate methods of the class it is applied to. This is done through the IMethodImplementationDecorator interface, which requires one single method, HandleImplementation to be implemented by the aspect. The compiler will call this method after a method body (implementation) for was generated and allows the aspect to take influence on the generated code and to change or augment it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
namespace ClassLibrary1;
interface
uses
  RemObjects.Oxygene.Cirrus;
type
  [AttributeUsage(AttributeTargets.Class or AttributeTargets.Struct)]
  LogToMethodAttribute = public class(System.Attribute, IMethodImplementationDecorator)
  private
  protected
  public
    [Aspect:AutoInjectIntoAspectAttribute]
    class method LogMessage(aEnter: Boolean; aName: String; Args: Array of object);
    method HandleImplementation(Services: IImplementationServices; aMethod: IMethodDefinition);
end;
 
implementation
 
class method LogToMethodAttribute.LogMessage(aEnter: Boolean; aName: String; Args: Array of object);
begin
  if aEnter then
    Console.WriteLine('Entering '+aName)
  else
  Console.WriteLine('Exiting '+aName);
end;
 
method LogToMethodAttribute.HandleImplementation(Services: IImplementationServices; aMethod: IMethodDefinition);
begin
  if String.Equals(aMethod.Name, 'LogMessage', StringComparison.OrdinalIgnoreCase) then exit;
  if String.Equals(aMethod.Name, '.ctor', StringComparison.OrdinalIgnoreCase) then exit;
 
  aMethod.SetBody(Services, method begin
    LogMessage(true, Aspects.MethodName, Aspects.GetParameters);
    try
      Aspects.OriginalBody;
    finally
      LogMessage(false, Aspects.MethodName, Aspects.GetParameters);
    end;
  end);
end;
 
end.

In the fragment above, our aspect it compares the method name to “.ctor” and “LogMessage” (we do not want to augment those), and if they do not match, it adds calls LogMessage calls around the original method, protected by a try/finally.

The Aspects class is a special Compiler Magic Class provided by Cirrus that allows the aspect to take control of the code it is being applied to. Among other things, you see that it can query for the method name and the parameters, but also the body of the method in question, as written in the original source for the class.

By calling SetBody() on the method, the aspect can replace the body of the generated code (in this case, by taking the original body and surrounding it my our calls to LogMessage. Note how the new method body is being provided as plain, readable Prism code, in form of an extension to the anonymous method syntax.

It is also worth noting that the LogMessage method of our aspect has an aspect of their own applied. The [aspect:AutoInjectIntoClass] is an aspect defined by Cirrus itself, and it’s intended for use within aspects only. What it does is cause the member (in this case the LogMessage method to be added to the class the aspect is applied to.

This is necessary since our aspect makes use of LogMessage() in the new and augmented method body – but no such method is likely to exist in the target object. Without AutoInjectIntoClass, all the logic for LogMessage would need to be crammed into the SetBody call – making it potentially harder to read, but also potentially duplicating a lot of code and logic.

The following application makes use of our Log aspect:

namespace CirrusTest;
interface
uses
  ClassLibrary1, System.Linq;
 
type
  [Aspect:LogToMethod]
  ConsoleApp = class
  public 
    class method Main;
    class method Test(S: string);
  end;
 
implementation
 
class method ConsoleApp.Main;
begin
  // add your own code here
  Console.WriteLine('Hello World.');
  Test('Input for Test');
end;
 
class method ConsoleApp.Test(S: string);
begin
  Console.WriteLine('TEST: '+s);
end;
end.

We simply created a new console app that references the aspect library we created above, as well as the Cirrus library. (it’s important to note, though, that because aspects are applied at compile time, the final executable will not depend on the aspect library or on Cirrus, anymore!)

Running and debugging this program will output a log message at the beginning and end of each method, just as specified inour aspect was designed.

Entering Main
Hello World.
Entering Test
TEST: Input for Test
Exiting Test
Exiting Main

As you can see in Reflector, the LogMessage method has also been injected into to our class, and the reference section lists only mscorlib – RemObjects.Oxygene.Cirrus.dll and our aspect .dll do not need to be deployed for the application to run. And of course the method bodies for Test and Main show the augmented calls to LogMessage:

The Cirrus library and infrastructure you are seeing here is still under development, and might still see substantial changes and refinements, API wise, until it ships. However, the above should show the general concepts of how we see this new feature being exposed to developers. We think Cirrus will be will be a useful and powerful addition to Delphi Prism’s language.

Cirrus

Chrome on Linux

November 19, 2007 in Elements, MonoDevelop, Platforms

Last week we’ve started looking into MonoDevelop integration for Chrome. MonoDevelop is an open source GTK based IDE for Linux. It has support for GTK# form design, C#, VB.NET and other languages and comes with a rich plugin model. MonoDevelop support for Chrome is planned for the V3 “Oxygene” release. with some help I’ve managed to get syntax highlighting, compiling and the compiler options working:

Vinci Part #5 – Super HTTP Channel

April 28, 2007 in .NET, Delphi, Free Pascal, Linux, Mac, Mono, MonoDevelop, Visual Studio, Windows

One of the new features of RemObjects SDK for Delphi and .NET in version 5 will be the Super HTTP Channel. This channel is a variation on the regular HTTP channel but supports two way traffic like the Super TCP Channel. Because it uses HTTP, it works through HTTP proxies and strict firewalls, it does however cause slightly more traffic than the TCP version.

The new HTTP Channel allows you to send multiple requests without having to use multiple HTTP channels. It also makes it possible to send an event from the server to the client without having to explicitly poll for it. It works by using two connections at once, one for sending, the other for receiving.

As side-effect of the implementation for .NET, we have introduced a new “normal” HTTP server component in Internet Pack: AsyncHTTPServer. The Async HTTP Server uses Windows built in IO Completion Ports to handle requests, which uses less threads than the traditional blocking sockets model. Besides the Internet Pack based server, we also have an ASP.NET “Handler” and an http.sys async implementation.