Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-nhibernate-30-testing-using-nhibernate-profiler-and-sqlite
Packt
06 Oct 2010
6 min read
Save for later

NHibernate 3.0: Testing Using NHibernate Profiler and SQLite

Packt
06 Oct 2010
6 min read
  NHibernate 3.0 Cookbook Get solutions to common NHibernate problems to develop high-quality performance-critical data access applications Master the full range of NHibernate features Reduce hours of application development time and get better application architecture and performance Create, maintain, and update your database structure automatically with the help of NHibernate Written and tested for NHibernate 3.0 with input from the development team distilled in to easily accessible concepts and examples Part of Packt's Cookbook series: each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on NHibernate, see here.) Using NHibernate Profiler NHibernate Profiler from Hibernating Rhinos is the number one tool for analyzing and visualizing what is happening inside your NHibernate application, and for discovering issues you may have. In this recipe, I'll show you how to get up and running with NHibernate Profiler. Getting ready Download NHibernate Profiler from http://nhprof.com, and unzip it. As it is a commercial product, you will also need a license file. You may request a 30-day trial license from the NHProf website. Using our Eg.Core model, set up a new NHibernate console application with log4net. (Download code). How to do it... Add a reference to HibernatingRhinos.Profiler.Appender.dll from the NH Profiler download. In the session-factory element of App.config, set the property generate_statistics to true. Add the following code to your Main method: log4net.Config.XmlConfigurator.Configure();HibernatingRhinos.Profiler.Appender. NHibernate.NHibernateProfiler.Initialize();var nhConfig = new Configuration().Configure();var sessionFactory = nhConfig.BuildSessionFactory();using (var session = sessionFactory.OpenSession()){ var books = from b in session.Query<Book>() where b.Author == "Jason Dentler" select b; foreach (var book in books) Console.WriteLine(book.Name);} Run NHProf.exe from the NH Profiler download, and activate the license. Build and run your console application. Check the NH Profiler. It should look like the next screenshot. Notice the gray dots indicating alerts next to the Session #1 and Recent Statements. Select Session #1 from the Sessions list at the top left pane. Select the statement from the top right pane. Notice the SQL statement in the following screenshot: Click on See the 1 row(s) resulting from this statement. Enter your database connection string in the field provided, and click on OK. Close the query results window. Switch to the Alerts tab, and notice the alert: Use of implicit transaction is discouraged. Click on the Read more link for more information and suggested solutions to this particular issue. Switch to the Stack Trace tab, as shown in the next screenshot: Double-click on the NHProfTest.NHProfTest.Program.Main stack frame to jump to that location inside Visual Studio. Using the following code, wrap the foreach loop in a transaction and commit the transaction: using (var tx = session.BeginTransaction()){ foreach (var book in books) Console.WriteLine(book.Name); tx.Commit();} In NH Profiler, right-click on Sessions on the top left pane, and select Clear All Sessions. Build and run your application. Check NH Profiler for alerts. How it works... NHibernate Profiler uses a custom log4net appender to capture data about NHibernate activities inside your application and transmit that data to the NH Profiler application. Setting generate_statistics allows NHibernate to capture many key data points. These statistics are displayed in the lower, left-hand side of the pane of NHibernate Profiler. We initialize NHibernate Profiler with a call to NHibernateProfiler.Initialize(). For best results, do this when your application begins, just after you have configured log4net. There's more... NHibernate Profiler also supports offline and remote profiling, as well as command-line options for use with build scripts and continuous integration systems. In addition to NHibernate warnings and errors, NH Profiler alerts us to 12 common misuses of NHibernate, which are as follows: Transaction disposed without explicit rollback or commit: If no action is taken, transactions will rollback when disposed. However, this often indicates a missing commit rather than a desire to rollback the transaction Using a single session on multiple threads is likely a bug: A Session should only be used by one thread at a time. Sharing a session across threads is usually a bug, not an explicit design choice with proper locking. Use of implicit transaction is discouraged: Nearly all session activity should happen inside an NHibernate transaction. Excessive number of rows: In nearly all cases, this indicates a poorly designed query or bug. Large number of individual writes: This indicates a failure to batch writes, either because adonet.batch_size is not set, or possibly because an Identity-type POID generator is used, which effectively disables batching. Select N+1: This alert indicates a particular type of anti-pattern where, typically, we load and enumerate a list of parent objects, lazy-loading their children as we move through the list. Instead, we should eagerly fetch those children before enumerating the list Superfluous updates, use inverse="true": NH Profiler detected an unnecessary update statement from a bi-directional one-to-many relationship. Use inverse="true" on the many side (list, bag, set, and others) of the relationship to avoid this. Too many cache calls per session: This alert is targeted particularly at applications using a distributed (remote) second-level cache. By design, NHibernate does not batch calls to the cache, which can easily lead to hundreds of slow remote calls. It can also indicate an over reliance on the second-level cache, whether remote or local. Too many database calls per session: This usually indicates a misuse of the database, such as querying inside a loop, a select N+1 bug, or an excessive number of writes. Too many joins: A query contains a large number of joins. When executed in a batch, multiple simple queries with only a few joins often perform better than a complex query with many joins. This alert can also indicate unexpected Cartesian products. Unbounded result set: NH Profiler detected a query without a row limit. When the application is moved to production, these queries may return huge result sets, leading to catastrophic performance issues. As insurance against these issues, set a reasonable maximum on the rows returned by each query Different parameter sizes result in inefficient query plan cache usage: NH Profiler detected two identical queries with different parameter sizes. Each of these queries will create a query plan. This problem grows exponentially with the size and number of parameters used. Setting prepare_sql to true allows NHibernate to generate queries with consistent parameter sizes. See also Configuring NHibernate with App.config Configuring log4net logging
Read more
  • 0
  • 0
  • 42449

article-image-getting-started-javafx
Packt
05 Oct 2010
11 min read
Save for later

Getting Started with JavaFX

Packt
05 Oct 2010
11 min read
  JavaFX 1.2 Application Development Cookbook Over 60 recipes to create rich Internet applications with many exciting features Easily develop feature-rich internet applications to interact with the user using various built-in components of JavaFX Make your application visually appealing by using various JavaFX classes—ListView, Slider, ProgressBar—to display your content and enhance its look with the help of CSS styling Enhance the look and feel of your application by embedding multimedia components such as images, audio, and video Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on JavaFX, see here.) Using javafxc to compile JavaFX code While it certainly makes it easier to build JavaFX with the support of an IDE (see the NetBeans and Eclipse recipes), it is not a requirement. In some situations, having direct access to the SDK tools is preferred (automated build for instance). This recipe explores the build tools that are shipped with the JavaFX SDK and provides steps to show you how to manually compile your applications. Getting ready To use the SDK tools, you will need to download and install the JavaFX SDK. See the recipe Installing the JavaFX SDK, for instructions on how to do it. How to do it... Open your favorite text/code editor and type the following code. The full code is available from ch01/source-code/src/hello/HelloJavaFX.fx. package hello;import javafx.stage.Stage;import javafx.scene.Sceneimport javafx.scene.text.Text;import javafx.scene.text.Font;Stage { title: "Hello JavaFX" width: 250 height: 80 scene: Scene { content: [ Text { font : Font {size : 16} x: 10 y: 30 content: "Hello World!" } ] }} Save the file at location hello/Main.fx. To compile the file, invoke the JavaFX compiler from the command line from a directory up from the where the file is stored (for this example, it would be executed from the src directory): javafxc hello/Main.fx If your compilation command works properly, you will not get any messages back from the compiler. You will, however, see the file HelloJavaFX.class created by the compiler in the hello directory. If, however, you get a "file not found" error during compilation, ensure that you have properly specified the path to the HelloJavaFX.fx file. How it works... The javafxc compiler works in similar ways as your regular Java compiler. It parses and compiles the JavaFX script into Java byte code with the .class extension. javafxc accepts numerous command-line arguments to control how and what sources get compiled, as shown in the following command: javafxc [options] [sourcefiles] [@argfiles] where options are your command-line options, followed by one or more source files, which can be followed by list of argument files. Below are some of the more commonly javafxc arguments: classpath (-cp)—the classpath option specifies the locations (separated by a path separator character) where the compiler can find class files and/or library jar files that are required for building the application. javafxc -cp .:lib/mylibrary.jar MyClass.fx sourcepath—in more complicated project structure, you can use this option to specify one or more locations where the compiler should search for source file and satisfy source dependencies. javafxc -cp . -sourcepath .:src:src1:src2 MyClass.fx -d—with this option, you can set the target directory where compiled class files are to be stored. The compiler will create the package structure of the class under this directory and place the compiled JavaFX classes accordingly. javafxc -cp . -d build MyClass.fx The @argfiles option lets you specify a file which can contain javafxc command-line arguments. When the compiler is invoked and a @argfile is found, it uses the content of the file as an argument for javafxc. This can help shorten tediously long arguments into short, succinct commands. Assume file cmdargs has the following content: -d build-cp .:lib/api1.jar:lib/api2.jar:lib/api3.jar-sourcepath core/src:components/src:tools/src Then you can invoke javafxc as: $> javafxc @cmdargs See also Installing the JavaFX SDK Creating and using JavaFX classes JavaFX is an object-oriented scripting language. As such, object types, represented as classes, are part of the basic constructs of the language. This section shows how to declare, initialize, and use JavaFX classes. Getting ready If you have used other scripting languages such as ActionScript, JavaScript, Python, or PHP, the concepts presented in this section should be familiar. If you have no idea what a class is or what it should be, just remember this: a class is code that represents a logical entity (tree, person, organization, and so on) that you can manipulate programmatically or while using your application. A class usually exposes properties and operations to access the state or behavior of the class. How to do it... Let's assume we are building an application for a dealership. You may have a class called Vehicle to represent cars and other type of vehicles processed in the application. The next code example creates the Vehicle class. Refer to ch01/source-code/src/javafx/Vehicle.fx for full listing of the code presented here. Open your favorite text editor (or fire up your favorite IDE). Type the following class declaration: class Vehicle { var make; var model; var color; var year; function drive () : Void { println("You are driving a " "{year} {color} {make} {model}!") }} Once your class is properly declared, it is now ready to be used. To use the class, add the following (highlighted code) to the file: class Vehicle {...}var vehicle = Vehicle { year:2010 color: "Grey" make:"Mini" model:"Cooper"};vehicle.drive(); Save the file as Vehicle.fx. Now, from the command-line, compile it with: $> javafxc Vehicle.fx If you are using an IDE, you can simply right, click on the file to run it. When the code executes, you should see: $> You are driving a 2010 Grey Mini Cooper! How it works... The previous snippet shows how to declare a class in JavaFX. Albeit a simple class, it shows the basic structure of a JavaFX class. It has properties represented by variables declarations: var make;var model;var color;var year; and it has a function: function drive () : Void { println("You are driving a " "{year} {color} {make} {model}!")} which can update the properties and/or modify the behavior (for details on JavaFX functions, see the recipe Creating and Using JavaFX functions). In this example, when the function is invoked on a vehicle object, it causes the object to display information about the vehicle on the console prompt. Object literal initialization Another aspect of JavaFX class usage is object declaration. JavaFX supports object literal declaration to initialize a new instance of the class. This format lets developers declaratively create a new instance of a class using the class's literal representation and pass in property literal values directly into the initialization block to the object's named public properties. var vehicle = Vehicle { year:2010 color: "Grey" make:"Mini" model:"Cooper"}; The previous snippet declares variable vehicle and assigns to it a new instance of the Vehicle class with year = 2010, color = Grey, make = Mini, and model = Cooper. The values that are passed in the literal block overwrite the default values of the named public properties. There's more... JavaFX class definition mechanism does not support a constructor as in languages such as Java and C#. However, to allow developers to hook into the life cycle of the object's instance creation phase, JavaFX exposes a specialized code block called init{} to let developers provide custom code which is executed during object initialization. Initialization block Code in the init block is executed as one of the final steps of object creation after properties declared in the object literal are initialized. Developers can use this facility to initialize values and initialize resources that the new object will need. To illustrate how this works, the previous code snippet has been modified with an init block. You can get the full listing of the code at ch01/source-code/src/javafx/Vehicle2.fx. class Vehicle {... init { color = "Black"; } function drive () : Void { println("You are driving a " "{year} {color} {make} {model}!"); }}var vehicle = Vehicle { year:2010 make:"Mini" model:"Cooper"};vehicle.drive(); Notice that the object literal declaration of object vehicle no longer includes the color declaration. Nevertheless, the value of property color will be initialized to Black in the init{} code block during the object's initialization. When you run the application, it should display: You are driving a 2010 Black Mini Cooper! See also Declaring and using variables in JavaFX Creating and using JavaFX functions Creating and using variables in JavaFX JavaFX is a statically type-safe and type-strict scripting language. Therefore, variables (and anything which can be assigned to a variable, including functions and expressions) in JavaFX, must be associated with a type, which indicates the expected behavior and representation of the variable. This sections explores how to create, initialize, and update JavaFX variables. Getting ready Before we look at creating and using variables, it is beneficial to have an understanding of what is meant by data type and be familiar with some common data types such as String, Integer, Float, and Boolean. If you have written code in other scripting languages such as ActionScript, Python, and Ruby, you will find the concepts in this recipe easy to understand. How to do it... JavaFX provides two ways of declaring variables including the def and the var keywords. def X_STEP = 50;prntln (X_STEP);X_STEP++; // causes errorvar x : Number;x = 100;...x = x + X_LOC; How it works... In JavaFX, there are two ways of declaring a variable: def—The def keyword is used to declare and assign constant values. Once a variable is declared with the def keyword and assigned a value, it is not allowed be reassigned a new value. var—The var keyword declares variables which are able to be updated at any point after their declaration. There's more... All variables must have an associated type. The type can be declared explicitly or be automatically coerced by the compiler. Unlike Java (similar to ActionScript and Scala), the type of the variable follows the variable's name separated by a colon. var location:String; Explicit type declaration The following code specifies the type (class) that the variable will receive at runtime: var location:String;location = "New York"; The compiler also supports a short-hand notation that combines declaration and initialization. var location:String = "New York"; Implicit coercion In this format, the type is left out of the declaration. The compiler automatically converts the variable to the proper type based on the assignment. var location;location = "New York"; Variable location will automatically receive a type of String during compilation because the first assignment is a string literal. Or, the short-hand version: var location = "New York"; JavaFX types Similar to other languages, JavaFX supports a complete set of primitive types as listed: :String—this type represents a collection of characters contained within within quotes (double or single, see following). Unlike Java, the default value for String is empty (""). "The quick brown fox jumps over the lazy dog" or 'The quick brown fox jumps over the lazy dog' :Number—this is a numeric type that represents all numbers with decimal points. It is backed by the 64-bit double precision floating point Java type. The default value of Number is 0.0. 0.01234100.01.24e12 :Integer—this is a numeric type that represents all integral numbers. It is backed by the 32-bit integer Java type. The default value of an Integer is 0. -44700xFF :Boolean—as the name implies, this type represents the binary value of either true or false. :Duration—this type represent a unit of time. You will encounter its use heavily in animation and other instances where temporal values are needed. The supported units include ms, s, m, and h for millisecond, second, minute, and hour respectively. 12ms4s12h0.5m :Void—this type indicates that an expression or a function returns no value. Literal representation of Void is null. Variable scope Variables can have three distinct scopes, which implicitly indicates the access level of the variable when it is being used. Script level Script variables are defined at any point within the JavaFX script file outside of any code block (including class definition). When a script-level variable is declared, by default it is globally visible within the script and is not accessible from outside the script (without additional access modifiers). Instance level A variable that is defined at the top-level of a class is referred to as an instance variable. An instance level is visible within the class by the class members and can be accessed by creating an instance of the class. Local level The least visible scope are local variables. They are declared within code blocks such as functions. They are visible only to members within the block.
