Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/CPlugin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Sun Aug 15 01:53:13 2010 UTC (13 years, 9 months ago) by okadu
File MIME type: text/x-c++src
File size: 8296 byte(s)


1 #include "stdafx.h"
2 #include "CPluginTree.h"
3 #include "CSkinPlugin.h"
4
5 // 外部グローバル
6 extern set<string> g_LackPlugin;
7
8 // static メンバ
9 bool CPlugin::ms_PreviewState = false;
10
11 /*
12 * コンストラクタ
13 */
14 CPlugin::CPlugin(
15 char *id // ID
16 ){
17 m_Script = m_Buffer = NULL;
18 m_State = 0;
19 m_InsertTreeFlag = false;
20 m_ID = id;
21 m_Version = 0.0f;
22 m_IconTex = NULL;
23 m_IconRect[0] = m_IconRect[1] = 0.0f; m_IconRect[2] = m_IconRect[3] = 1.0f;
24 m_Next = NULL;
25 }
26
27 /*
28 * デストラクタ
29 */
30 CPlugin::~CPlugin(){
31 DELETE_A(m_Buffer);
32 }
33
34 /*
35 * ソート用比較関数
36 */
37 int CPlugin::Compare(
38 CPlugin *rhs // 右辺
39 ){
40 int ret = _mbsicmp((PUCHAR)m_Name.c_str(), (PUCHAR)rhs->m_Name.c_str());
41 if(!ret) ret = _mbsicmp((PUCHAR)m_ID.c_str(), (PUCHAR)rhs->m_ID.c_str());
42 if(!ret) ret = _mbsicmp((PUCHAR)m_Author.c_str(), (PUCHAR)rhs->m_Author.c_str());
43 return ret;
44 }
45
46 /*
47 * ディレクトリ移動
48 */
49 bool CPlugin::ChDir(){
50 return !chdir(g_BaseDir) && !chdir(DirName()) && !chdir(m_ID.c_str());
51 }
52
53 /*
54 * エラーをハンドル
55 */
56 void CPlugin::HandleError(
57 CSynErr *err // エラーハンドラ
58 ){
59 err->Handle(FlashIn("%s <%s>", DirName(), m_ID.c_str()), m_Buffer);
60 DELETE_A(m_Buffer);
61 }
62
63 /*
64 * 定義ファイルヘッダのロード
65 */
66 char *CPlugin::LoadHeader(
67 char *str // 定義ファイル
68 ){
69 char *tmp, *eee;
70 string type;
71 m_IconTex = NULL;
72 if(!(str = Space(eee = str))) throw CSynErr(eee);
73 if(!(str = BeginBlock(eee = str, "PluginHeader"))) throw CSynErr(eee);
74 if(!(str = AsgnFloat(eee = str, "RailSimVersion", &m_Version))) throw CSynErr(eee);
75 if(m_Version<2.00f) throw CSynErr(eee, "%s: %.2f", lang(InvalidVersion), m_Version);
76 if(RAILSIM_VERSION<m_Version) throw CSynErr(eee, "%s: %.2f", lang(UnsupportedVersion), m_Version);
77 if(!(str = AsgnIdentifier(eee = str, "PluginType", &type))) throw CSynErr(eee);
78 if(type!=DirName()) throw CSynErr(eee, "%s: %s", lang(InvalidPluginType), type.c_str());
79 if(!(str = AsgnString(eee = str, "PluginName", &m_Name))) throw CSynErr(eee);
80 if(!(str = AsgnString(eee = str, "PluginAuthor", &m_Author))) throw CSynErr(eee);
81 if(tmp = AsgnString(eee = str, "IconTexture", &m_IconFileName)) str = tmp;
82 if(tmp = AsgnFloat(eee = str, "IconRect", m_IconRect, 4, false)) str = tmp;
83 int i = 0;
84 string desc;
85 while(tmp = AsgnString(eee = str, "Description", &desc)){
86 str = tmp;
87 m_Description += i++ ? "\n"+desc : desc;
88 }
89 if(!(str = EndBlock(eee = str))) throw CSynErr(eee, ERR_ENDBLOCK);
90 return str;
91 }
92
93 /*
94 * 予備ロード
95 */
96 bool CPlugin::PreLoad(
97 FILE *file // ファイル
98 ){
99 char *str = m_Buffer = LoadBinaryText(file);
100 try{
101 str = LoadHeader(str);
102 }
103 catch(CSynErr err){
104 HandleError(&err);
105 return false;
106 }
107 m_Script = str;
108 return true;
109 }
110
111 /*
112 * 予備ロード
113 */
114 bool CPlugin::PreLoadOldForm(
115 FILE *file // ファイル
116 ){
117 try{
118 char *name = FlashOut(0), *auth = FlashOut(1);
119 if(fscanf(file, "%s %s", name, auth)<2) throw CSynErr(NULL);
120 m_Name = name;
121 m_Author = auth;
122 m_Description = lang(RS1Plugin);
123 }
124 catch(CSynErr err){
125 err.Handle(FlashIn("%s <%s>\n%s", DirName(), m_ID.c_str()), NULL);
126 return false;
127 }
128 fclose(file);
129 m_Version = 1.41f;
130 return true;
131 }
132
133 /*
134 * 基本情報テキストを取得
135 */
136 string CPlugin::GetBasicInfo(){
137 return "ID: "+m_ID+"\n"+lang(Name)+": "+m_Name+"\n"+lang(Author)+": "+m_Author;
138 }
139
140 /*
141 * 必要ならロード
142 */
143 CPlugin *CPlugin::LoadAndGet(){
144 switch(m_State){
145 case 1: // 予備ロード済み
146 if(m_Version<2.0f){
147 if(!LoadOldForm()) break;
148 }else{
149 if(!Load()) break;
150 }
151 m_State = 2;
152 case 2: // ロード済み
153 return this;
154 }
155 return NULL;
156 }
157
158 /*
159 * ツリーアイテム挿入
160 */
161 CTreeFileElement *CPlugin::InsertItem(
162 CTreeDirElement *p, // 挿入先
163 CPluginTree *o // ツリービュー
164 ){
165 CTreeFileElement *fe = new CTreeFileElement((char *)m_Name.c_str(), p, o, this);
166 p->InsertItem(fe);
167 m_InsertTreeFlag = true;
168 SetTreeElement(fe);
169 return fe;
170 }
171
172 /*
173 * アイコンテクスチャ設定
174 */
175 void CPlugin::SetIconTexture(){
176 if(m_IconFileName.size()){
177 ChDir();
178 m_IconTex = g_TexList.Get(FALSE, m_IconFileName.c_str());
179 m_IconFileName = "";
180 }
181 if(m_IconTex){
182 devSetTexture(0, m_IconTex);
183 SetUVMap(m_IconRect[0], m_IconRect[1],
184 m_IconRect[0]+m_IconRect[2], m_IconRect[1]+m_IconRect[3]);
185 }else{
186 g_Skin->SetInterfaceTexture();
187 SetUVMap(0.875f, 0.75f, 1.0f, 0.875f);
188 }
189 }
190
191 ////////////////////////////////////////////////////////////////////////////////
192 ////////////////////////////////////////////////////////////////////////////////
193
194 /*
195 * コンストラクタ
196 */
197 CPluginList::CPluginList(){
198 m_List = NULL;
199 m_PluginNum = 0;
200 }
201
202 /*
203 * デストラクタ
204 */
205 CPluginList::~CPluginList(){
206 CPlugin *ptr = m_List;
207 while(ptr){
208 CPlugin *next = ptr->m_Next;
209 delete ptr;
210 ptr = next;
211 }
212 m_List = NULL;
213 }
214
215 /*
216 * 定義ファイルのロード
217 */
218 bool CPluginList::List(){
219 long filelist;
220 _finddata_t data;
221 CPlugin **adr = &m_List;
222 if(chdir(g_BaseDir) || chdir(DirName())) return false;
223 if((filelist = _findfirst("*", &data))>=0){
224 do{
225 FILE *file;
226 if(!(data.attrib&_A_SUBDIR)) continue;
227 if(chdir(g_BaseDir) || chdir(DirName()) || chdir(data.name)) continue;
228 CPlugin *newpi = NewEntry(data.name);
229 if(file = fopen(TextName2(), "rb")){
230 if(!newpi->PreLoad(file)){
231 delete newpi;
232 continue;
233 }
234 }else if(TextName() && (file = fopen(TextName(), "rt"))){
235 if(!newpi->PreLoadOldForm(file)){
236 delete newpi;
237 continue;
238 }
239 }else{
240 delete newpi;
241 continue;
242 }
243 newpi->m_State = 1;
244 *adr = newpi;
245 adr = &newpi->m_Next;
246 m_PluginNum++;
247 } while(!_findnext(filelist, &data));
248 _findclose(filelist);
249 }
250 return true;
251 }
252
253 /*
254 * 定義ファイルのロード
255 */
256 bool CPluginList::LoadOne(
257 char *defpath, // 定義ファイルパス
258 char *piid, // プラグイン ID
259 bool oldform // RS1PI
260 ){
261 CPlugin **adr = &m_List;
262 while(*adr) adr = &(*adr)->m_Next;
263 if(chdir(g_BaseDir)) return false;
264 FILE *file;
265 CPlugin *newpi = NewEntry(piid);
266 bool success = false;
267 if(oldform){
268 if(file = fopen(defpath, "rt")){
269 if(newpi->PreLoadOldForm(file)) success = true;
270 else fclose(file);
271 }
272 }else{
273 if(file = fopen(defpath, "rb")){
274 if(newpi->PreLoad(file)) success = true;
275 else fclose(file);
276 }
277 }
278 if(!success){
279 delete newpi;
280 return false;
281 }
282 newpi->m_State = 1;
283 *adr = newpi;
284 m_PluginNum++;
285 return true;
286 }
287
288 /*
289 * ID からプラグインを探す
290 */
291 CPlugin *CPluginList::FindPlugin(
292 const char *id, // ID
293 bool load // 読込フラグ
294 ){
295 if(!*id) return NULL;
296 CPlugin *ptr = m_List;
297 while(ptr){
298 if(!_mbsicmp((PUCHAR)id, (PUCHAR)ptr->m_ID.c_str()))
299 return load ? ptr->LoadAndGet() : ptr;
300 ptr = ptr->m_Next;
301 }
302 if(Default() && _mbsicmp((PUCHAR)id, (PUCHAR)Default()))
303 return FindPlugin(Default(), load);
304 g_LackPlugin.insert(FlashIn("%s\\%s", DirName(), id));
305 return NULL;
306 }
307
308 /*
309 * 利用可能なプラグインを探す
310 */
311 CPlugin *CPluginList::FindAvailable(){
312 CPlugin *ptr = m_List;
313 while(ptr){
314 if(ptr->LoadAndGet()) return ptr;
315 ptr = ptr->m_Next;
316 }
317 return NULL;
318 }
319
320 /*
321 * プラグインツリー構築
322 */
323 void CPluginList::BuildTree(
324 CPluginTree *tree // ツリービュー
325 ){
326 CPlugin *ptr = m_List;
327 CTreeDirElement *root = tree->GetRoot();
328 while(ptr){
329 if(!ptr->m_InsertTreeFlag) ptr->InsertItem(root, tree);
330 ptr = ptr->m_Next;
331 }
332 tree->GetRoot()->Sort(true);
333 }
334
335 ////////////////////////////////////////////////////////////////////////////////
336 ////////////////////////////////////////////////////////////////////////////////
337
338 /*
339 * テキストファイルをバイナリでロード
340 */
341 char *LoadBinaryText(
342 FILE *file, // ファイル
343 int maxbyte // 読込最大サイズ
344 ){
345 if(!file) return NULL;
346 fseek(file, 0, SEEK_END);
347 int size = ftell(file);
348 if(0<=maxbyte && maxbyte<size) size = maxbyte;
349 fseek(file, 0, SEEK_SET);
350 char *buf = new char[size+1];
351 if(fread(buf, size, 1, file)!=1){
352 fclose(file);
353 delete [] buf;
354 return NULL;
355 }
356 buf[size] = 0;
357 fclose(file);
358 return buf;
359 }
360
361 /*
362 * テキストファイルをバイナリでロード
363 */
364 char *LoadBinaryText(
365 char *fname, // ファイル名
366 int maxbyte // 読込最大サイズ
367 ){
368 return LoadBinaryText(fopen(fname, "rb"), maxbyte);
369 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26