乒乓缓冲类的设计(下)

    下面可以测试这个类了。回归原本设计该类的出发点,是为了解决卷轴的滚动绘制问题。但作为测试,把这个绘制卷轴的程序写出来显然麻烦了一点(不过补写本文时这整个游戏实际都已经做完了),于是用一个简单的模型来代替:
       一个长度为10的StringBuffer对象sbMainScene代表主屏幕可见区域;一个长度为2的StringBuffer型数组sbBuffer[],其每个元素都是一长度为5的StringBuffer对象作为双缓冲区的代表。绘制缓冲区的操作变为,每次随机产生一个0至0x10之间的整数,用从它到倒数到0的十六进制表示来作为填充StringBuffer的内容。比如随机产生的数字为4,则新“绘制”的内容是“43210”;滚动卷轴的操作变为:用缓冲区的内容向sbMainScene左移,每左移一位输出一次sbMainScene的内容,这样每次输出的内容就好像是屏幕滚动的每一帧一样。测试程序如下:

import java.util.Random;

import BiBuffer.BiBuffer;

public class TestBiBuffer {
 static int counter=-1; //随机产生数字的寄存器
 static String numChars="0123456789ABCDEF"; //作为数字对应字符的查找表之用
 static StringBuffer sbMainScene;
 static Random rand;

 public static void main(String[] args) {
  rand=new Random(System.currentTimeMillis());
  
  //初始化“可见区域”
  sbMainScene=new StringBuffer(10);
  for (int i=0; i<10; i++) sbMainScene.append(" ");
  
  //建立缓冲
  StringBuffer[] sbBuffer=new StringBuffer[2];
  for (int i=0; i<2; i++) sbBuffer[i]=new StringBuffer(5);
  //用创建好的缓冲数组建立乒乓缓冲对象
  final BiBuffer buffers=new BiBuffer(sbBuffer);
  
  //读取者线程,负责“卷轴滚动”
  Thread tReader=new Thread() {
   public void run() {
    Object buf;
    StringBuffer s;
    
    while (true) {
     //为“读”请求一个缓冲
       buf=buffers.openBuf('r');          
       s=(StringBuffer)buf;
     
     for (int i=0; i<s.length(); i++) {
      //将缓冲区内容左移入可见区域
      sbMainScene.deleteCharAt(0);
      sbMainScene.append(s.charAt(i));
      //每移一位输出一次可见区域内容
      System.out.println(sbMainScene);
     }
     
     //关闭
       buffers.closeBuf(buf);
    }
   }
  };
  
  Thread tWriter=new Thread() {
   public void run() {
    Object buf;
    StringBuffer s;
    
    while(true) {
     //为“写”请求一个缓冲
     buf=buffers.openBuf('w');          
       s=(StringBuffer)buf;
     
     s.delete(0, s.length());
     for (int i=0; i<s.capacity(); i++) {
      //若倒数完毕,重新产生一个随机非负整数
      if (counter==-1) counter=rand.nextInt(numChars.length());
      //将数字对应字符连缀进缓冲区,计数值减1
      s.append(numChars.charAt(counter--));
     }
     
     //关闭
     buffers.closeBuf(buf);
    }
   }
  };
  
  tReader.start();  tWriter.start();
 }
}

执行后就可以看到效果了。截取某次运行的一段输出结果看看:
03210DCBA9
3210DCBA98
210DCBA987
10DCBA9876
0DCBA98765
DCBA987654
CBA9876543
BA98765432
A987654321
9876543210
8765432106
7654321065
6543210654
5432106543
4321065432
3210654321
2106543210
1065432109
0654321098
6543210987
5432109876
4321098765
3210987654
2109876543
1098765432
0987654321
9876543210
8765432106
……
说明功能是正确无误的。

  至于上文说到的简化使用的设计,其实无非就是增加了一个接口的定义和两个方法:
BiBufferAccessor.java :

public interface BiBufferAccessor {
 public abstract void doWrite(Object buf);
 public abstract void doRead(Object buf);
}

BiBuffer.java :
//……
    public void write(BiBufferAccessor w) {
        Object buf;
        buf=openBuf('w');
        w.doWrite(buf);
        closeBuf(buf);
       
    }
   
    public void read(BiBufferAccessor r) {
        Object buf;
        buf=openBuf('r');
        r.doRead(buf);
        closeBuf(buf);
    }
}
这样一来,可以让对缓冲对象进行操作的类实现doWrite和doRead方法,把自身作为参数传入,即可省出要写openBuf和closeBuf的麻烦,更重要的是确保不会写出错误的代码(openBuf没有匹配的closeBuf)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值