Read more
  • 0
  • 0
  • 4556

article-image-hosting-workflow-applications-microsoft-windows-workflow-foundation-40
Packt
05 Oct 2010
4 min read
Save for later

Hosting Workflow Applications in Microsoft Windows Workflow Foundation 4.0

Packt
05 Oct 2010
4 min read
Introduction WF4 is one part of .NET Framework 4.0, which means WF4 workflow can be hosted and run in any type of application running with the .NET framework. We can host a workflow as a WCF service. We can also invoke a workflow service from a workflow or host workflow in an ASP.NET application and handle all the business logic behind the page. When we design workflow applications, please let workflow be workflow. Don't couple workflow with other logic. For example, in this chapter, hosting workflow in ASP.NET is for conception demonstration only, not the best practice. In the real world, most of the time, workflow should be implemented as a workflow service hosted in IIS7 or AppFabric. AppFabric is an IIS7 extension that includes many tools to help us host a workflow service. AppFabric is to workflow service like IIS7 is to ASP.NET website. However, we can run a workflow service in IIS7 without AppFabric installed. Although AppFabric is powerful, we need to spend some time to learn it. For more information about AppFabric, you can check this link: https://www.microsoft.com/en-us/download/details.aspx?id=27115 Hosting a workflow service in IIS7 The process of sending an e-mail would consume some time - maybe a few seconds or even minutes. It would be a waste of time and resources for our applications to stop and wait for an e-mail sending action to complete. Because sending e-mail is time-consuming, a better design is to strip this feature out as an independent WCF workflow service and host that service in IIS7. Getting ready We need the SendEmailActivity activity to send an e-mail. How to do it... Create a WCF workflow service application: Create a WCF workflow service application and name it HostingWorkflowServiceInIIS7. Add SendEmailActivity to the toolbox: In the Toolbox tab, right-click and select Choose Items. In the opening dialog, click Browse and navigate to the ActivityLibrary.dll Click OK. We will find SendEmailActivity in the toolbox: Create a SendEmail workflow service: Delete Service1.xamlx, which is created by default, and add a new WCF workflow service to the project. Name it SendEmailService.xamlx. Drag a TransactedReceiveScope activity to the design panel, click the Variables button, and create a variable named emailMessage: Drag a Receive activity to the Request box of TransactedReceiveScope. Set the OperationName to SendEmail. Click the Content Definition link to create a parameter as shown here: Assign ISendEmailService to the ServiceContractName property. Check the CanCreateInstance property. Next, drag SendEmailActivity to the body of TransactedReceiveScope. Assign the following properties to SendEmailActivity: The final workflow will look as shown in the following screenshot: Create a website in IIS7 for this WF service: In IIS7 Manager Console, create a website and assign the website's physical path to the project folder of HostingWorkflowServiceInIIS7. Assign it a new port number. By default, an ASP.NET application will run under the built-in network service account (or ApplicationPoolIdentity in IIS7.5). This account has the most limited permissions. For testing, we can shift the application pool's identity to an administrator account. We should be able to find the following module and handlers in IIS7: If we cannot, then we should reinstall .NET framework 4.0 or repair it. Here are the repair commands: Repair command for 32-bit: .NET Framework 4 Full (32-bit) – silent repair %windir%Microsoft.NETFrameworkv4.0.30319SetupCacheClient setup.exe /repair /x86 /x64 /ia64 /parameterfolder Client /q /norestart Repair command for 64-bit: .NET Framework 4 Full (64-bit) – silent repair %windir%Microsoft.NETFramework64v4.0.30319SetupCacheClientsetup.exe /repair /x86 /x64 /ia64 /parameterfolder Client /q /norestart Use WCFTestClient.exe to test the WCF service: Usually, we can find the WCFTestClient.exe tool in C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDE. We just need to open our mail. A new mail with subject Hello WF Service indicates that we have created and hosted the WF service successfully. How it works... Simply put, once we have set up the IIS7, we need to copy all the workflow service project files and folders to the IIS application folder and the workflow service will just work. There's more We can also host a WF4 service in IIS6 once we have installed .NET framework 4.0. Running a WF4 service in IIS6 is not recommended.
Read more
  • 0
  • 0
  • 2468

article-image-installing-and-using-sametime-connect
Packt
04 Oct 2010
6 min read
Save for later

Installing and Using Sametime Connect

Packt
04 Oct 2010
6 min read
  IBM Lotus Sametime 8 Essentials: A User's Guide Mastering Online Enterprise Communication with this collaborative software Collaborate securely with your colleagues and teammates both inside and outside your organization by using Sametime features such as instant messaging and online meetings Make your instant messaging communication more interesting with the inclusion of graphics, images, and emoticons to convey more information in fewer words Communicate with other instant messaging services and users, such as AOL Instant Messaging, Yahoo Instant Messaging, and Google Talk and know how someone's online status can help you communicate faster and more efficiently Discover how the Sametime Meeting Center can maximize the productivity of teams in your organization with the use of online meetings, training session playback, seamless voice/video integration, and screen sharing See how Sametime works in common, every-day, real-world situations with tips, resources, and detailed screenshots Read more about this book (For more resources on IBM, see here.) Installing Sametime Connect on Windows Installing Sametime Connect on a Windows desktop is similar to installing any other Windows software. In order to run Sametime your workstation will need to meet the minimum hardware and operating system requirements. If you're unsure about your hardware or operating system, be sure to check with your system administrator. You'll need a copy of the installation software, which is typically a file that ends in .EXE. Locate the file via Windows Explorer, and begin the installation by double-clicking on the setup.exe file. After a language option screen, you will see the Sametime Connect client installation welcome screen to start your install process. Click on Next to proceed. After a License screen (in which you select the I Accept option and click on Next), you will have the choice of where your install of Sametime Connect should be placed: You will see one final screen to confirm you are ready to start your install: If everything seems correct, click on the Install button to start the process. The Windows installer will run for a few minutes, and will successfully install the software in the location you have specified. Once it has installed, you will see a message telling you the installation was successful, and also offering to launch the Sametime Connect software for you: Assuming you leave the Launch option selected, Sametime Connect will start and take you to the Sametime sign on screen. Installing Sametime Connect on a Macintosh Mac users can also install Sametime Connect. That's one really nice feature of the Sametime Connect client—you have options as to which operating system you can use. So if you use Windows at work, but have a Mac at home, you can still stay connected to your Sametime buddies. And as with the Windows environment, your Macintosh will need to meet the minimum hardware and operating system requirements in order to run Sametime. We've listed them here. The following versions of the Macintosh operating system can run the Sametime Connect client: OSX 10.4.x and OSX 10.5. To install the Mac Sametime Connect client, you will need the sametime-connect.pkg file or the file specific to the version of Sametime supported in your environment. You begin by clicking on the .pkg file which will launch the Sametime installer. Click on Continue to proceed through the license and language agreements until you reach the screen to choose the install directory. You can choose to install Sametime in a directory other than the default, but the default is usually a good choice. Once you've decided on the install location, click on Install to proceed. If your install is successful, you'll see the following screen. You'll also see a Sametime icon in your applications folder on the Mac. Installing Sametime Connect on Linux Installing Sametime Connect on a Linux desktop is just as easy as installing Sametime Connect on any other desktop. We've included the minimum hardware and operating system requirements as follows: You'll need a copy of the installation software, typically a file that ends with an .RPM suffix. Here is an example of what it looks like on a SuSE Linux desktop: Double-click on the sametime-connect-8.0.2-1.i586.rpm file to start the installation. A dialog box appears listing the name of the software that will be installed, along with a checkmark next to it to specify that it's the correct item. When you're ready, click on the Install button to start the process: The installer will run for a few minutes and come back with a message saying the installation was successful. Once that is done, all that's left to do is to launch Sametime Connect from your desktop application menu: When Sametime launches for the very first time, you'll see the Sametime splash screen and you'll be required to respond to the licensing agreement dialog box. Type 1 to accept the agreement or press Enter to read the license agreement. Once you have agreed to the licensing agreement, the sign-on screen for the Sametime Connect client will be displayed. At that point, you will have the sign-on screen for the Connect client, and it will work just like any other version of Sametime Connect. Setting up the connection to the Sametime server Now that you have Sametime installed, you'll need to log into it. You will have the Sametime icon on your desktop or in your start menu, depending on the operating system you are using. Launching Sametime will open up the logon dialog box: A few essential pieces of information are needed to complete this dialog box, which they should be provided to you by your technical department, namely Host server, User name, and Password. The Host server field is the Sametime server name. As your contacts connect to this server, you can see when they are available for chatting by the status icons that appear by their names. Your username is normally the same name or user id you use to sign on to your Lotus Notes client, but you may have a separate user id for Sametime depending on the type of authentication Sametime is using. Your password is most likely the same as your Notes client id password, but your technical department should provide you with this information. If you want to automatically logon when you start up Sametime, select the Remember Password and Automatically log in checkboxes. This combination ensures that you will automatically sign into Sametime whenever you start up the application. And while this says "automatically", it's important to remember to keep your password up-to-date. The password in the dialog box will require an update for your login to Sametime to be successful. Once you have completed the dialog box, click on Log In, and if your login information is correct, your Sametime client will show you connected to the server:
