Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
haXe 2 Beginner's Guide

You're reading from  haXe 2 Beginner's Guide

Product type Book
Published in Jul 2011
Publisher
ISBN-13 9781849512565
Pages 288 pages
Edition 1st Edition
Languages

Table of Contents (21) Chapters

haxe 2
Credits
Foreword
About the Author
About the Reviewers
www.PacktPub.com
Preface
1. Getting to know haXe 2. Basic Syntax and Branching 3. Being Cross-platform with haXe 4. Understanding Types 5. The Dynamic Type and Properties 6. Using and Writing Interfaces, Typedefs, and Enums 7. Communication Between haXe Programs 8. Accessing Databases 9. Templating 10. Interfacing with the Target Platform 11. A Dynamic Website Using JavaScript 12. Creating a Game with haXe and Flash Pop Quiz Answers Index

Chapter 3. Being Cross-platform with haXe

Targeting different platforms with the same code-base.

This chapter is about how to target several platforms from the same haXe code – the thing that haXe is known for.

haXe allows us to target several platforms; so, you may want to take advantage of this feature to be able to use your applications or libraries on several platforms. Unfortunately, there are some drawbacks, but don't worry, we will go through them and see how to work around them.

In this chapter, we will:

  • See what is cross-platform in the standard library

  • Talk about platform-specific packages

  • Learn about their specificities

  • Learn about conditional compilation

So, not only are we going to talk about being cross-platform, but also about platform-specific things. So, if you're ready, let's get started!

What is cross-platform in the library


The standard library includes a lot of classes and methods, which you will need most of the time in a web application. So, let's have a look at the different features. What we call standard library is simply a set of objects, which is available when you install haXe.

Object storage

The standard library offers several structures in which you can store objects. In haXe, you will see that, compared to many other languages, there are not many structures to store objects. This choice has been made because developers should be able to do what they need to do with their objects instead of dealing with a lot of structures, which they have to cast all the time.

The basic structures are array, list, and hash. All of these have a different utility:

  • Objects stored in an array can be directly accessed by using their index

  • Objects in a list are linked together in an ordered way

  • Objects in an hash are tied to what are called "keys", but instead of being an Int, keys are...

Platform-specific packages


You've already understood that there are some platform-specific packages, let's have an overview of them.

JavaScript

The platform-specific package for JavaScript is the js package. It basically contains only typedefs representing the DOM and has a layout that's not comparable to any one of the other platform-specific package.

Flash

As we've already mentioned, Flash has two platform-specific packages: the first one is flash and it is used when targeting Flash up to Flash 8, or else, you use the flash9 package (but access it by writing flash). Those packages contain definitions for the external classes that are natives in Flash. Their layouts are not comparable to any other platform-specific packages.

Neko

Neko has its own package named neko . It contains a lot of useful classes allowing for example, sockets communication, file-system access, console input and output, and threads management.

Its layout is comparable to the layouts of the C++ and PHP packages.

PHP

The php...

Conditional compilation


haXe allows you to do conditional compilation. This means that some parts of the code can be compiled and others can be ignored depending on the flags you give to the compiler and depending on the platform you're targeting.

Conditional compilation instructions always begin with the #if instruction.

Conditional compilation depending on flags

You can define a flag on the command line by using the –D switch. So, to define the myway flag, you would use the following: -D myway.

Then, you use it in the following way:

#if myway
//Code here compiled only if myway is defined
#else
//Code here compiled in the other case
#end

There is also a not operator:

#if !myway
//Code here compiled only myway is not defined
#end

Conditional compilation depending on the target

Conditional compilation depending on the target basically works in the same way, except that the name of the target you are compiling to automatically gets set. So, you will have something like the following:

#if cpp
//C++ code...

The remap switch


The compiler has a remap switch that allows us to rename a package, for example, imagine the following code:

//Some previous codemyPack.Lib.println("Hello remapping!");
//Some code following

This would obviously not work because the Lib class is not in the myPack package. However, if you compile with the switch --remap myPack:neko when compiling to Neko, this will work. The reason is simple: anywhere you have used the package name myPack; the compiler will replace it with Neko, therefore using the correct package.

This can be used to make some cross-platform code.

On the other hand, it has a big draw-back: when you remap a package, all of the modules it contains are remapped. This actually means that you won't be able to use something that is platform-specific inside this package.

Coding cross-platform using imports


We've already seen the import keyword that allows us to import all the classes of a module. This keyword can be used to write some cross-platform code. Indeed, it is the preferred way to do so, when working with packages that have the same layout. It has the advantage of being easily readable and does not mean adding three lines every time you want to access a platform-specific package.

