aboutsummaryrefslogtreecommitdiffstats
path: root/docs/examples/spacewar/Debug.java
diff options
context:
space:
mode:
Diffstat (limited to 'docs/examples/spacewar/Debug.java')
-rw-r--r--docs/examples/spacewar/Debug.java219
1 files changed, 219 insertions, 0 deletions
diff --git a/docs/examples/spacewar/Debug.java b/docs/examples/spacewar/Debug.java
new file mode 100644
index 000000000..a3afb1dda
--- /dev/null
+++ b/docs/examples/spacewar/Debug.java
@@ -0,0 +1,219 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Debug.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Menu;
+import java.awt.CheckboxMenuItem;
+import java.awt.Frame;
+import java.awt.TextArea;
+import java.awt.Dimension;
+
+/**
+ * This aspect specifies debugging information to be output to the
+ * information window.
+ *
+ * When the debug aspect is compiled in the Frame menu has several checkbox
+ * items that can be used to control the amount of tracing information
+ * displayed. (By default the first three are off, because they generate
+ * so much information.)
+ *
+ * There are two reasons to gather all this debugging code into an aspect
+ * like this:
+ *
+ * (1) It makes it easier to understand when it is all in one place.
+ *
+ * (2) It means that we can "plug and debug". We can enable/disable
+ * the debugging code simply by weaving or not weaving this
+ * aspect in.
+ *
+ * All in all, this is a lot better than the usual practice of writing
+ * complex debugging code and then deleting it when the bug is found,
+ * only to regret it a month later when a related bug surfaces. (Or even
+ * the same bug!)
+ *
+ * This file also defines a class InfoWin, which it uses to display all the
+ * debugging information.
+ */
+aspect Debug {
+
+ private static InfoWin infoWin = new InfoWin();
+
+ private static Menu menu = new Menu("Debug");
+
+ private static CheckboxMenuItem traceConstructors =
+ new CheckboxMenuItem("trace constructors", false);
+ private static CheckboxMenuItem traceInitializations =
+ new CheckboxMenuItem("trace initializations", false);
+ private static CheckboxMenuItem traceMethods =
+ new CheckboxMenuItem("trace methods", false);
+ private static CheckboxMenuItem traceClockTick =
+ new CheckboxMenuItem("trace clock tick", false);
+ private static CheckboxMenuItem traceRegistry =
+ new CheckboxMenuItem("trace registry", true);
+ private static CheckboxMenuItem traceFireCollideDamage =
+ new CheckboxMenuItem("trace fire, collide, damage", true);
+
+ after() returning (SWFrame frame): call(SWFrame+.new(..)) {
+ menu.add(traceConstructors);
+ menu.add(traceInitializations);
+ menu.add(traceMethods);
+ menu.add(traceClockTick);
+ menu.add(traceRegistry);
+ menu.add(traceFireCollideDamage);
+ frame.getMenuBar().add(menu);
+ }
+
+ /*
+ * all constructors
+ */
+ pointcut allConstructorsCut():
+ call((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ after() returning: allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * All dynamic initializations
+ */
+ pointcut allInitializationsCut():
+ initialization((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin initializing " + thisJoinPoint.getSignature());
+ }
+ }
+ after() returning : allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done initializing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * all methods
+ */
+ pointcut allMethodsCut():
+ execution(* (spacewar.* && !(Debug+ || InfoWin+)).*(..));
+
+ before(): allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("entering " + thisJoinPoint.getSignature());
+ }
+ }
+ after() returning : allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("exiting " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * clock ticks
+ */
+ after(Object obj) returning :
+ (target(obj) && (target(Game) ||
+ target(Registry) ||
+ target(SpaceObject)))
+ && call(void clockTick()) {
+ if (traceClockTick.getState())
+ infoWin.println("ticking " + obj);
+ }
+
+ /*
+ * registry contents
+ */
+ after(Registry registry) returning :
+ target(registry) && (call(void register(..)) ||
+ call(void unregister(..))) {
+ if (traceRegistry.getState())
+ infoWin.println(registry.getTable().size() +
+ " space objects in the registry.");
+ }
+
+ /*
+ * fire, collide, damage
+ */
+ after() returning : call(void Ship.fire()) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println("firing");
+ }
+
+ after(Ship ship, SpaceObject obj) returning :
+ call(void handleCollision(SpaceObject)) && target(ship) && args(obj) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(ship + " collides with " + obj);
+ }
+
+ after(Ship shipA, Ship shipB) returning :
+ execution(void Ship.bounce(Ship, Ship)) && args(shipA, shipB) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(shipA + " bounces with " + shipB);
+ }
+
+ before(Ship ship, double amount):
+ call(void Ship.inflictDamage(double)) && target(ship) && args(amount) {
+ if (traceFireCollideDamage.getState())
+ if (amount > 0)
+ infoWin.println(ship + "gets " +
+ amount + " damage (" +
+ ship.getDamage() + ")");
+ }
+
+}
+
+class InfoWin {
+ private Frame frame;
+ private TextArea info;
+
+ InfoWin() {
+ frame = new Frame("debugging info for spacewar game");
+ info = new TextArea();
+ info.setEditable(false);
+
+ Dimension screenSize = frame.getToolkit().getScreenSize();
+ frame.setSize(250, 600);
+ frame.setLocation(screenSize.width - 250, 0);
+ frame.add(info);
+ frame.show();
+ frame.toFront();
+ }
+
+ void clear() {
+ info.setText("");
+ }
+
+ void println(String line) {
+ info.append(line + "\n");
+ }
+
+ void print(String line) {
+ info.append(line);
+ }
+}