Read more
  • 0
  • 0
  • 3404

article-image-mysql-admin-configuring-innodb-and-installing-mysql-windows-service
Packt
01 Oct 2010
3 min read
Save for later

MySQL Admin: Configuring InnoDB and Installing MySQL as a Windows Service

Packt
01 Oct 2010
3 min read
In order to prevent the transactional nature of InnoDB from completely thwarting its performance, it implements what is called the redo log. In this recipe, we will present the relevant settings to (re-)configure a database server's redo log. Getting ready As the redo log setup is a part of the server configuration, you will need an operating system user account and sufficient rights to modify the server's configuration file. You will also need rights to restart the MySQL service because the redo log cannot be reconfigured on the fly. Moreover, an administrative MySQL user account is required to prepare the server for the shutdown, necessary as part of the procedure. Caution: As this recipe will modify the configuration of parameters critical to data integrity, you should make a backup copy of the configuration file before editing it! How to do it... Connect to the server using your administrative account. Issue the following command: mysql> SET GLOBAL innodb_fast_shutdown=0;Query OK, 0 rows affected (0.00 sec) Verify the setting like this: mysql> SHOW VARIABLES LIKE 'innodb_fast_shutdown'; Log off from MySQL and stop the MySQL server. Locate the MySQL configuration file, usually called my.cnf or my.ini (on Windows) and open it in a text editor. Locate the following parameters in the [mysqld] section (you values will vary, of course): [mysqld]...innodb_log_group_home_dir=/var/lib/mysql/redologinnodb_log_file_size=32Minnodb_log_buffer_size=64Minnodb_log_files_in_group=2... Edit the above configuration settings to their new values. If you require help on how to find suitable values, see the There's more... section of this recipe. Save the configuration file. Navigate to the directory configured for innodb_log_group_home_dir. If there is no such setting in your configuration file, navigate to MySQL's data directory that is then taken as the default. Move the files whose names start with ib_logfile to a backup location. Do not copy them; they must be removed from their original location. Restart the MySQL server. Verify that new files are created as you configured them: $ ls -l /var/lib/mysqld/redolog If you do not see the new files appear and the server does not start up correctly, check the MySQL error log for messages. Usually, the only thing that can go wrong here is that you either mistyped the directory name or did not actually remove the previous ib_logfile files. To restore everything back to the original configuration, restore your configuration file from the backup and restore the ib_logfile files you moved out to the backup to their original location. What just happened... By setting innodb_fast_shutdown to 0, you told the server to finish writing any pending changes to the disk before actually exiting. This makes sure there are no remaining transactions in the current redo logs that could get lost when these files are replaced. After that you could change the configuration to new values, possibly using a different number of files and different sizes. Then, before restarting, you could move the old redo log files out of the way. This is important because otherwise MySQL would complain about a mismatch between the settings file and the actual situation on disk. When it comes up finding no redo log files, it will create new ones with the settings just configured.
Read more
  • 0
  • 0
  • 7395

article-image-advanced-aspects-inserting-and-deleting-data-mysql
Packt
01 Oct 2010
10 min read
Save for later

Advanced aspects of Inserting and Deleting data in MySQL

Packt
01 Oct 2010
10 min read
  MySQL Admin Cookbook 99 great recipes for mastering MySQL configuration and administration Set up MySQL to perform administrative tasks such as efficiently managing data and database schema, improving the performance of MySQL servers, and managing user credentials Deal with typical performance bottlenecks and lock-contention problems Restrict access sensibly and regain access to your database in case of loss of administrative user credentials Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on MySQL, see here.) Inserting new data and updating data if it already exists Manipulating data in a database is part of everyday work and the basic SQL means of INSERT, UPDATE, and DELETE make this a pretty straightforward, almost trivial task—but is this always true? When considering data manipulation, most of the time we think of a situation where we know the content of the database. With this information, it is usually pretty easy to find a way of changing the data the way you intend to. But what if you have to change data in circumstances where you do not know the actual database content beforehand? You might answer: "Well, then look at your data before changing it!" Unfortunately, you do not always have this option. Think of distributed installations of any software that includes a database. If you have to design an update option for this software (and the respective databases), you might easily come to a situation where you simply do not know about the actual database content. One example of a problem arising in these cases is the question of whether to insert or to update data: "Does the data in question already (partially) exist?" Let us assume a database table config that stores configuration settings. It holds key-value pairs, with name being the name (and thus the key) of the setting and value its value. This table exists in different database installations, one for every branch office of your company. Your task is to create an update package to set a uniform upper limit of 25% for the price discount that is allowed in your sales software. If no such limit has been defined yet, there is no respective entry in the config table, and you have to insert a new record. If the limit, however, has been set before (for example by the local manager), the entry does already exist, in which case you have to update it to hold the new value. While the update of a potentially existing entry does not pose a problem, an INSERT statement that violates uniqueness constraints will simply cause an error. This is, however, typically not acceptable in an automated update procedure. The following recipe will show you how to solve this problem with only one SQL command. Getting ready Besides a running MySQL server, a SQL client, and an account with appropriate user rights (INSERT, UPDATE), we need a table to update. In the earlier example, we assumed a table named sample.config with two character columns name and value. The name column is defined as the primary key: CREATE TABLE sample.config ( name VARCHAR(64) PRIMARY KEY, value VARCHAR(64)); How to do it... Connect to your database using your SQL client Execute the following command: mysql> INSERT INTO sample.config VALUES ("maxPriceDiscount","25%") ON DUPLICATE KEY UPDATE value='25%';Query OK, 1 row affected (0.05 sec) How it works... This command is easily explained because it simply does what it says: it inserts a new row in the table using the given values, as long as this does not cause a duplicate entry in either the primary key or another unique index. If a duplicate record exists, the existing row is updated according to the clauses defined after ON DUPLICATE KEY UPDATE. While it is sometimes tedious to enter some of the data and columns two times (once for the INSERT and a second time for the UPDATE), this statement allows for a lot of flexibility when it comes to the manipulation of potentially existing data. Please note that when executing the above statement, the result differs slightly with respect to the number of affected rows, depending on the actual data present in the database: When the record does not exist yet, it is inserted, which results in one affected row. But if the record is updated rather than inserted, it reports two affected rows instead, even if only one row gets updated. There's more... The INSERT INTO … ON DUPLICATE UPDATE construct does not work when there is no UNIQUE or PRIMARY KEY defined on the target table. If you have to provide the same semantics without having appropriate key definitions in place, it is recommended to use the techniques discussed in the next recipe. Inserting data based on existing database content In the previous recipe Inserting new data and updating data if it already exists, we discussed a method to either insert or update records depending on whether the records already exist in the database. A similar problem arises when you need to insert data to your database, but the data to insert depends on the data in your database. As an example, consider a situation in which you need to insert a record with a certain message into a table logMsgs, but the message itself should be different depending on the current system language that is stored in a configuration table (config). It is fairly easy to achieve a similar behavior for an UPDATE statement because this supports a WHERE clause that can be used to only perform an update if a certain precondition is met: UPDATE logMsgs SET message= CONCAT('Last update: ', NOW()) WHERE EXISTS (SELECT value FROM config WHERE name='lang' AND value = 'en');UPDATE logMsgs SET message= CONCAT('Letztes Update: ', NOW()) WHERE EXISTS (SELECT value FROM config WHERE name='lang' AND value = 'de');UPDATE logMsgs SET message= CONCAT('Actualisation derniere: ', NOW()) WHERE EXISTS (SELECT value FROM config WHERE name='lang' AND value = 'fr'); Unfortunately, this approach is not applicable to INSERT commands, as these do not support a WHERE clause. Despite this missing option, the following recipe describes a method to make INSERT statements execute only if an appropriate precondition in the database is met. Getting ready As before, we assume a database, a SQL client (mysql), and a MySQL user with sufficient privileges (INSERT and SELECT in this case). Additionally, we need a table to insert data into (here: logMsgs) and a configuration table config (please refer to the previous recipe for details). How to do it... Connect to your database using your SQL client. Execute the following SQL commands: mysql> INSERT INTO sample.logMsgs(message) -> SELECT CONCAT('Last update: ', NOW()) -> FROM sample.config WHERE name='lang' AND value='en';Query OK, 0 rows affected (0.00 sec)Records: 0 Duplicates: 0 Warnings: 0 How it works... Our goal is to have an INSERT statement take into account the present language stored in the database. The trick to do so is to use a SELECT statement as input for the INSERT. The SELECT command provides a WHERE clause, so you can use a condition that only matches for the respective language. One restriction of this solution is that you can only insert one record at a time, so the size of scripts might grow considerably if you have to insert lots of data and/or have to cover many alternatives. There's more... If you have more than just a few values to insert, it is more convenient to have the data in one place rather than distributed over several individual INSERT statements. In this case, it might make sense to consolidate the data by putting it inside a temporary table; the final INSERT statement uses this temporary table to select the appropriate data rows for insertion into the target table. The downside of this approach is that the user needs the CREATE TEMPORARY TABLES privilege, but it typically compensates with much cleaner scripts: After creating the temporary table with the first statement, we insert data into the table with the following INSERT statement. The next statement inserts the appropriate data into the target table sample.logMsgs by selecting the appropriate data from the temporary data that matches the language entry from the config table. The temporary table is then removed again. The final SELECT statement is solely for checking the results of the operation. Deleting all data from large tables Almost everyone who works with databases experiences the constant growth of the data stored in their database and it is typically well beyond the initial estimates. Because of that you often end up with rather large data sets. Another common observation is that in most databases, there are some tables that have a special tendency to grow especially big. If a table's size reaches a virtual threshold (which is hard to define, as it depends heavily on the access patterns and the data structures), it gets harder and harder to maintain and performance degradation might occur. From a certain point on, it is even difficult to get rid of data in the table again, as the sheer number of records makes deletion a pretty expensive task. This particularly holds true for storage engines with Multi-Version Concurrency Control (MVCC): if you order the database to delete data from the table, it must not be deleted right away because you might still roll back the deletion. So even while the deletion was initiated, a concurrent query on the table still has to be able to see all the records (depending on the transaction isolation level). To achieve this, the storage engine will only mark the records as deleted, but the actual deletion takes place after the operation is committed and all other transactions that access this table are closed as well. If you have to deal with large data sets, the most difficult task is to operate on the production system while other processes concurrently work on the data. In these circumstances, you have to keep the duration of your maintenance operations as low as possible in order to minimize the impact on the running system. As the deletion of data from a large table (typically starting at several millions of rows) might take quite some time, the following recipe shows a way of minimizing the duration of this operation in order to reduce side effects (like locking effects or performance degradation). Getting ready Besides a user account with appropriate privileges (DELETE), you need a sufficiently large table to delete data from. For this recipe, we will use the employees database, which is an example database available from MySQL: http://dev.mysql.com/doc/employee/en/employee.html This database provides some tables with sensible data and some pretty large tables, the largest having more than 2.8 million records. We assume that the Employees database was installed with an InnoDB storage engine enabled. To delete all rows of the largest table employees.salaries in a quick way, please read on. How to do it...
