Wednesday, October 21, 2009

Section 24.1.  What Is PDE Build?










24.1. What Is PDE Build?


At its heart, PDE Build is an Ant script generator. It takes in a collection of plug-ins and features, their manifests and build.properties files, and generates a set of Ant build scripts. These scripts are run to produce a build. The export operations you have been doing throughout this book use PDE Build under the covers.


PDE Build is quite flexible. It can consume hybrid mixes of plug-ins and features that are pre-built and those that remain to be built. Some may be included in the final output, while others may not. The output of a build can also vary from plug-ins in directories to update sites and Zip archives of JAR'd and signed plug-ins and features.


The build mechanism builds plug-ins and features, or cascades of the transitively included features and plug-ins starting at a root feature. Cross-platform building is also supported.


The main benefit of PDE Build is that it brings all this together into one relatively simple process. Developers express their normal runtime dependencies in manifest files and a mapping from development time structure to runtime structure in the feature and plug-in build.properties files. PDE Build does the rest.


Key to this process is the automatic generation of the build scripts. Using the input manifests and build.properties, PDE generates Ant scripts that copy identified files and compile identified code using a classpath derived by effectively flattening the plug-in dependency graph. The runtime classpath for a plug-in is defined as a complex graph of plug-in dependencies as described in its manifest file. The classes referenced at runtime are also needed at compile-time, so the compile-time classpath is similarly complex. PDE Build uses the Runtime's plug-in resolution and wiring mechanisms to derive the classpath for each plug-in being built.


As we mentioned above, you have already been using PDE Build if you followed along with the feature- or product-exporting examples. When you use these actions, you are under the covers, running PDE Build. The rest of this chapter explores the use of PDE Build in a release engineering setting, where reproducibility and automation are key concerns.












Section 22.3.  Distributed Builds










22.3. Distributed Builds


If you have a large project and more than one Macintosh at your disposal, you can see dramatically shorter build times with distributed builds. A Macintosh can volunteer idle time for distributed builds by opening the Distributed Builds panel of the Preferences window (Figure 22.1) and checking the first checkbox in the panel. Xcode processes on other computers or even the same computer can then send portions of their builds to the volunteer for compilation. The volunteer can choose to give the distributed-build background process low, medium, or high priority.



Figure 22.1. The Distributed Builds panel of the Xcode Preferences window. The upper checkbox makes this machine available to others for compiling modules. The lower checkbox makes this machine a host for distributed builds, either on every machine that advertises itself on the local Bonjour net as a distcc node or on only those listed machines you mark as trusted.

[View full size image]




If you want to take advantage of distributed builds, check the second checkbox in the Distributed Builds panel of the Preferences window. The list below the checkbox will then fill with the names of all the local net's computers that are advertising via Bonjour (formerly Rendezvous) that they can take distributed builds. You can choose to distribute work to all comers or only to the machines you indicate in the list are trusted.


Each machine participating in a distributed build must be running the same architecture and the same versions of Mac OS X, gcc, and Xcode. Xcode need not be running on the distributed machines.


No matter what your Distributed Builds settings, some tasks are always done on the home machine of the build. In particular, the home machine builds precompiled headers and does preprocessing before sending out compilation units. Because the home machine has work to do that no other machine can, it is wisest not to enable the local machine as sharable for distributed builds. Distributed compilation can't benefit from more than about six remotes; beyond that point, the local machine is spending all its time assembling preprocessed compilands for the remotes and becomes the limiting factor.


Remember that distributing the source and getting the compiled objects back takes time. Distributed builds may be a net loss in productivity if you use it on a network of less than 100Mb/second capacity. This rules out wireless and 10Base-T networks.


If you are dealing with a firewall, be sure that it passes the distributed-build ports of 3632 and 7264.












26.5 OpenGL in the Pop Framework



[ Team LiB ]










26.5 OpenGL in the Pop Framework


