洞房大花猫

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

有时候一个游戏,像RPG这种的,经常在游戏过程中需要频繁存档,在性能不好的平台上容易出各种问题,比如游戏Crash,存档丢失等等,今天想到一个可选的解法,就是用MMAP。虽然我到现在也没有搞懂这个机制究竟是怎样让程序员得到了好处,但是,至少这是一个有可能解决问题的办法。

代码:

 1 #include <sys/mman.h>
 2 #include <fcntl.h>
 3 #include <stdio.h>
 4 #include <memory.h>
 5 #include <unistd.h>
 6 #include <stdlib.h>
 7 #include <fstream>
 8                              
 9 using namespace std;
10                              
11 class Profile
12 {
13 // the data
14 public:
15     int val1;
16     int val2;
17     int val3;
18                              
19 public:
20     Profile() 
21     {
22     // NOT to set the default value, seriously.
23     }
24     void* operator new(size_t size)
25     {
26         return OpenProfile(size);
27     }
28     void operator delete(void* p)
29     {
30                              
31     }
32     void UpdateProfile()
33     {
34         // Synchronize the content between memory and filesystem
35         printf("msync() ret: %d\n", msync(this, sizeof(Profile), MS_SYNC));
36     }
37     void CloseProfile()
38     {
39         printf("munmap() ret: %d\n", munmap(this, sizeof(Profile)));
40     }
41                                  
42 private:
43     static void* OpenProfile(size_t size)
44     {
45         void* ret = NULL;
46         // open the file which name is "Profile".
47         int fd = open("Profile", O_RDWR);
48         // if there is not this file yet, create it.
49         if(-1 == fd)
50         {
51             // Create the "Profile" file and write '00000..' in it, and the size of this file is sizeof(Profile).
52             ofstream outfile("Profile", ofstream::out | ofstream::trunc | ofstream::binary);
53             outfile.seekp(size - sizeof(char), ios::beg);
54             outfile << '\0';
55             outfile.close();
56                              
57             fd = open("Profile", O_RDWR);
58             if(-1 == fd)
59             {
60                 printf("cannot open \"file\"");
61                 exit(0);
62             }
63         }
64         // Map the file
65         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
66         if(MAP_FAILED == ret)
67         {
68             printf("cannot map file");
69             exit(0);
70         }
71                                      
72         return ret;
73     }
74 };
75                              
76 int main()
77 {
78     // OPEN the Profile, and if there is no Profile now, will create one.
79     Profile* ptr = new Profile();
80                              
81     // MODIFY the profile.
82     ptr->val1 = 10;
83     ptr->val2 = 20;
84     ptr->val3 = 30;
85                              
86     // This code SAVE 
87     ptr->UpdateProfile();
88                              
89     // This code CLOSE
90     ptr->CloseProfile();
91     delete ptr;
92                                 
93     // READ the Profile:
94     ptr = new Profile();//nothing else need to do, you could see the profile has already been read in.
95     printf("val1 = %d, val2 = %d, val3 = %d\n", ptr->val1, ptr->val2, ptr->val3);
96                              
97     return 0;
98 }

上面这个存档类Profile,使用方法变简单了,只要new出来,就相当于进行了read存档的操作。在需要存档的时候可调用UpdateProfile,但实际上,由于mmap的机制,即使你没有调用UpdateProfile,存档实际上也有可能是保存了的。

不过我只知道mmap是把文件映射到内存中,这样你读写内存的时候实际上相当于读写了文件。对于mmap的原理和得到的实惠还不知晓。

posted on 2012-08-03 16:02  spencer24  阅读(275)  评论(0编辑  收藏  举报