Read more
  • 0
  • 0
  • 8356
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-running-multiple-mysql-server-instances-parallel-linux-server
Packt
01 Oct 2010
5 min read
Save for later

Running Multiple MySQL Server Instances in Parallel on a Linux Server

Packt
01 Oct 2010
5 min read
  MySQL Admin Cookbook 99 great recipes for mastering MySQL configuration and administration Set up MySQL to perform administrative tasks such as efficiently managing data and database schema, improving the performance of MySQL servers, and managing user credentials Deal with typical performance bottlenecks and lock-contention problems Restrict access sensibly and regain access to your database in case of loss of administrative user credentials Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible Read more about this book (For more resources on MySQL, see here.) Introduction On most Linux setups, MySQL comes as a readymade installation package, making it easy to get started. It is, however, a little more complicated to run multiple instances in parallel, often a setup handy for development. This is because in contrast to Windows, MySQL is usually not installed in a self-contained directory, but most Linux distribution packages spread it across the appropriate system folders for programs, configuration files, and so on. You can, however, also install MySQL in its own directory, for example, if you need to use a version not available as a prepared package for your Linux distribution. While this gives you the greatest flexibility, as a downside you will have to take care of wiring up your MySQL server with the operating system manually. For example, you will need to hook up the startup and shutdown scripts with the appropriate facilities of your distribution. In more recent distributions, you can make use of a tool called mysqld_multi, a solution that lets you set up multiple instances of MySQL daemons with varying configurations. In this recipe, we will show you how to set up two parallel MySQL servers, listening on different TCP ports and using separate data directories for their respective databases. Getting ready This recipe is based on an Ubuntu Linux machine with the 8.04 LTS version. mysqld_multi comes with the MySQL packages for that operating system. If you are using other distributions, you need to make sure you have mysqld_multi installed to be able to follow along. Refer to your distribution's package repositories for information on which packages you need to install. You will also need an operating system user with sufficient privileges to edit the MySQL configuration file—typically /etc/mysql/my.cnf on Ubuntu—and restart services. As for AppArmor or SELinux, we assume these have been disabled before you start to simplify the process. How to do it... Locate and open the my.cnf configuration file in a text editor. Create the following two sections in the file: # mysqld_multi test, instance 1[mysqld1]server-id=10001socket=/var/run/mysqld/mysqld1.sockport=23306pid-file=/var/run/mysqld/mysqld1.piddatadir=/var/lib/mysql1log_bin=/var/log/mysql1/mysql1-bin.log# mysqld_multi test, instance 2[mysqld2]server-id=10002socket=/var/run/mysqld/mysqld2.sockport=33306pid-file=/var/run/mysqld/mysqld2.piddatadir=/var/lib/mysql2log_bin=/var/log/mysql2/mysql2-bin.log Save the configuration file. Issue the following command to verify the two sections are found by mysqld_multi: $ sudo mysqld_multi report Initialize the data directories: $ sudo mysql_install_db --user=mysql --datadir=/var/lib/mysql1$ sudo mysql_install_db --user=mysql --datadir=/var/lib/mysql2 Start both instances and verify they have been started: $ sudo mysqld_multi start 1$ sudo mysqld_multi report Connect to both instances and verify their settings: $ mysql -S /var/run/mysqld/mysql1.sockmysql> SHOW VARIABLES LIKE 'server_id'; How it works... mysqld_multi uses a single configuration file for all MySQL server instances, but inside that file each instance has its individual [mysqld] section with its specific options. mysqld_multi then takes care of launching the MySQL executable with the correct options to use the options from its corresponding section. The sections are distinguished by a positive number directly appended to the word mysqld in the section header. You can specify all the usual MySQL configuration file options in these sections, just as you would for a single instance. Make sure, however, to specify the minimum set of options as in the recipe steps previously stated, as these are required to be unique for every single instance. There's more... Some special preparation might be needed, depending on the particular operating system you are using. Turning off AppArmor / SELinux for Linux distributions If your system uses the AppArmor or SELinux security features, you will need to make sure these are either turned off while you try this out, or configured (for permanent use once your configuration has been finished) to allow access to the newly defined directories and files. See the documentation for your respective Linux distribution for more details on how to do this. Windows On Windows, running multiple server instances is usually more straightforward. MySQL is normally installed in a separate, self-contained folder. To run two or more independent server instances, you only need to install a Windows service for each of them and point them to an individual configuration file. Considering the alternative MySQL Sandbox project As an alternative to mysqld_multi you might want to have a look at MySQL Sandbox, which offers a different approach to hosting multiple independent MySQL installations on a single operating system. While mysqld_multi manages multiple configurations in a single file, MySQL Sandbox aims at completely separating MySQL installations from each other, easily allowing even several MySQL releases to run side by side. For more details, visit the project's website at http://mysqlsandbox.net Preventing invalid date values from being stored in DATE or DATETIME columns In this recipe, we will show you how to configure MySQL in a way such that invalid dates are rejected when a client attempts to store them in a DATE or DATETIME column using a combination of flags for the SQL mode setting. See the There's more... section of this recipe for some more detailed information on the server mode setting in general and on how to use it on a per-session basis. Getting ready
Read more
  • 0
  • 0
  • 10583

article-image-using-spritefonts-board-based-game-xna-40
Packt
30 Sep 2010
10 min read
Save for later

Using SpriteFonts in a Board-based Game with XNA 4.0

Packt
30 Sep 2010
10 min read
  XNA 4.0 Game Development by Example: Beginner's Guide Create your own exciting games with Microsoft XNA 4.0 Dive headfirst into game creation with XNA Four different styles of games comprising a puzzler, a space shooter, a multi-axis shoot 'em up, and a jump-and-run platformer Games that gradually increase in complexity to cover a wide variety of game development techniques Focuses entirely on developing games with the free version of XNA Packed with many suggestions for expanding your finished game that will make you think critically, technically, and creatively Fresh writing filled with many fun examples that introduce you to game programming concepts and implementation with XNA 4.0 A practical beginner's guide with a fast-paced but friendly and engaging approach towards game development Read more about this book (For more resources on XNA 4.0, see here.) SpriteFonts Unlike a Windows Forms application, XNA cannot use the TrueType fonts that are installed on your computer. In order to use a font, it must first be converted into a SpriteFont, a bitmap based representation of the font in a particular size that can be drawn with the SpriteBatch.DrawString() command. Technically, any Windows font can be turned into a SpriteFont, but licensing restrictions on most fonts will prevent you from using them in your XNA games. The redistributable font package is provided by Microsoft to address this problem and give XNA developers a range of usable fonts that can be included in XNA games. Following are samples of each of the fonts included in the font package: Time for action – add SpriteFonts to Game1 Right click on the Fonts folder in the Content project in Solution Explorer and select Add | New Item. From the Add New Item dialog, select Sprite Font. Name the font Pericles36.spritefont. After adding the font, the spritefont file will open in the editor window. In the spritefont file, change <Fontname>Kootenay</Fontname> to <Fontname>Pericles</Fontname>. Change <Size>14</Size> to <Size>36</Size>. Add the following declaration to the Game1 class: SpriteFont pericles36Font; Update the LoadContent() method of the Game1 class to load spritefont by adding: pericles36Font = Content.Load<SpriteFont>(@"FontsPericles36"); What just happened? Adding a SpriteFont to your game is very similar to adding a texture image. Since both are managed by the Content Pipeline, working with them is identical from a code standpoint. In fact, SpriteFonts are really just specialized sprite sheets, similar to what we used for our game pieces, and are drawn via the same SpriteBatch class we use to draw our sprites. The .spritefont file that gets added to your project is actually an XML document containing information that the Content Pipeline uses to create the .XNB file that holds the bitmap information for the font when you compile your code. The .spritefont file is copied from a template, so no matter what you call it, the XML will always default to 14 point Kootenay. In steps 4 and 5, we will edit the XML to generate 36 point Pericles instead. Just as with a Texture2D, we declare a variable (this time a SpriteFont) to hold the Pericles 36 point font. The Load() method of the Content object is used to load the font. SpriteFonts and extended charactersWhen a SpriteFont is built by the Content Processor, it actually generates bitmap images for each of the characters in the font. The range of characters generated is controlled by the <CharacterRegions> section in the SpriteFont's XML description. If you attempt to output a character not covered by this range, your game will crash. You can avoid this by removing the HTML comment characters (<!--and -->) from around the <DefaultCharacter> definition in the XML file. Whenever an unknown character is output, the character defined in <DefaultCharacter> will be used in its place. Score display Displaying the player's score with our new SpriteFont is simply a matter of calling the SpriteBatch.DrawString() method. Time for action – drawing the score Add a new Vector2 to the declarations area of Game1 to store the screen location where the score will be drawn: Vector2 scorePosition = new Vector2(605, 215); In the Draw() method, remove "this.Window.Title = playerScore.ToString();" and replace the line with: ToString();" and replace the line with:spriteBatch.DrawString(pericles36Font, playerScore.ToString(), scorePosition, Color.Black); What just happened? Using named vectors to store things like text positions, allows you to easily move them around later if you decide to modify the layout of your game screen. It also makes code more readable, as we have the name scorePosition instead of a hard-coded vector value in the spriteBatch.DrawString() call. Since our window size is set to 800 by 600 pixels, the location we have defined above will place the score into the pre-defined score box on our background image texture. The DrawString() method accepts a font to draw with (pericles36Font), a string to output (playerScore.ToString()), a Vector2 specifying the upper left corner of the location to begin drawing (scorePosition), and a color for the text to be drawn in (Color.Black). ScoreZooms Simply drawing the player's score is not very exciting, so let's add another use for our SpriteFont. In some puzzle games, when the player scores, the number of points earned is displayed in the center of the screen, rapidly growing larger and expanding until it flies off of the screen toward the player. We will implement this functionality with a class called ScoreZoom that will handle scaling the font. Time for action – creating the ScoreZoom class Add a new class file called ScoreZoom.cs to the Game1 class. Add the following using directive to the top of the file: using Microsoft.Xna.Framework.Graphics; Add the following declarati ons to the ScoreZoom class: public string Text;public Color DrawColor;private int displayCounter;private int maxDisplayCount = 30;private float scale = 0.4f;private float lastScaleAmount = 0.0f;private float scaleAmount = 0.4f; Add the Scale read-only property to the ScoreZoom class: public float Scale{ get { return scaleAmount * displayCounter; }} Add a Boolean property to indicate when the ScoreZoom has finished displaying: public bool IsCompleted{ get { return (displayCounter > maxDisplayCount); }} Create a constructor for the ScoreZoom class: public ScoreZoom(string displayText, Color fontColor){ Text = displayText; DrawColor = fontColor; displayCounter = 0;} Add an Update() method to the ScoreZoom class: public void Update(){ scale += lastScaleAmount + scaleAmount; lastScaleAmount += scaleAmount; displayCounter++;} What just happened? The ScoreZoom class holds some basic information about a piece of text and how it will be displayed to the screen. The number of frames the text will be drawn for are determined by displayCounter and maxDisplayCount. To manage the scale, three variables are used: scale contains the actual scale size that will be used when drawing the text, lastScaleAmount holds the amount the scale was increased by during the previous frame, and scaleAmount determines the growth in the scale factor during each frame. You can see how this is used in the Update() method. The current scale is increased by both the lastScaleAmount and scaleAmount. lastScaleAmount is then increased by the scale amount. This results in the scale growing in an exponential fashion instead of increasing linearly by a scaleAmount for each frame. This will give the text a zooming effect as it starts growing slowly and then speeds up rapidly to fill the screen. Time for action – updating and displaying ScoreZooms Add a Queue object to the Game1 class to hold active ScoreZooms: Queue<ScoreZoom> ScoreZooms = new Queue<ScoreZoom>(); Add a new helper method to the Game1 class to update the ScoreZooms queue: private void UpdateScoreZooms(){ int dequeueCounter = 0; foreach (ScoreZoom zoom in ScoreZooms) { zoom.Update(); if (zoom.IsCompleted) dequeueCounter++; } for (int d = 0; d < dequeueCounter; d++) ScoreZooms.Dequeue();} In the Update() method, inside the case section for GameState.Playing, add the call to update any active ScoreZooms. This can be placed right before the case's break; statement: UpdateScoreZooms(); Add the following to the CheckScoringChain() method to create a ScoreZoom when the player scores. Add this right after the playerScore is increased: ScoreZooms.Enqueue(new ScoreZoom("+" + DetermineScore(WaterChain.Count).ToString(), new Color(1.0f, 0.0f, 0.0f, 0.4f))); Modify the Draw() method of the Game1 class by adding the following right before the SpriteBatch.DrawString() call which draws the player's score: foreach (ScoreZoom zoom in ScoreZooms){ spriteBatch.DrawString(pericles36Font, zoom.Text, new Vector2(this.Window.ClientBounds.Width / 2, this.Window.ClientBounds.Height / 2), zoom.DrawColor, 0.0f, new Vector2(pericles36Font.MeasureString(zoom.Text).X / 2, pericles36Font.MeasureString(zoom.Text).Y / 2), zoom.Scale, SpriteEffects.None, 0.0f);} What just happened? Since all ScoreZoom objects "live" for the same amount of time, we can always be certain that the first one we create will finish before any created during a later loop. This allows us to use a simple Queue to hold ScoreZooms since a Queue works in a first-in-first-out manner. When UpdateScoreZooms() is executed, the dequeueCounter holds the number of ScoreZoom objects that have finished updating during this cycle. It starts at zero, and while the foreach loop runs, any ScoreZoom that has an IsCompleted property of true increments the counter. When the foreach has completed, ScoreZooms.Dequeue() is run a number of times equal to dequeueCounter. Adding new ScoreZoom objects is accomplished in step 4, with the Enqueue() method. The method is passed a new ScoreZoom object, which is constructed with a plus sign (+) and the score being added, followed by a red color with the alpha value set to 0.4f, making it a little more than halfway transparent. Just as the SpriteBatch.Draw() method has multiple overloads, so does the SpriteBatch.DrawString() method, and in fact, they follow much the same pattern. This form of the DrawString() method accepts the SpriteFont (pericles36Font), the text to display, a location vector, and a draw color just like the previous call. For the draw location in this case, we use this.Window.ClientBounds to retrieve the width and height of the game window. By dividing each by two, we get the coordinates of the center of the screen. The remaining parameters are the same as those of the extended Draw() call we used to draw rotated pieces. After the color value is rotation, which we have set to 0.0f, followed by the origin point for that rotation. We have used the MeasureString() method of the SpriteFont class to determine both the height and width of the text that will be displayed and divided the value by two to determine the center point of the text. Why do this when there is no rotation happening? Despite what the order of the parameters might indicate, this origin also impacts the next parameter: the scale. When the scale is applied, it sizes the text around the origin point. If we were to leave the origin at the default (0, 0), the upper left corner of the text would remain in the center of the screen and it would grow towards the bottom right corner. By setting the origin to the center of the text, the scale is applied evenly in all directions: Just as with the extended Draw() method earlier, we will use SpriteEffects.None for the spriteEffects parameter and 0.0f for the layer depth, indicating that the text should be drawn on top of whatever has been drawn already. Adding the GameOver game state Now that we can draw text, we can add a new game state in preparation for actually letting the game end when the facility floods.