Look back at the code for CPopView::OnDraw(CDC* pDC)
that we gave in Section 24.4: Graphics in the Pop Framework. Here is a bulleted list showing some of the corresponding OpenGL calls made by the _pgraphics member of CPopView
if _pgraphics is of the type cGraphicsOpenGL*.



  • Wake up the graphics with


    _pgraphics->activate().

    This calls



    ::wglMakeCurrent( _pDC->GetSafeHdc(), _hRC )

  • Clear the graphics background with


    _pgraphics->clear(targetrect).

    This calls



    ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  • Install the projection and view matrices with these lines.


    _pviewpointcritter->loadProjectionMatrix();
    _pviewpointcritter->loadViewMatrix();

    These in turn call:



    ::glMatrixMode(GL_MODELVIEW)
    ::glLoadMatrixf(_pviewpointcritter->attitude().inverse());
    ::glMatrixMode(GL_PROJECTION)
    ::gluPerspective (fieldofviewangleindegrees, xtoyaspectratio,
    nearzclip, farzclip); //Values from _pviewpointcritter

  • Draw your game world and then the critters with


    pgame()->drawCritters(_pgraphics, _drawflags).

    This generates a variety of ::gl
    and ::glu
    calls like, in the case of polygons



    ::glEnableClientState(GL_VERTEX_ARRAY);
    ::glVertexPointer(...);
    ::glDrawArrays(...);

  • Send the graphics to your video display with


    _pgraphics->display(this, pDC)

    This calls



    ::glFinish();// Tell OpenGL to flush its pipeline
    ::SwapBuffers( _pDC->GetSafeHdc() ); // Now Swap the buffers






    [ Team LiB ]



    Section 10.5. XSLT Concepts










    10.5. XSLT Concepts


    When developing an XSL style sheet, I usually find myself using only two of the XSL functions shown earlier: the key() function and the generate-id() function, both of which are indispensable when doing something unique to XSL style sheets. I am referring to something called Muenchian grouping.


    Muenchian grouping, invented by Steve Muench, the XML Evangelist of the Oracle Corporation, is a method of grouping nodes based upon their values. Although I can describe how it works, it is probably a better idea to take a look at the example of Muenchian grouping shown in Listing 10-13. After that, we take it apart to see how it works.


    Listing 10-13. A Muenchian Grouping Example





    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:key name="keyBook" match="book" use="series" />

    <xsl:template match="/">

    <xsl:element name="table">
    <xsl:attribute name="width">100%</xsl:attribute>

    <xsl:apply-templates select="//book[1]" mode="header" />
    <xsl:apply-templates select="//book[generate-id(.) = generate-
    id(key('keyBook',series)[1])]" />
    <xsl:apply-templates select="//book[string-length(series) =
    0]/series" />
    </xsl:element>

    </xsl:template>

    <xsl:template match="book">

    <xsl:variable name="key">
    <xsl:value-of select="series" />
    </xsl:variable>

    <xsl:apply-templates select="//series[node() = $key]" />

    </xsl:template>

    <xsl:template match="series">

    <xsl:element name="tr">
    <xsl:apply-templates select="parent::node()/*" mode="cell" />
    </xsl:element>

    </xsl:template>

    <xsl:template match="*" mode="cell">

    <xsl:element name="td">
    <xsl:attribute name="align">left</xsl:attribute>

    <xsl:value-of select="." />
    </xsl:element>

    </xsl:template>

    <xsl:template match="book" mode="header">

    <xsl:element name="tr">
    <xsl:apply-templates select="./*" mode="columnHeader" />
    </xsl:element>

    </xsl:template>

    <xsl:template match="*" mode="columnHeader">

    <xsl:variable
    name="lowerCase">qwertyuiopasdfghjklzxcvbnm</xsl:variable>
    <xsl:variable
    name="upperCase">QWERTYUIOPASDFGHJKLZXCVBNM</xsl:variable>

    <xsl:element name="th">
    <xsl:attribute name="width">33%</xsl:attribute>

    <xsl:value-of select="translate(name(.),$lowerCase,$upperCase)" />
    </xsl:element>

    </xsl:template>

    </xsl:stylesheet>




    The element that starts the whole ball rolling is the key element, which creates a cross-reference based upon the node specified by the use attribute. Using the series element as the key results in an index consisting of The Lord of the Rings and Lord Darcy, with the book The Way Station left out because its series element is null. This cross-reference is accessed using the key function, which accepts two parameters: the name from the key element and the node.


    Another function that plays an integral part in Muenchian grouping is the generate-id function. This function, well, generates a unique ID for every node in an XML document every time that the document is processed. So the XPath statement //book[generate-id(.) = generate-id(key('keyBook',series)[1])] locates the first element with each unique key from the cross-reference and applies the matching template. The matching template then uses the unique series to select the matching elements.


    It is all pretty basic XSLT and XPath stuff, although it does have a tendency to make grown men whimper like little scared puppies. If it doesn't, here is one that will put someone over the edge: Imagine trying to group based upon multiple criteria, such as author and series. Although it isn't done very often, and you'll probably never have to do it, I'll give you a hint: Concatenate the elements using the concat function.












    Initialization








    Initialization


    In the last section, you introduced the numberOfStudents field and initialized it to 0. This initialization is technically not requiredint fields are initialized to 0 by default. Explicitly initializing a field in this manner, while unnecessary, is useful to help explain the intent of the code.


    For now, you have two ways to initialize fields: You can initialize at the field level or you can initialize in a constructor. You could have initialized numberOfStudents in the CourseSession constructor:



    class CourseSession {
    private String department;
    private String number;
    private int numberOfStudents;

    CourseSession(String department, String number) {
    this.department = department;
    this.number = number;
    numberOfStudents = 0;
    }
    ...


    There is no hard-and-fast rule about where to initialize. I prefer initializing at the field level when possiblehaving the initialization and declaration in one place makes it easier to follow the code. Also, as you will learn later in this lesson, you can have more than one constructor; initializing at the field level saves you from duplicate initialization code in each constructor.


    You will encounter situations where you cannot initialize code at the field level. Initializing in the constructor may be your only alternative.








      Hour 8








       

       



      Hour 8








      1:

      Why would you want to include a .resx file in your project rather than just including the already compiled .resources file?


      A1:

      In case you need to make changes to the resources contained within the .resx file. You can't make changes to a compiled .resources file.


      2:

      What is an advantage of using managed resources compared to unmanaged resources? What are some disadvantages?


      A2:

      Managed resources are handled by the common language runtime and thus gain all the advantages that it entails. However, there is currently more work that needs to be done to Visual C++ .NET to make working with managed resources easier.


      3:

      Can you use the GetObject function within the ResourceManager class to retrieve a string resource?


      A3:

      Yes, you can. The GetString function is just a modified GetObject call that automatically performs the cast from the Object type to the String object. You can call GetObject and cast to a String object to retrieve a string resource.













       

       





      Top

      Digital Game Spaces











       < Day Day Up > 











      Digital Game Spaces



      Although games have been played in real-world spaces for millennia, the appearance of electronic and digital games in the last few decades have provided new kinds of game spaces: playgrounds that exist only on the screens of computer monitors and televisions. These game spaces take a multitude of forms, from blocky 2D grids to expansive 3D worlds. One useful taxonomy for describing the range of these digital spaces comes from Mark J. P. Wolf, in his essay "Space in the Video Game." Wolf lists eleven ways that video games operate to structure and represent space. We paraphrase these categories below, with examples from Wolf's essay:











      • Text-only space: text adventure games such as Zork and Planetfall





      • One contained screen: Pong, Space Invaders, Breakout





      • One screen with wraparound: Asteroids, Pac-Man (with teleporter wraparound)





      • Scrolling on one axis: Defender, Atari's Football arcade game





      • Scrolling on two axes: Gauntlet, Sim City





      • Adjacent spaces displayed one room at a time: Berzerk, Atari's Adventure





      • Scrolling with separate background layers: Zaxxon, Double Dragon





      • Limited 3D space: Tempest, Night Driver





      • Two spaces on one screen or two separate screens: Spy vs. Spy, Dactyl Nightmare





      • Full 3D spaces: Battlezone, DOOM, Tomb Raider





      • "Mapped" Spaces: Defender, Myst (both have a separate radar or map display) [9]




      Wolf 's categories are not without some conceptual problems. For example, there is a fundamental difference between a "two-and-a-half" dimensional space like DOOM and a more fully 3D space like Tomb Raider (in DOOM the player can only move in two dimensions and the objects are completely flat). Additionally, some of his categories, such as separate background scrolling layers and "mapped" spaces, seem to be fuzzier designations (most of the categories he lists could also incorporate a "map" element). Wolf's typology is certainly not the only way to conceptualize digital game spaces, but his categories are useful in pointing out the wealth of forms they take.






      Zork: Text-only space

      The structure of a digital game space always grows directly from the formal system that defines the game. However, the space that a player experiences is also a function of representation (how the space is displayed to the player) and interaction (how a player navigates through the space). These three ele-ments—formal structure, structure of display, and interactive structure—together constitute the experience of a digital game space. All three of them need to be designed in concert to achieve proper narrative effect in your game.


      For example, the feeling of zero-G drift in Asteroids is linked directly to the design of the game space. Rather than bouncing off the screen wall like a Pong ball, the player's ship moves right on through to the other side, evoking the illusion of endless movement through the darkness of space. The game's style of movement, emphasizing inertial drift and retro-rocket maneuvers, also heightens the feeling of space travel. Although the player's ship never leaves the screen, at the beginning of each wave, asteroids drift in from the edges. Once they appear, these asteroids follow the same wraparound logic as the player's ship. Other objects, such as the UFO saucers, don't ever wrap around, and simply disappear once they reach the edge of the screen. Curiously, these inconsistencies never break the game's spatial continuity. The fact that some objects remain constantly on screen (the player's ship and existing asteroids) whereas others seem to drift in from parts unknown (new asteroids and UFOs), adds up to a rich and multi-layered narrative of cosmic exploration and survival. Space creates narrative in all senses of Miller's definition: space helps define the "characters"(the game objects); space is the context in which narrative events occur; and space patterns narrative experience over time for the player.






      Asteroids: One screen with wraparound





      Tempest: Limited 3D space





      Tomb Raider: Full 3D space





      Double Dragon: Scrolling with separate background layers





      Spy vs. Spy: Two spaces on one screen





      Defender: "Mapped" space

      The design of a game space creates a context for narrative interaction, by structuring events in patterns of space, time, and causality. As Marsha Kinder notes in Playing with Power in Movies, Television, and Video Games, " Narrative creates a context for interpreting all perceptions. Narrative maps the world and its inhabitants, including one's own position within that grid."[10] The narrative play of games is always connected to an underlying grid of possibility, to goals and conflict, to uncertainty and the moment-to-moment action of the core mechanic. The space of a game is quite literally its space of play.


      In a fighting game such as Tekken, the space is tightly constrained, crowding the two fighters up against each other. There is nowhere to run and nowhere to hide. All you can do is fight your opponent, an action the design of the space explicitly encourages and facilitates. In contrast, the corridors and rooms of a Quake deathmatch space create a narrative of stealthy maneuvers, mad dashes to grab power-ups, and the surprise of sudden death. Tekken has no hidden spatial information. But in Quake, walls block players from seeing each other, dark lighting makes hiding in shadows possible, and the periodically appearing power-ups create uncertainty about when and where they can be found. In both Tekken and Quake, a player's "position on the grid," as Kinder puts it, is simultaneously a location in the space of the game and a position within the space of the game narrative. The formal, represented, and interactive spaces of games are also narrative spaces, contexts for interpreting the experience of a game as a story.


      When we frame experience as narrative, the events and actions of game play take on form and meaning within the game's representational universe. The dynamic properties of the space of Tekken and Quake are important in creating emergent narratives of conflict. But the spaces contain embedded narrative qualities as well. In Quake, the spaces embody the sets, props, and characters of pulp sci-fi horror. In Tekken, as with most fighting games, each arena is thematically linked to one of the game's characters. Space can therefore be used to express information about a character's persona or backstory, or to create narratives about defending one's home turf or invading an enemy's territory.







      [9]Mark J. P. Wolf, "Space in the Video Game." In The Medium of the Video Game, edited by Mark J. P. Wolf (Austin: University of Texas Press, 2002), p.53-70





      [10]MarshaKinder, Playing with Power in Movies, Television, and Video Games: From Muppet Babies to Teenage Mutant (Los Angeles: University of California Press, 1993), p. 2.



















       < Day Day Up >