RemObjects Software Gears
 
       

CS2PAS 0.2

{#} by Carlo Kok 06/08/09 11:54:04 am, 116 words, Categories: main

Just uploaded CS2PAS 0.2, this release should be able to do a conversion of the most common C# constructs. Download

Changes:

* 36: Bad conversion of array typed variable
* 37: Error during processing: Index was out of range.
* 40: Char constants declared like '\x1A' cannot be converted
* 39: this. keyword is not converted to self.
* 30: && and || operators should automatically add parenthesis
* 29: simple "if (x) return" gets way to verbose
* 42: Class marked as internal is left using the internal keyword
* 31: DO for while, with and the others should do a space first
* 25: constructors get emitted with class name, in decl
* 24: "protected" gets translates as "assembly or protected"
* 26: inherited calls dont lose the dot
* 28: switch statement gets converted badly

Compiling and running monodevelop from VS.NET

{#} by Carlo Kok 05/20/09 01:17:03 pm, 325 words, Categories: main

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.

CSharp to Oxygene 0.1

{#} by Carlo Kok 04/10/09 06:55:42 pm, 52 words, Categories: main

I've just written a new tool that converts C# code to Prism code. It's the first version, and it's still a work in progress, but the first release is out, and available on:

http://code.remobjects.com/p/csharptoxy/

It includes the source (in SVN) and is licensed as MPL. Feedback appreciated.

Open source project website

{#} by Carlo Kok 04/02/09 09:52:58 pm, 109 words, Categories: main

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

{#} by Carlo Kok 02/06/09 04:21:05 pm, 940 words, Categories: main

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:

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

Delphi prism: With matching ....

{#} by Carlo Kok 01/13/09 10:31:18 am, 120 words, Categories: main

a while ago we implemented a very useful feature called with matching. With matching is like with, but it does an <> nil check, and jumps over the whole block if it's nil. This makes it possible to replace this:

if lMyObj is MyType then begin
  var lMyTypeRef := lMyObj as MyType;
  lMyTypeRef.Prop1 := ..
  lMyTypeRef.Prop2 := ..
  lMyTypeRef.Prop3 := ..
  lMyTypeRef.Prop4 := ..
  lMyTypeRef.Method1()
  lMyTypeRef.Method2()
...
end;

with:

with matching lMyTypeRef := MyType(lMyObj) do begin
  lMyTypeRef.Prop1 := ..
  lMyTypeRef.Prop2 := ..
  lMyTypeRef.Prop3 := ..
  lMyTypeRef.Prop4 := ..
  lMyTypeRef.Method1()
  lMyTypeRef.Method2()
...
end;

The matching keyword was originally introduced to allow a for each loop only process items that match a specific type like:

for each matching el: string in myarraylist do begin
  MessageBox.Show(el);
...
end;

DataAbstract, RemObjects, Linq and Silverlight support

{#} by Carlo Kok 06/26/08 03:17:27 pm, 137 words, Categories: main

We've been working on some very cool things here at ro, one of which is:

screenshot

What's shown here is a Silverlight 2.0 beta2 object inside Internet Explorer that fetches data using a LINQ query to a DA server using RO using DA-SQL (more on that will follow in a blog posting from Marc) fetched and sent back to the server, all running asynchronously. The grid used is the excellent AgDataGrid from DevExpress.

New in the next DA/RO for .NET will be running requests asynchronously, this will make it possible to run a RO or DA request non-blocking and get a threaded callback once the data (or exception) is ready, this will even work with DA/LINQ. Another new feature is Silverlight support in RO and DA, and DA-SQL which will be covered in the following blog posts.

Bug Database, Chrome and MVC ASP.NET

{#} by Carlo Kok 04/10/08 01:28:30 pm, 623 words, Categories: main

For those unfamiliar with MVC, MVC stands for Model View Controller. It's a way of separating the logic (controller), from the gui (view), and the data (model). The model contains all data needed by the view, the view shows it, and if an action occurs, passes the action to the controller, which does the logic, and updates the model again, so the view can be refreshed. The advantage of this is that, even though it ends up with more code, the code is a lot more readable, as the code needed for the gui isn't mixed up with the logic needed for validation and the data isn't in the view, but separated from the view, which just has a copy, it's also a lot easier to reuse code to write a new view (for example, a web interface and a windows forms interface on the same data) as it's not so tightly bound together.

Recently I've been looking at MVC frameworks for ASP.NET to improve code quality and ease of adding features. I have looked at both MonoRail and the MVC extensions for ASP.NET. And decided that even though it's beta, the official MVC extensions for ASP.NET is the way to go.

The ASP.NET MVC extensions come with templates for C# and VB, and although we are going to provide templates for it in Chrome, we can't do that till it's finalized; these extensions change quite a bit between releases. But the project is fairly simple, it's a Web Application Project, a standalone Class Library with a ProjectTypeGuid for ASP.NET, output directory for both profiles set to Bin/. Copying the web.config file, and using the same directory structure. The MVC logic uses a directory structure like:

  • Content (Folder containing anything you want to provide directly to the user, like css and images)
    • Site.css (Default Css style for the project)
  • Controllers (Folder containing the source code for the controllers)
    • HomeController.pas
  • Model (Data classes for the project)
  • View (directory containing all the views)
    • Home (view for the "Home" controller)
      • Index.aspx (asp.net page for the "Index" action)
      • Index.aspx.pas (code behind for the index action; descends from System.Web.Mvc.ViewPage)
      • About.aspx (asp.net page for the "About" action)
      • About.aspx.pas (code behind for the about action; descends from System.Web.Mvc.ViewPage)
    • Shared (view for the master page)
      • Site.Master (master page for the project)
      • Site.Master.Pas (code behind class for the master page, descends from System.Web.Mvc.ViewMasterPage)
  • Default.aspx (dummy page to redir to the action page)
  • Global.asax (application initialization)
  • Global.asax.pas (application initialization; sets up the mapping from /Controller/Action to the actual controller and view

As a project to play with this new framework I decided to tackle the long-standing issue for a web interface for our bug databases (we use a combination of MantisBT and a custom application using Data Abstract). We already had a simple login-da service for these databases, so the only thing needed was the actual web interface for it. Writing something using MVC takes practice, but it's not hard; using a Remote Data Adapter to grab the data from the server; storing it in a List<ListingItem> to pass to the view for the issue index. Another model was used for the per-issue listing. The view was kept as simple as possible, to just show the data.

Combining the power of ASP.NET, MVC, Chrome and Data Abstract, writing a web interface for the bugdb was a simple task. The web gui still needs some finishing touches to make it look good, but the coding is done, so the new bug db gui should be available soon.

Moving to SVN

{#} by Carlo Kok 01/21/08 12:18:07 pm, 389 words, Categories: main

Recently we decided that, due to lack of updates on our current version control system and issues with it that didn't seem to ever get fixed, to move to Subversion. Subversion, as most will know is an open source version control system.

We had considered moving to subversion several times before, but never wanted to switch because of the hassle, the inability to move the history and lack of several features we really need in a client. Last year or so I had found .NET bindings for Subversion (part of the Anhk SVN VS.NET plugin), which I wrote a simple svn client based on top of. Besides that, I wrote a program that could enumerate the revision info from the old system into a database, and import them into SVN. A year later I sent Marc the code I had for the client and he finished it, into what now is Floss (see for more info on Floss.).

The moving wasn't easy. First of all, our old system used per-file revisions, but SVN did several files in a single revision, so what we had to do in the importer is find checkins that belong to eachother, in person, time and checkin comment and group them into a single group. Then change the SVN revision date and svn author so it had the proper date information, and then check the files in. The next step was to find where the old system branched it, and look through the labels for a hint at which version it was branched, as a branch wasn't named, we used a label on the non-branched revision that came after the branch with a "base label" for the new version. This way we could find out the branch was 1 version below the base label. After that we had to create tags for the most important labels into the tags directory.

Tricky as it was, after several test runs we managed to import the old repository into Subversion, so from today on, we'll be using Subversion only. It was an interesting experience to do all this, but nonetheless well worth it. We'll be working on Floss, expanding the things we need from a Subversion client, and we'll be all getting used to Subversion for the coming weeks but, we did it, we're ready for the future.

Useful Chrome language feature: Conditional exception handlders

{#} by Carlo Kok 12/06/07 01:00:02 pm, 129 words, Categories: main

A conditional exception handler is an on e: ... do block in an exception handler that has a where condition. This allows you to only catch an exception when all your conditions apply to it. Although we've had this feature since the first version of Chrome, it's not a very well known.

/// <summary>Reads data from a socket. Returns 0 when the socket was disconnected or reset by peer </summary>
class method Utilities.ReadData(Sock: Socket; Data: array of Byte): Integer;
begin
  try
    Result := Sock.Receive(Data, 0, Data.Length, SocketFlags.None);
  except
    on e: SocketException where e.ErrorCode = 10054 do 
      Result := 0; // Reset by peer
  end;
end;

Above block reads data from a socket, but it catches the "Reset by peer" exception, and returns 0, like it's a regular disconnect.

Chrome on Linux

{#} by Carlo Kok 11/19/07 01:53:41 pm, 66 words, Categories: main

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 #12 - XML-RPC PHP Client CodeGen

{#} by Carlo Kok 05/24/07 06:55:46 pm, 162 words, Categories: main

Yesterday I finished the article about XML-RPC in RemObject SDK (which can be found here).

XML-RPC is a Remote Procedure Call specification based on XML, similar to SOAP, but written to be as simple as possible, while still allowing for more complex data structures. As it is simple and easy to use, there are now many implementations for just about any programming language including C, Perl, PHP, Java, Javascript , Python, Delphi and .NET (the latter two are supported by the RemObjects SDK).

The cool new thing in V5 is a Service Builder code generation plug-in that creates .inc files to use from PHP. As XML-RPC doesn't have any metadata like WSDL has for a SOAP service, the declarations for using XML-RPC services have to be provided. To do this manually, the xmlrpcmsg for every call and the xmlrpcval for every parameter would need to be added by hand, making it much easier to make mistakes.

Check out the article for more info

Vinci Part #7 - "Internet Pack" for Delphi

{#} by Carlo Kok 05/04/07 06:28:54 pm, 235 words, Categories: main

When we started working on the Super HTTP Channel for Delphi, we soon realized that none of the TCP/IP socket wrappers we currently use were a good idea for the server part of the channel, as Indy, Synapse and BPDX all use one thread per connection - which would amount to 2 thread per client and wouldn't scale very well.

What we had to do is write our own socket wrapper that would work 100% async, like the .NET code does, and still would scale properly. Our new socket class uses Begin/End pairs for every method that would be blocking and accept a callback as a parameter for when the data was available, the connection accepted or the socket was ready to send data. The actual implementation uses the portable "select" call on 64 sockets at once, keeping the thread usage down quite a lot. On top of that we wrote our own simple Http server class, using only async callbacks.

We didn't tie the Super HTTP Channel to this socket implementation, however, instead we wrote an abstract implementation and a subclass that implements it based on the async IP code. So it's always possible to implement it on top of alternative HTTP server implementations.

We're considering the async socket and http layer to be the first step towards an "Internet Pack for Delphi" - although will be treating is a part of the RemObjects SDK, for now.

Vinci Part #5 - Super HTTP Channel

{#} by Carlo Kok 04/28/07 03:43:15 pm, 180 words, Categories: main

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.

Chrome WPF Video

{#} by Carlo Kok 11/09/06 10:45:32 am, 70 words, Categories: main

I spend some time with WPF this week and came up with a Quicksort demo for Chrome that uses WPF. The video can be found at:

http://remobjects.com/devcenter/videos/

And the sample itself can be downloaded too (It's at the end of the video). To run it yourself you need Chrome 1.5, the WPF runtime (.NET 3.0) and optionally the Orcas plugin for VS2005 (to open the XAML in VS2005).

DllMain Thread Deinitialization

{#} by Carlo Kok 10/05/06 01:45:03 pm, 243 words, Categories: main

I came across an interesting issue with Windows dll loading/unloading capabilities. The issue is that Windows does not return from an EndThread/ExitThread/TerminateThread when DllMain is running until it's done. This causes some interesting issues with the Delphi TThread class, which waits for the thread to be terminated to free it, so when a thread is freed from the finalization section of a unit in a dll, it will indefinitely wait. It's not possible to use FreeOnTerminate instead and keep it running. This would leave the thread running in address space that doesn't exist anymore.

There is no real workaround except changing the source code of TThread to stop waiting just before it reaches the ThreadProc's EndThread or writing your own TThread class. In writing a solution for use in the RemObjects SDK we had several problems. Obviously we couldn't change the Classes unit on every Delphi installation the ROSDK was installed. Another problem was that we support Delphi 6 and that doesn't expose a static Synchronize method, so the class had to descend from TThread. We had to do, what I consider one of the worst hacks but it looked like it was the only way. We reintroduced WaitFor, implemented it so it would return right before the thread was calling ExitThread, using a Windows event. After that we introduced a method to wait for it to finish and free it so it mimicked the existing behavior of the TThread destructor.

| Next >

 

Carlo Kok

Twitter

marc hoffman (follow)
    loading...
Mike Orriss (follow)
    loading...

Navigation

XML Feeds 

Who's Online?

  • Guest Users: 10