Read more
  • 0
  • 0
  • 3446

article-image-using-animated-pieces-board-based-game-xna-40
Packt
30 Sep 2010
14 min read
Save for later

Using Animated Pieces in a Board-based Game with XNA 4.0

Packt
30 Sep 2010
14 min read
  XNA 4.0 Game Development by Example: Beginner's Guide Create your own exciting games with Microsoft XNA 4.0 Dive headfirst into game creation with XNA Four different styles of games comprising a puzzler, a space shooter, a multi-axis shoot 'em up, and a jump-and-run platformer Games that gradually increase in complexity to cover a wide variety of game development techniques Focuses entirely on developing games with the free version of XNA Packed with many suggestions for expanding your finished game that will make you think critically, technically, and creatively Fresh writing filled with many fun examples that introduce you to game programming concepts and implementation with XNA 4.0 A practical beginner's guide with a fast-paced but friendly and engaging approach towards game development Read more about this book (For more resources on XNA 4.0, see here.) Animated pieces We will define three different types of animated pieces: rotating, falling, and fading. The animation for each of these types will be accomplished by altering the parameters of the SpriteBatch.Draw() call. Classes for animated pieces In order to represent the three types of animated pieces, we will create three new classes. Each of these classes will inherit from the GamePiece class, meaning they will contain all of the methods and members of the GamePiece class, but add additional information to support the animation. Child classesChild classes inherit all of their parent's members and methods. The RotatingPiece class can refer to the pieceType and suffix of the piece without recreating them within RotatingPiece itself. Additionally, child classes can extend the functionality of their base class, adding new methods and properties or overriding old ones. In fact, Game1 itself is a child of the Micrsoft.Xna.Game class, which is why all of the methods we use (Update(), Draw(), LoadContent(), and so on) are declared as "override". Let's begin by creating the class we will use for rotating pieces. Time for action – rotating pieces Open your existing Flood Control project in Visual C# Express if it is not already active. Add a new class to the project called "RotatingPiece". Add "using Microsoft.Xna.Framework;" to the using area at the top of the class. Update the declaration of the class to read class RotatingPiece : GamePiece. Add the following declarations to the RotatingPiece class: public bool clockwise;public static float rotationRate = (MathHelper.PiOver2 / 10);private float rotationAmount = 0;public int rotationTicksRemaining = 10; Add a property to retrieve the current rotation amount: public float RotationAmount{ get { if (clockwise) return rotationAmount; else return (MathHelper.Pi*2) - rotationAmount; }} Add a constructor for the RotatingPiece class: public RotatingPiece(string pieceType, bool clockwise) : base(pieceType){ this.clockwise = clockwise;} Add a method to update the piece: public void UpdatePiece(){ rotationAmount += rotationRate; rotationTicksRemaining = (int)MathHelper.Max(0, rotationTicksRemaining-1);} What just happened? In step 2, we modified the declaration of the RotatingPiece class by adding : GamePiece to the end of it. This indicates to Visual C# that the RotatingPiece class is a child of the GamePiece class. The clockwise variable stores a "true" value if the piece will be rotating clockwise and "false" if the rotation is counter-clockwise. When a game piece is rotated, it will turn a total of 90 degrees (or pi/2 radians) over 10 animation frames. The MathHelper class provides a number of constants to represent commonly used numbers, with MathHelper.PiOver2 being equal to the number of radians in a 90 degree angle. We divide this constant by 10 and store the result as the rotationRate for use later. This number will be added to the rotationAmount float, which will be referenced when the animated piece is drawn. Working with radians All angular math is handled in radians from XNA's point of view. A complete (360 degree) circle contains 2*pi radians. In other words, one radian is equal to about 57.29 degrees. We tend to relate to circles more often in terms of degrees (a right angle being 90 degrees, for example), so if you prefer to work with degrees, you can use the MathHelper.ToRadians() method to convert your values when supplying them to XNA classes and methods. The final declaration, rotationTicksRemaining, is reduced by one each time the piece is updated. When this counter reaches zero, the piece has finished animating. When the piece is drawn, the RotationAmount property is referenced by a spriteBatch. Draw() call and returns either the rotationAmount property (in the case of a clockwise rotation) or 2*pi (a full circle) minus the rotationAmount if the rotation is counter-clockwise. The constructor in step 7 illustrates how the parameters passed to a constructor can be forwarded to the class' parent constructor via the :base specification. Since the GamePiece class has a constructor that accepts a piece type, we can pass that information along to its constructor while using the second parameter (clockwise) to update the clockwise member that does not exist in the GamePiece class. In this case, since both the clockwise member and the clockwise parameter have identical names, we specify this.clockwise to refer to the clockwise member of the RotatingPiece class. Simply clockwise in this scope refers only to the parameter passed to the constructor. this notationYou can see that it is perfectly valid C# code to have method parameter names that match the names of class variables, thus potentially hiding the class variables from being used in the method (since referring to the name inside the method will be assumed to refer to the parameter). To ensure that you can always access your class variables even when a parameter name conflicts, you can preface the variable name with this. when referring to the class variable. this. indicates to C# that the variable you want to use is part of the class, and not a local method parameter. Lastly, the UpdatePiece() method simply increases the rotationAmount member while decreasing the rotationTicksRemaining counter (using MathHelper.Max() to ensure that the value does not fall below zero). Time for action – falling pieces Add a new class to the Flood Control project called "FallingPiece". Add using Microsoft.Xna.Framework; to the using area at the top of the class. Update the declaration of the class to read class FallingPiece : GamePiece Add the following declarations to the FallingPiece class: public int VerticalOffset;public static int fallRate = 5; Add a constructor for the FallingPiece class: public FallingPiece(string pieceType, int verticalOffset) : base(pieceType){ VerticalOffset = verticalOffset;} Add a method to update the piece: public void UpdatePiece(){ VerticalOffset = (int)MathHelper.Max( 0, VerticalOffset - fallRate);} What just happened? Simpler than a RotatingPiece, a FallingPiece is also a child of the GamePiece class. A falling piece has an offset (how high above its final destination it is currently located) and a falling speed (the number of pixels it will move per update). As with a RotatingPiece, the constructor passes the pieceType parameter to its base class constructor and uses the verticalOffset parameter to set the VerticalOffset member. Note that the capitalization on these two items differs. Since VerticalOffset is declared as public and therefore capitalized by common C# convention, there is no need to use the "this" notation, since the two variables technically have different names. Lastly, the UpdatePiece() method subtracts fallRate from VerticalOffset, again using the MathHelper.Max() method to ensure the offset does not fall below zero. Time for action – fading pieces Add a new class to the Flood Control project called "FadingPiece". Add using Microsoft.Xna.Framework; to the using area at the top of the class. Update the declaration of the class to read class FadingPiece : GamePiece Add the following declarations to the FadingPiece class: public float alphaLevel = 1.0f;public static float alphaChangeRate = 0.02f; Add a constructor for the FadingPiece class: public FadingPiece(string pieceType, string suffix) : base(pieceType, suffix){} Add a method to update the piece: public void UpdatePiece(){alphaLevel = MathHelper.Max( 0, alphaLevel - alphaChangeRate);} What just happened? The simplest of our animated pieces, the FadingPiece only requires an alpha value (which always starts at 1.0f, or fully opaque) and a rate of change. The FadingPiece constructor simply passes the parameters along to the base constructor. When a FadingPiece is updated, alphaLevel is reduced by alphaChangeRate, making the piece more transparent. Managing animated pieces Now that we can create animated pieces, it will be the responsibility of the GameBoard class to keep track of them. In order to do that, we will define a Dictionary object for each type of piece. A Dictionary is a collection object similar to a List, except that instead of being organized by an index number, a dictionary consists of a set of key and value pairs. In an array or a List, you might access an entity by referencing its index as in dataValues[2] = 12; With a Dictionary, the index is replaced with your desired key type. Most commonly this will be a string value. This way, you can do something like fruitColors["Apple"]="red"; Time for action – updating GameBoard to support animated pieces In the declarations section of the GameBoard class, add three dictionaries: public Dictionary<string, FallingPiece> fallingPieces = new Dictionary<string, FallingPiece>();public Dictionary<string, RotatingPiece> rotatingPieces = new Dictionary<string, RotatingPiece>();public Dictionary<string, FadingPiece> fadingPieces = new Dictionary<string, FadingPiece>(); Add methods to the GameBoard class to create new falling piece entries in the dictionaries: public void AddFallingPiece(int X, int Y, string PieceName, int VerticalOffset){ fallingPieces[X.ToString() + "_" + Y.ToString()] = new FallingPiece(PieceName, VerticalOffset);}public void AddRotatingPiece(int X, int Y,string PieceName, bool Clockwise){ rotatingPieces[X.ToString() + "_" + Y.ToString()] = new RotatingPiece(PieceName, Clockwise);}public void AddFadingPiece(int X, int Y, string PieceName){ fadingPieces[X.ToString() + "_" + Y.ToString()] = new FadingPiece(PieceName,"W");} Add the ArePiecesAnimating() method to the GameBoard class: { if ((fallingPieces.Count == 0) && (rotatingPieces.Count == 0) && (fadingPieces.Count == 0)) { return false; } else { return true; }} Add the UpdateFadingPieces() method to the GameBoard class: private void UpdateFadingPieces(){ Queue<string> RemoveKeys = new Queue<string>(); foreach (string thisKey in fadingPieces.Keys) { fadingPieces[thisKey].UpdatePiece(); if (fadingPieces[thisKey].alphaLevel == 0.0f) RemoveKeys.Enqueue(thisKey.ToString()); } while (RemoveKeys.Count > 0) fadingPieces.Remove(RemoveKeys.Dequeue());} Add the UpdateFallingPieces() method to the GameBoard class: private void UpdateFallingPieces(){ Queue<string> RemoveKeys = new Queue<string>(); foreach (string thisKey in fallingPieces.Keys) { fallingPieces[thisKey].UpdatePiece(); if (fallingPieces[thisKey].VerticalOffset == 0) RemoveKeys.Enqueue(thisKey.ToString()); } while (RemoveKeys.Count > 0) fallingPieces.Remove(RemoveKeys.Dequeue());} Add the UpdateRotatingPieces() method to the GameBoard class: private void UpdateRotatingPieces(){ Queue<string> RemoveKeys = new Queue<string>(); foreach (string thisKey in rotatingPieces.Keys) { rotatingPieces[thisKey].UpdatePiece(); if (rotatingPieces[thisKey].rotationTicksRemaining == 0) RemoveKeys.Enqueue(thisKey.ToString()); } while (RemoveKeys.Count > 0) rotatingPieces.Remove(RemoveKeys.Dequeue());} Add the UpdateAnimatedPieces() method to the GameBoard class: public void UpdateAnimatedPieces(){ if (fadingPieces.Count == 0) { UpdateFallingPieces(); UpdateRotatingPieces(); } else { UpdateFadingPieces(); }} What just happened? After declaring the three Dictionary objects, we have three methods used by the GameBoard class to create them when necessary. In each case, the key is built in the form "X_Y", so an animated piece in column 5 on row 4 will have a key of "5_4". Each of the three Add... methods simply pass the parameters along to the constructor for the appropriate piece types after determining the key to use. When we begin drawing the animated pieces, we want to be sure that animations finish playing before responding to other input or taking other game actions (like creating new pieces). The ArePiecesAnimating() method returns "true" if any of the Dictionary objects contain entries. If they do, we will not process any more input or fill empty holes on the game board until they have completed. The UpdateAnimatedPieces() method will be called from the game's Update() method and is responsible for calling the three different update methods above (UpdateFadingPiece(), UpdateFallingPiece(), and UpdateRotatingPiece()) for any animated pieces currently on the board. The first line in each of these methods declares a Queue object called RemoveKeys. We will need this because C# does not allow you to modify a Dictionary (or List, or any of the similar "generic collection" objects) while a foreach loop is processing them. A Queue is yet another generic collection object that works like a line at the bank. People stand in a line and await their turn to be served. When a bank teller is available, the first person in the line transacts his/her business and leaves. The next person then steps forward. This type of processing is known as FIFO, or First In, First Out. Using the Enqueue() and Dequeue() methods of the Queue class, objects can be added to the Queue (Enqueue()) where they await processing. When we want to deal with an object, we Dequeue() the oldest object in the Queue and handle it. Dequeue() returns the first object waiting to be processed, which is the oldest object added to the Queue. Collection classes C# provides a number of different "collection" classes, such as the Dictionary, Queue, List, and Stack objects. Each of these objects provides different ways to organize and reference the data in them. For information on the various collection classes and when to use each type, see the following MSDN entry: http://msdn.microsoft.com/en-us/library/6tc79sx1(VS.80).aspx Each of the update methods loops through all of the keys in its own Dictionary and in turn calls the UpdatePiece() method for each key. Each piece is then checked to see if its animation has completed. If it has, its key is added to the RemoveKeys queue. After all of the pieces in the Dictionary have been processed, any keys that were added to RemoveKeys are then removed from the Dictionary, eliminating those animated pieces. If there are any FadingPieces currently active, those are the only animated pieces that UpdateAnimatedPieces() will update. When a row is completed, the scoring tiles fade out, the tiles above them fall into place, and new tiles fall in from above. We want all of the fading to finish before the other tiles start falling (or it would look strange as the new tiles pass through the fading old tiles). Fading pieces In the discussion of UpdateAnimatedPieces(), we stated that fading pieces are added to the board whenever the player completes a scoring chain. Each piece in the chain is replaced with a fading piece. Time for action – generating fading pieces In the Game1 class, modify the CheckScoringChain() method by adding the following call inside the foreach loop before the square is set to "Empty": gameBoard.AddFadingPiece( (int)ScoringSquare.X, (int)ScoringSquare.Y, gameBoard.GetSquare( (int)ScoringSquare.X, (int)ScoringSquare.Y)); What just happened? Adding fading pieces is simply a matter of getting the square (before it is replaced with an empty square) and adding it to the FadingPieces dictionary. We need to use the (int) typecasts because the ScoringSquare variable is a Vector2 value, which stores its X and Y components as floats. Falling pieces Falling pieces are added to the game board in two possible locations: From the FillFromAbove() method when a piece is being moved from one location on the board to another, and in the GenerateNewPieces() method, when a new piece falls in from the top of the game board. Time for action – generating falling pieces Modify the FillFromAbove() method of the GameBoard class by adding a call to generate falling pieces right before the rowLookup = -1; line: AddFallingPiece(x, y, GetSquare(x, y), GamePiece.PieceHeight *(y-rowLookup)); Update the GenerateNewPieces() method by adding the following call right after the RandomPiece(x,y) line: AddFallingPiece(x, y, GetSquare(x, y), GamePiece.PieceHeight * GameBoardHeight); What just happened? When FillFromAbove() moves a piece downward, we now create an entry in the FallingPieces dictionary that is equivalent to the newly moved piece. The vertical offset is set to the height of a piece (40 pixels) times the number of board squares the piece was moved. For example, if the empty space was at location 5,5 on the board, and the piece above it (5,4) is being moved down one block, the animated piece is created at 5,5 with an offset of 40 pixels (5-4 = 1, times 40). When new pieces are generated for the board, they are added with an offset equal to the height (in pixels) of the game board, determined by multiplying the GamePiece.PieceHeight value by the GameBoardHeight. This means they will always start above the playing area and fall into it.