So, here's a simple example: imagine you want to target Neko and PHP and want to use the println method available in neko.Lib.println and php.Lib.println (these methods allow you to write a line of text on the stdout). As you can see here, regarding what we are going to use, the neko and php package have the same layout (indeed, they have the same layout for quite a lot of their classes). So, we can write the following code:

#if php
import php.Lib;
#elseif neko
import neko.Lib;
#end

class Main
{
   public static function main()
   {
      Lib.println("Hello World");
   ...

Time for action – Welcoming the user on Neko & PHP


We are going to write a simple program that asks the user their name and prints a little welcome message along with the date. This program should work with the same codebase on Neko and PHP.

The following are the steps you should follow to write this program:

  1. Identify what classes you will need to print text and read from the keyboard.

  2. Identify what classes are in a platform-specific package.

  3. Add imports for those classes.

  4. Run and test.

  5. You should get the following output:

The following is the final code you should have produced:

#if neko
import neko.Lib;
import neko.io.File;
#elseif php
import php.Lib;
import php.io.File;
#end

class Main 
{
   
   static function main() 
   {
      //Print a prompt
      Lib.print("Please enter your name: ");
      //Read the answer
      var name = File.stdin().readLine();
      //Print the welcome message
      Lib.println("Welcome " + name);
      //Store the date
      var date = Date.now();
      //Concatenate...

Time for action – Reading from the XML file


We are going to create a function to read from an XML file. So, let's proceed step by step.

  1. First, create the Layer class as follows:

    class Layer
    {
       public var id : String;
       
       public function new()
       {}
    }
  2. Now create the Page class as follows:

    class Page
    {
       public var name : String;
       public var layers : List<Layer>;
       
       public function new()
       {
       }
    }
  3. Now, let's create a function to create a page from an XML file. Add the following function to the Page class:

    public static function fromXMLFile(path : String) : Page
    {
       var nPage = new Page();
       var xmlDoc = Xml.parse(neko.io.File.read(path, false).readAll().toString());
       nPage.name = xmlDoc.firstElement().get("name");
       
       return nPage;
    }
  4. As you can see, it is not yet complete. We have to parse a layer from the XML file, so let's do it now. Add the following function in the Layer class:

    public static function fromXMLNode(node : Xml)
    {
       var nLayer : Layer;
       nLayer = new Layer...

Time for action – Writing to an XML file


  1. We want to be able to write an XML file. To write the XML file, we will follow the same idea. Add the following function in the Layer class:

    public function toXMLNode() : Xml
    {
       var nXml = Xml.createElement("layer");
       nXml.set("id", this.id);
       return nXml;
    }
  2. Now, add the following code in the Page class:

    public function toXMLFile(path : String)
    {
       var xmlDoc = Xml.createDocument();
       var pageNode = Xml.createElement("page");
       pageNode.set("name", this.name);
       xmlDoc.addChild(pageNode);
       
       for(l in layers)
       {
          pageNode.addChild(l.toXMLNode());
       }
       
       neko.io.File.write(path, false).writeString(xmlDoc.toString());
    }

You can now save a page and all its layers by calling toXMLFile.

What just happened?

We have created a simple of the function in order to be able to save our page as an XML file by calling toXMLFile.

Testing our sample


The following is a sample main function if you want to try this code. It may also help you to understand how to use it:

public static function main(): Void
{
   trace('Hello World');
   trace(Page.fromXMLFile("/Users/benjamin/example.xml"));
   trace(Page.fromXMLFile("/Users/benjamin/example.xml"));
   
   var p = new Page();
   p.name = "Page de test";
   
   var l1 = new Layer();
   l1.id="l1";
   var l2 = new Layer();
   l2.id="l2";
   
   p.layers.add(l1);
   p.layers.add(l2);
   
   p.toXMLFile("/Users/benjamin/page1.xml");
}

Making it cross-platform


This code works on the Neko target. Using what we've learned about using imports to make code cross-platform, you can make this code work on PHP very easily. That's something you should try on your own to learn!

Summary


In this chapter, we've learned about how to do some cross-platform programming with haXe.

Specifically, we covered what is in the Standard Library, how to use conditional compilation and other ways to write cross-platform code, and how to handle XML files.

Now, let's move on to our next chapter in which we will talk about the typing system!

lock icon The rest of the chapter is locked
You have been reading a chapter from
haXe 2 Beginner's Guide
Published in: Jul 2011 Publisher: ISBN-13: 9781849512565
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at ₹800/month. Cancel anytime}