Read more
  • 0
  • 0
  • 2006

article-image-content-delivery-alfresco-3
Packt
29 Sep 2010
11 min read
Save for later

Content Delivery in Alfresco 3

Packt
29 Sep 2010
11 min read
  Alfresco 3 Web Content Management Create an infrastructure to manage all your web content, and deploy it to various external production systems A complete guide to Web Content Creation and Distribution Understand the concepts and advantages of Publishing-style Web CMS Leverage a single installation to manage multiple websites Integrate Alfresco web applications with external systems Read more about this book (For more resources on Alfresco 3, see here.) Introduction to content delivery Alfresco provides a framework for pushing content from a stage (or authoring) server to live and test servers, as shown in the following figure: The Alfresco content production environment produces an approved view of a web project called a snapshot. Consider each snapshot as a web project version. Alfresco deployment takes a snapshot and pushes it out to either live or test servers. Consider a sample scenario as shown in the following diagram, where the content from the stage server is deployed to live servers. When snapshot version 2 is deployed to live servers, then the Alfresco deployment engine only copies the files which are either new or modifed and removes the files which are deleted when compared to snapshot version 1. The deployment engine is smart, which affects only few files rather than copying all of the files of a web project. Now that the snapshot version 2 is live (deployed to live servers), the editorial staff may work on a future version 3. Let's say for some reason there is an issue with snapshot version 2, which is live. You have the option of rolling it back to the previous good version of snapshot version 1. You can roll forward or you can roll back to a specific version of a web project snapshot version. This feature is very powerful even from a legal audit point of view, wherein you have an ability to reproduce the website as of a specific date. Further, the deployment process may be automated so that it happens automatically when content is approved for publishing. The deployment framework provides a flexible and highly-configurable system to allow you to tailor the system to your requirements. If the Alfresco-supplied components are not suitable, you can plug in your own authenticators, transport implementations, content transformers, and deployment targets. Live server vs. Test server Alfresco WCM enables previewing the content within the stage server environment. After content creation, the Editorial staff may preview web pages to verify the content, as well as the look and feel. Similarly the content reviewers and business owners may preview to review the web pages during the workflow process. Because of this powerful feature, you may not need a separate test server to preview and approve the content. The stage server itself is used for both authoring and testing the content. Hence, the content is authored and approved on the stage server and then deployed to the live servers directly. However, there can be a situation where you may need a separate test server. For example, if you are deploying content to another frontend application outside of Alfresco such as a PHP or .NET application, or situations when the virtualization server is not capable of providing the preview. Starting with the version 2.2 release Alfresco introduced the concept of a Test Server. You deploy the content from a Staging Sandbox to the live server and you deploy content from User Sandbox or from a workflow to the test server. Static vs. Dynamic delivery model Within the live or test server environment, you can push out content to a fat filesystem to be served up by Apache or IIS, or you can push your content into another runtime instance of Alfresco. Pushing content to a fat filesystem environment is also known as Static Deployment and it is achieved using Alfresco File System Receiver (FSR). Pushing content to another runtime instance of Alfresco is also known as Dynamic Deployment and it is achieved using Alfresco Server Receiver (ASR). In static deployment, the web pages are already rendered (or baked) before deploying. In dynamic deployment, since the content is in the runtime instance of Alfresco, the web pages will be generated (or fried) at runtime. The following is a summary of static and dynamic delivery models:     Static "Bake" Model Dynamic "Fry" Model Delivery Technology Web Servers Application Servers Page Compositing Submission time Request time Content deployed to File System Alfresco Runtime Content Search Not supported Supported out of the box Content Security Not supported Supported out of the box Personalization Limited Unlimited Performance Ultimate Less than the "bake" model   You can consider a hybrid deployment (both static and dynamic) for some business applications. You can define certain static content of the web project such as images, videos, and scripts to be deployed to the filesystem and certain dynamic content such as web pages to be deployed to the Alfresco runtime. This approach gives you good performance as well as personalized and dynamically changing content in a production environment. FSR for static delivery A File System Receiver (FSR) will need to be installed and configured on each live or test server to receive published static content from the Alfresco Staging Server. The FSR is a small, standalone server that receives updates from an Alfresco repository running Web Content Management; content is published to a fat filesystem. The published fat files will typically be served by a web server such as Apache, for static content or an application server such as Tomcat, JBoss, or IIS for web applications (WARs, PHP files, and so on). FSR requires filesystem access and must run as a user with appropriate rights to the target filesystem. The FSR is a standalone Java Daemon (no Tomcat or other app server required) and it has minimal resource requirements. The FSR supports the invocation of custom Java code and/or programs. Therefore, it can be used to perform additional tasks post-deployment such as search engine indexing, pushing content to a Content Delivery Network (CDN), or replicating content to other systems or repositories. The destination file server receiver has to be running with its RMI registry port and service port (44100 and 44101 by default) opened. Installing FSR If you refer to SourceForge at http://sourceforge.net/projects/alfresco/files/, you will notice three different downloads of FSR. A Microsoft Windows installer file (Alfresco-DeploymentCommunity-3.3-Setup.exe), a Linux installer file (Alfresco-DeploymentCommunity-3.3-Linux-x86-Install) for automatic installation, and a ZIP file (alfresco-community-deployment-3.3.zip) for manual installation. I would prefer using the ZIP file and manually installing the standalone deployment receiver. Both Windows and Linux installers have certain limitations as they do not provide configuring various deployment targets. Unzip the deployment ZIP file into a convenient location (it does not make its own directory) on a live or test server. Notice a file named deployment.properties, which contains the configuration information. The folder deployment includes default target information. To configure the filesystem receiver, open the deployment.properties file in the text editor of your choice. Choose locations for each of the following: ; filesystem receiver configuration deployment.filesystem.datadir=D:/07_MUN_WORK/alfresco_book_wcm_32e/ deployment-data/depdata deployment.filesystem.logdir=D:/07_MUN_WORK/alfresco_book_wcm_32e/ deployment-data/deplog deployment.filesystem.metadatadir=D:/07_MUN_WORK/alfresco_book_ wcm_32e/deployment-data/depmetadata deployment.filesystem.autofix=true deployment.filesystem.errorOnOverwrite=false ; Deployment Engine configuration deployment.rmi.port=44100 deployment.rmi.service.port=44101 ; Stand alone deployment server specific properties deployment.user=admin deployment.password=admin deployment.filesystem.datadir: This is the location in which the filesystem deployment receiver stores deployed files during a deployment, before committing them to their final locations. deployment.filesystem.logdir: This is the location in which the filesystem deployment receiver stores deployment time log data. deployment.filesystem.metadatadir: This is the location in which the filesystem deployment receiver stores metadata about deployed content. deployment.filesystem.autofix: The file system deployment target can either issue an error upon detecting a problem or automatically fix the problem. The autofix parameter controls whether the File System Deployment Target will attempt to fix the metadata itself or just issue a warning. Set the value to true to fix, or false to not fix. deployment.filesystem.errorOnOverWrite: The file system deployment target can issue an error upon overwriting the files. Set the value to false to overwrite the files, which is needed when updating the existing files. deployment.rmi.port: The port number to use for the RMI registry. Choose this so as not to conflict with any other services. By default, the standalone deployment receiver uses 44100. deployment.rmi.service.port: The port number to use for RMI service. Choose this so as not to conflict with any other services. By default this is 44101. Note that while specifying the directory locations on Microsoft Windows, either use forward slashes or escape the backslashes. For example, C:/dir1/dir2 or C:dir1dir2> Configuring your deployment targets You can configure as many target filesystem receivers as you need on a single live or test server. By default, a single filesystem receiver is defined with simple configuration via deployment.properties. Deployment targets are placed in the deployment folder with the filename deployment/*target.xml. To define more targets, follow the pattern of deployment/default-target.xml. There are two steps involved Definition of your target information in the deployment.properties file. Registration of your target with the deployment engine using an XML file. Let's create a deployment target for the CIGNEX website and let's name it as cignex-live1 target. As a first step to configure filesystem receiver, open the deployment.properties file in the text editor of your choice and add the cignex-live1 filesystem target configuration as follows: ; cignex-live1 filesystem target configuration deployment.filesystem.cignex-live1.metadatadir= ${deployment. filesystem.metadatadir}/cignex-live1 deployment.filesystem.cignex-live1.rootdir= D:/07_MUN_WORK/alfresco_book_wcm_32e/deployment-data/targets/cignex- live1 deployment.filesystem.cignex-live1.name=cignex-live1 deployment.filesystem.cignex-live1.user=admin deployment.filesystem.cignex-live1.password=admin Now to register this new target, you need to create a target XML file in the deployment folder. You can refer to an existing target file, default-target.xml, in the deployment folder for more information. Copy deployment/default-target.xml as the deployment/cignex-live1-target.xml file. Open the deployment/cignex-live1-target.xml file in your text editor of choice and replace the keyword default with the keyword cignex-live1. With these simple two steps, you have configured a new target named cignex-live1. Start and stop deployment receiver To run the receiver, execute deploy_start.sh(or deploy_start.bat) as the user on that server. Remember this user will be the owner of the deployed content. To stop the receiver, execute the deploy_stop.sh or deploy_stop.bat file. Using FSR from Alfresco WCM staging Now that the FSR is configured and running, you can use it from Alfresco staging to deploy the content. Configuring a web project to use FSR The following are the steps to configure a Web Project to use an FSR. Navigate to Company Home | Web Projects | <web project name>. Select Edit Web Project Settings from the Action menu. Click on Next to reach the Configure Deployment Servers window. Click on the Add Deployment Receiver link as shown in the following screenshot. Fill out the form as needed. The minimum required fields to be filled out, assuming default settings, are the Host name where the FSR is located and the Target Name. The following table contains the description of each of the FSR configuration fields.   Field Name Description Type Live Server or Test Server. You deploy the content from Staging Sandbox to the live server. And you deploy the content from User Sandbox or from workflow to the test server. Display Name A descriptive label for the server, used by the UI. Display Group The deployment receivers configured using the same Display Group name will be treated as one batch during deployment. Transport Name Name of the network protocol connection to the remote filesystem receiver. By default it is RMI. Host The host name of the destination server, can be a name or IP address. Port The RMI port to connect to on the destination server. URL The runtime URL of the destination server. Can be used to preview the deployment, upon a successful deployment. User Name The username to use to connect to the destination server. Password The password to use to connect to the destination server. Source Path The path of the folder to deploy, for example /ROOT/site1. Excludes A single regular expression (multiple rules can be defined within the expression) of items to exclude from the deployment, for example .*.jpg$|.*.gif$. Target Name The name of a target to deploy to, configured in the FSR. Include in Auto Deployment If checked, then this target will be included in auto deployment. Click on the Add and Finish buttons to complete the configuration.
Read more
  • 0
  • 0
  • 2628
article-image-unity-3d-game-development-dont-be-clock-blocker
Packt
29 Sep 2010
9 min read
Save for later

Unity 3D Game Development: Don't Be a Clock Blocker

Packt
29 Sep 2010
9 min read
  Unity 3D Game Development by Example Beginner's Guide A seat-of-your-pants manual for building fun, groovy little games quickly Build fun games using the free Unity 3D game engine even if you've never coded before Learn how to "skin" projects to make totally different games from the same file – more games, less effort! Deploy your games to the Internet so that your friends and family can play them Packed with ideas, inspiration, and advice for your own game design and development Stay engaged with fresh, fun writing that keeps you awake as you learn Read more about this book (For more resources on Unity 3D, see here.) We've taken a baby game like Memory and made it slightly cooler by changing the straight-up match mechanism and adding a twist: matching disembodied robot parts to their bodies. Robot Repair is a tiny bit more interesting and more challenging thanks to this simple modification. There are lots of ways we could make the game even more difficult: we could quadruple the number of robots, crank the game up to a 20x20 card grid, or rig Unity up to some peripheral device that issues a low-grade electrical shock to the player every time he doesn't find a match. NOW who's making a baby game? These ideas could take a lot of time though, and the Return-On-Investment (ROI) we see from these features may not be worth the effort. One cheap, effective way of amping up the game experience is to add a clock. Apply pressure What if the player only has x seconds to find all the matches in the Robot Repair game? Or, what if in our keep-up game, the player has to bounce the ball without dropping it until the timer runs out in order to advance to the next level? In this article let's: Program a text-based countdown clock to add a little pressure to our games Modify the clock to make it graphical, with an ever-shrinking horizontal bar Layer in some new code and graphics to create a pie chart-style clock That's three different countdown clocks, all running from the same initial code, all ready to be put to work in whatever Unity games you dream up. Roll up your sleeves—it's time to start coding! Time for action – prepare the clock script Open your Robot Repair game project and make sure you're in the game Scene. We'll create an empty GameObject and glue some code to it. Go to GameObject | Create Empty. Rename the empty Game Object Clock. Create a new JavaScript and name it clockScript. Drag-and-drop the clockScript onto the Clock Game Object. No problem! We know the drill by now—we've got a Game Object ready to go with an empty script where we'll put all of our clock code. Time for more action – prepare the clock text In order to display the numbers, we need to add a GUIText component to the Clock GameObject, but there's one problem: GUIText defaults to white, which isn't so hot for a game with a white background. Let's make a quick adjustment to the game background color so that we can see what's going on. We can change it back later. Select the Main Camera in the Hierarchy panel. Find the Camera component in the Inspector panel. Click on the color swatch labeled Back Ground Color, and change it to something darker so that our piece of white GUIText will show up against it. I chose a "delightful" puce (R157 G99 B120). Select the Clock Game Object from the Hierarchy panel. It's not a bad idea to look in the Inspector panel and confirm that the clockScript script was added as a component in the preceding instruction. With the Clock Game Object selected, go to Component | Rendering | GUIText. This is the GUIText component that we'll use to display the clock numbers on the screen. In the Inspector panel, find the GUIText component and type whatever in the blank Text property. In the Inspector panel, change the clock's X position to 0.8 and its Y position to 0.9 to bring it into view. You should see the word whatever in white, floating near the top-right corner of the screen in the Game view.. Right, then! We have a Game Object with an empty script attached. That Game Object has a GUIText component to display the clock numbers. Our game background is certifiably hideous. Let's code us some clock. Still time for action – change the clock text color Double-click the clockScript. Your empty script, with one lone Update() function, should appear in the code editor. The very first thing we should consider is doing away with our puce background by changing the GUIText color to black instead of white. Let's get at it. Write the built-in Start function and change the GUIText color: function Start(){ guiText.material.color = Color.black;}function Update() {} Save the script and test your game to see your new black text. If you feel comfy, you can change the game background color back to white by clicking on the Main Camera Game Object and finding the color swatch in the Inspector panel. The white whatever GUIText will disappear against the white background in the Game view because the color-changing code that we just wrote runs only when we test the game (try testing the game to confirm this). If you ever lose track of your text, or it's not displaying properly, or you just really wanna see it on the screen, you can change the camera's background color to confirm that it's still there. If you're happy with this low-maintenance, disappearing-text arrangement, you can move on to the Prepare the clock code section. But, if you want to put in a little extra elbow grease to actually see the text, in a font of your choosing, follow these next steps. Time for action rides again – create a font texture and material In order to change the font of this GUIText, and to see it in a different color without waiting for the code to run, we need to import a font, hook it up to a Material, and apply that Material to the GUIText. Find a font that you want to use for your game clock. I like the LOLCats standby Impact. If you're running Windows, your fonts are likely to be in the C:WindowsFonts directory. If you're a Mac user, you should look in the LibraryFonts folder. Drag the font into the Project panel in Unity. The font will be added to your list of Assets. Right-click (or secondary-click) an empty area of the Project panel and choose Create | Material. You can also click on the Create button at the top of the panel. Rename the new Material to something useful. Because I'm using the Impact font, and it's going to be black, I named mine "BlackImpact" (incidentally, "Black Impact" is also the name of my favorite exploitation film from the 70s). Click on the Material you just created in the Project Panel. In the Inspector panel, click on the color swatch labeled Main Color and choose black (R0 G0 B0), then click on the little red X to close the color picker. In the empty square area labeled None (Texture 2D), click on the Select button, and choose your font from the list of textures (mine was labeled impact - font texture). At the top of the Inspector panel, there's a drop-down labeled Shader. Select Transparent/Diffuse from the list. You'll know it worked when the preview sphere underneath the Inspector panel shows your chosen font outline wrapped around a transparent sphere. Pretty cool! Click on the Clock Game Object in the Hierarchy panel. Find the GUIText component in the Inspector panel. Click and drag your font—the one with the letter A icon—from the Project panel into the parameter labeled Font in the GUIText component. You can also click the drop-down arrow (the parameter should say None (Font) initially) and choose your font from the list. Similarly, click-and-drag your Material—the one with the gray sphere icon—from the Project panel into the parameter labeled Material in the GUIText component. You can also click on the drop-down arrow (the parameter should say None (Material) initially) and choose your Material from the list. Just as you always dreamed about since childhood, the GUIText changes to a solid black version of the fancy font you chose! Now, you can definitely get rid of that horrid puce background and switch back to white. If you made it this far and you're using a Material instead of the naked font option, it's also safe to delete the guiText.material.color = Color.black; line from the clockScript. Time for action – what's with the tiny font? The Impact font, or any other font you choose, won't be very… impactful at its default size. Let's change the import settings to biggify it. Click on your imported font—the one with the letter A icon—in the Project panel. In the Inspector panel, you'll see the True Type Font Importer. Change the Font Size to something respectable, like 32, and press the Enter key on your keyboard. Click on the Apply button. Magically, your GUIText cranks up to 32 points (you'll only see this happen if you still have a piece of text like "whatever" entered into the Text parameter of the GUIText of the Clock Game Object component). What just happened - was that seriously magic? Of course, there's nothing magical about it. Here's what happened when you clicked on that Apply button: When you import a font into Unity, an entire set of raster images is created for you by the True Type Font Importer. Raster images are the ones that look all pixelly and square when you zoom in on them. Fonts are inherently vector instead of raster, which means that they use math to describe their curves and angles. Vector images can be scaled up any size without going all Rubik's Cube on you. But, Unity doesn't support vector fonts. For every font size that you want to support, you need to import a new version of the font and change its import settings to a different size. This means that you may have four copies of, say, the Impact font, at the four different sizes you require. When you click on the Apply button, Unity creates its set of raster images based on the font that you're importing.
Read more
  • 0
  • 0
  • 3993

article-image-new-ibm-books-packt
Packt
29 Sep 2010
1 min read
Save for later

New IBM Books from Packt

Packt
29 Sep 2010
1 min read
New IBM Books IBM Rational ClearCase 7.0 Take a deep dive into extending ClearCase 7.0 to ensure the consistency and reproducibility of your software configurations IBM Lotus Domino: Classic Web Application Development Techniques A step-by-step guide for web application development and quick tips to enhance applications using Lotus Domino
Read more
  • 0
  • 0
  • 1938

article-image-deployment-feature-alfresco-3
Packt
29 Sep 2010
3 min read
Save for later

The Deployment Feature of Alfresco 3

Packt
29 Sep 2010
3 min read
  Alfresco 3 Web Content Management Create an infrastructure to manage all your web content, and deploy it to various external production systems A complete guide to Web Content Creation and Distribution Understand the concepts and advantages of Publishing-style Web CMS Leverage a single installation to manage multiple websites Integrate Alfresco web applications with external systems Read more about this book (For more resources on Alfresco 3, see here.) Alfresco WCM staging has an autodeploy option in its default workflow, allowing end users, at the time of submit, to enforce automatic deployment of approved changes directly to the live website without having to manually initiate deployment. The Submit Items window has an Auto Deploy checkbox, as shown in the following screenshot: Upon approval, if the auto deploy option is on, the workflow will perform a deployment to those live servers that have the Include In Auto Deploy option enabled. For more details about enabling this option, refer the Configuring a web project to use FSR section in the previous article. Deploying to a test server The Test Server Deployment functionality provides in-context preview by allowing a contributor to deploy their content to an external target (either an ASR or FSR), from which it can be rendered by any web application technology that can either read from a filesystem or access an ASR via HTTP (which includes all of the major web application technologies in use today, including Java, .NET, PHP, Ruby, Python, CGI, and so on). Once a test server has been deployed to, it is allocated to the user or workflow that performed the deployment. Once the user or workflow has finished with the test server it is released and returned to the pool of test servers. This happens automatically in the case of a workflow sandbox and manually via a UI action for User Sandboxes. The following process has to be followed to use the test server: Set up a test server pool. Deploy to a test server. Preview the content. Release the test server. Setting up a test server pool The following are the steps to configure a Web Project to use an FSR. Navigate to Company Home Web Projects | <web project name>|. Select the Edit Web Project Settings from the Action menu. Click on Next to reach the Configure Deployment Servers window. Click on the Add Deployment Receiver link as shown in the following screenshot: For Type, select Test Server, specify the Display Name, Host name, and the Target Name. Click on the Add button. Similarly configure another test server, say with "cignex-test2" as the target. Ensure that the FSR is running on the test server. The targets "cignex-test1" and "cignex-test2" are configured in FSR. Deploy to a test server Let's say, you as a content manager would like to deploy your User Sandbox to the test server for testing purposes. Go to your User Sandbox and from the More Actions menu choose Deploy as shown in the following screenshot: The Deploy Sandbox window displays, listing all of the unallocated test servers as shown in the next screenshot. Select a test server to use (only one test server can be allocated to a sandbox at a time), and click on OK. The Monitor Deployment information displays once the deployment completes. If an error occurs, the reason for the error is shown under the Deployment Failed message:
Read more
  • 0
  • 0
  • 1445
article-image-testing-and-debugging-windows-workflow-foundation-40-wf-program
Packt
29 Sep 2010
2 min read
Save for later

Testing and Debugging Windows Workflow Foundation 4.0 (WF) Program

Packt
29 Sep 2010
2 min read
  Microsoft Windows Workflow Foundation 4.0 Cookbook Over 70 recipes with hands-on, ready to implement solutions for authoring workflows Customize Windows Workflow 4.0 applications to suit your needs A hands-on guide with real-world illustrations, screenshots, and step-by-step instructions Explore various functions that you can perform using WF 4.0 with running code examples A hands-on guide with real-world illustrations, screenshots, and step-by-step instructions Read more about this book (For more resources on this subject, see here.) Testing a WF program with unit test framework In this task, we will create a Test Project to do unit test for WF program. How to do it... Add a Test Project to the solution: Add a Test Project to Chapter01 solution and name the project as UnitTestForWFProgram as shown in the following screenshot: Add a workflow file to the Test Project:Add a workflow activity to this project. Right-click the newly created Test Project, then go to Add | New Items... | Workflow | Activity and name the activity as WorkflowForTest.xaml. In the opening WF designer, create an OutArgument as OutMessage. Next, drag an Assign activity to Designer panel and assign string "Test Message" to the OutMessage argument as shown in the the following screenshot: In WF4, workflow is actually an Activity class. We could see "Workflow" as a conception from a macroeconomic viewpoint, while consider "Activity" as a development concept. Create unit test code:Open UnitTest1.cs file and fill the file with following code: code 33 Run it:Set UnitTestForWorkflow as Startup project. Press Ctrl+F5 to build and run the test without debugging as shown in the following screenshot: How it works... In the preceding code snippet, [TestClass] indicates it is a unit test class, whereas [TestMethod] indicates a test method. When the Test Project runs, the test method will be executed automatically. There's more... In real application development, we can also create a separate Unit Test project and add a reference to the target project.
Read more
  • 0
  • 0
  • 3225

article-image-working-microsoft-windows-workflow-foundation-40-wf-program
Packt
29 Sep 2010
5 min read
Save for later

Working with a Microsoft Windows Workflow Foundation 4.0 (WF) Program

Packt
29 Sep 2010
5 min read
  Microsoft Windows Workflow Foundation 4.0 Cookbook Over 70 recipes with hands-on, ready to implement solutions for authoring workflows Customize Windows Workflow 4.0 applications to suit your needs A hands-on guide with real-world illustrations, screenshots, and step-by-step instructions Explore various functions that you can perform using WF 4.0 with running code examples A hands-on guide with real-world illustrations, screenshots, and step-by-step instructions Read more about this book (For more resources on this subject, see here.) Introduction Considering workflow programs as imperative program, we need to think of three fundamental things: How to define workflow programs How to build (compile) workflow programs How to execute workflow programs In WF4, we can define a workflow in either managed .NET code or in XAML. There are two kinds of code workflow authoring styles: Custom Activity class Creating workflow dynamically in the runtime There are also two ways to author workflow in XAML: By WF designer (recommended) Typing XML tags manually Essentially, workflow program is .NET program, no matter how we create it. After defining workflows, we can build workflow applications as we build normal .NET applications. When it comes to workflow execution, we need to consider three basic things: How to flow data into and out of a workflow How to store a temporary data when workflow is executing How to manipulate data in workflow This article is going to focus on answering these questions. Before moving ahead, make sure we have the following installed on our computer: Windows Vista/7 or Windows Server 2008 Visual Studio 2010 and .NET framework 4.0 We can also use Windows XP; however, its usage is not recommended. Creating the first WF program: HelloWorkflow In this task we will create our first workflow to print "Hello Workflow" to console application. How to do it... Create a Workflow Console Application project:After starting Visual Studio 2010, select File | New Project. A dialog is presented, as shown in the following screenshot. Under Visual C# section, select Workflow, and choose Workflow Console Application. Name the project HelloWorkflow. Name the solution Chapter01 and make sure to create a directory for the solution. Author workflow program:First, drag a Sequence activity to designer from Toolbox, next drag a WriteLine activity into Sequence activity. Finally, input "Hello Workflow" in the expression box of WriteLine activity. We can see the following screenshot: Run it:Press Ctrl+F5 to run project without debugging. The result is as shown in the following screenshot: How it works... When we press Ctrl+F5, Visual Studio saves the current project, and then it runs the project from Main method in Program.cs file. WorkflowInvoker.Invoke(new Workflow1()); The preceding statement starts the workflow. After the workflow starts running, WriteLine activity prints the "Hello Workflow" to Console Application. The workflow we created in WF designer is actually an XML file. We can open Workflow1.xaml with XML editor to check it. Right-click on Workflow1.xaml then click Open With..., and choose XML Editor to open the Workflow1.xaml as XML file. All XAML files will be compiled to .dll or .exe file. That is why when we press Ctrl+F5, the program just runs like a normal C# program. There's more... So far, there are no officially published WF4 Designer add-ins for Visual Studio 2008. We need a copy of Visual Studio 2010 installed on our computer to use WF4 designer, otherwise we can only create workflows by imperative code or by writing pure XAML file. Creating a WF program using C# Code In this task, we will create the same "HelloWorkflow" function workflow using pure C# code, beginning from a Console Application. How to do it... Create a Console Application project:Create a new Console Application project under Chapter01 solution. Name the project HelloCodeWorkflow. The following screenshot shows the Console Application new project dialog: Add reference to System.Activities assembly:By default, a new Console Application doesn't have reference to System.Activities assembly, due to which we need to perform this step. Create workflow definition code:Open Program.cs file and change the code present as follows: Open Program.cs file and change the code present as follows:using System.Activities;using System.Activities.Statements;namespace HelloCodeWorkflow { class Program { static void Main(string[] args) { WorkflowInvoker.Invoke(new HelloWorkflow()); } } public class HelloWorkflow:Activity { public HelloWorkflow() { this.Implementation = () => new Sequence { Activities = { new WriteLine(){Text="Hellow Workflow"} } }; } }} Run it:Set HelloCodeWorkflow as StartUp project and press Ctrl+F5 to run it. As expected, the result should be just like the previous result showed. How it works... We use the following namespace: using System.Activities;using System.Activities.Statements; Because WorflowInvoker class belongs to System.Activities namespace and Sequence activity, WriteLine activity belongs to System.Activities.Statements. public class HelloWorkflow:Activity { public HelloWorkflow() { this.Implementation = () => new Sequence { Activities = { new WriteLine(){Text="Hellow Workflow"} } }; }} By implementing a class inherited from Activity, we define a workflow using imperative code. WorkflowInvoker.Invoke(s); This code statement loads a workflow instance up and runs it automatically. WorkflowInvoker.Invoke method is synchronous and invokes the workflow on the same thread as the caller. There's more WF4 also provide us a class DynamicActivity by which we can create a workflow instance dynamically in the runtime. In other words, by using DynamicActivity, there is no need to define a workflow class before initializing a workflow instance. Here is a sample code: public static DynamicActivity GetWF() { return new DynamicActivity() { Implementation = () => new Sequence() { Activities ={ new WriteLine(){Text="Hello Workflow"} } } };}
Read more
  • 0
  • 0
  • 4667
Modal Close icon
Modal Close icon