Editor Interface.cpp 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. static Int Compare(C Edit::Elm &elm, C UID &id) {return Compare(elm.id, id);}
  5. namespace Edit{
  6. /******************************************************************************/
  7. #define EI_VER 34 // this needs to be increased every time a new command is added, existing one is changed, or some of engine class file formats get updated
  8. #define EI_STR "Esenthel Editor Network Interface"
  9. #define CLIENT_WAIT_TIME ( 60*1000) // 60 seconds
  10. #define CLIENT_WAIT_TIME_LONG ( 6*60*1000) // 6*60 seconds, some operations may take a long time to complete
  11. #define CLIENT_WAIT_TIME_PUBLISH (60*60*1000) // 60*60 seconds, publishing may take very long time (especially when creating PVRTC textures)
  12. ASSERT( EI_NUM<=256); // because they're stored as bytes
  13. ASSERT(ELM_NUM<=256); // because they're stored as bytes
  14. /******************************************************************************/
  15. static Str ElmFullData(C MemPtr<Elm> &elms, C UID &elm_id, Str &name, Bool &removed, Bool &publish) // 'elms' must be sorted by their ID
  16. {
  17. name .clear();
  18. removed=false;
  19. publish=true ;
  20. Memt<UID> processed;
  21. for( UID cur_id=elm_id; cur_id.valid(); )
  22. {
  23. if( processed.binaryInclude(cur_id, Compare)) // not yet processed
  24. if(C Elm *elm=elms.binaryFind (cur_id, Compare)) // was found in elements
  25. {
  26. name =(name.is() ? elm->name+'\\'+name : elm->name);
  27. removed|=elm->removed;
  28. publish&=elm->publish;
  29. cur_id =elm->parent_id;
  30. continue;
  31. }
  32. break;
  33. }
  34. return name;
  35. }
  36. /******************************************************************************/
  37. // MATERIAL MAP
  38. /******************************************************************************/
  39. void MaterialMap::create(Int resolution)
  40. {
  41. _m .createSoftTry(resolution, resolution, 1, IMAGE_R8G8B8A8);
  42. _i .createSoftTry(resolution, resolution, 1, IMAGE_R8G8B8A8);
  43. _ip.clear();
  44. }
  45. void MaterialMap::del()
  46. {
  47. _m .del();
  48. _i .del();
  49. _ip.del();
  50. }
  51. Int MaterialMap::resolution()C {return _m.w();}
  52. /******************************************************************************/
  53. void MaterialMap::set(Int x, Int y, C UID &m0, C UID &m1, C UID &m2, C UID &m3, C VecB4 &blend)
  54. {
  55. _m.color(x, y, Color(_ip.getIDIndex0(m0), _ip.getIDIndex0(m1), _ip.getIDIndex0(m2), _ip.getIDIndex0(m3)));
  56. _i.color(x, y, Color( blend.x , blend.y , blend.z , blend.w ));
  57. }
  58. void MaterialMap::set(Int x, Int y, C UID &m0, C UID &m1, C UID &m2, C UID &m3, C Vec4 &blend)
  59. {
  60. Vec4 b=blend; if(Flt sum=b.sum())b/=sum; // normalize blends
  61. _m.color (x, y, Color(_ip.getIDIndex0(m0), _ip.getIDIndex0(m1), _ip.getIDIndex0(m2), _ip.getIDIndex0(m3)));
  62. _i.colorF(x, y, b);
  63. }
  64. void MaterialMap::get(Int x, Int y, UID &m0, UID &m1, UID &m2, UID &m3, VecB4 &blend)
  65. {
  66. Color m=_m.color(x, y),
  67. i=_i.color(x, y);
  68. m0=(InRange(m.r, _ip) ? _ip[m.r] : UIDZero);
  69. m1=(InRange(m.g, _ip) ? _ip[m.g] : UIDZero);
  70. m2=(InRange(m.b, _ip) ? _ip[m.b] : UIDZero);
  71. m3=(InRange(m.a, _ip) ? _ip[m.a] : UIDZero);
  72. blend.set(i.r, i.g, i.b, i.a);
  73. }
  74. void MaterialMap::get(Int x, Int y, UID &m0, UID &m1, UID &m2, UID &m3, Vec4 &blend)
  75. {
  76. Color m=_m.color (x, y);
  77. Vec4 i=_i.colorF(x, y);
  78. m0=(InRange(m.r, _ip) ? _ip[m.r] : UIDZero);
  79. m1=(InRange(m.g, _ip) ? _ip[m.g] : UIDZero);
  80. m2=(InRange(m.b, _ip) ? _ip[m.b] : UIDZero);
  81. m3=(InRange(m.a, _ip) ? _ip[m.a] : UIDZero);
  82. blend.set(i.x, i.y, i.z, i.w);
  83. }
  84. /******************************************************************************/
  85. void MaterialMap::resize(Int resolution)
  86. {
  87. MAX(resolution, 0);
  88. if (resolution!=T.resolution())
  89. {
  90. _m.resize(resolution, resolution, FILTER_NONE, true, false, true);
  91. _i.resize(resolution, resolution, FILTER_NONE, true, false, true);
  92. }
  93. }
  94. /******************************************************************************/
  95. Bool MaterialMap::save(File &f)C
  96. {
  97. f.cmpUIntV(0); // version
  98. if(_m .save(f))
  99. if(_i .save(f))
  100. if(_ip.save(f))
  101. return f.ok();
  102. return false;
  103. }
  104. Bool MaterialMap::load(File &f)
  105. {
  106. switch(f.decUIntV())
  107. {
  108. case 0:
  109. {
  110. if(_m .load(f))
  111. if(_i .load(f))
  112. if(_ip.load(f))
  113. if(f.ok())return true;
  114. }break;
  115. }
  116. del(); return false;
  117. }
  118. /******************************************************************************/
  119. // FILE PARAMS
  120. /******************************************************************************/
  121. TextParam& FileParams:: getParam(C Str &name) {if(TextParam *par=findParam(name))return *par; return params.New().setName(name);}
  122. TextParam* FileParams::findParam(C Str &name)
  123. {
  124. Int i=0;
  125. if(InRange(i, params))FREPAD(j, params) // process in order
  126. {
  127. XmlParam &param=params[j]; if(param.name==name)
  128. {
  129. if(i==0)return &param; i--;
  130. }
  131. }
  132. return null;
  133. }
  134. /******************************************************************************/
  135. Str FileParams::encode()C
  136. {
  137. Str s=name; FREPA(params)
  138. {
  139. C TextParam &param=params[i]; s+='?'; s+=param.name; if(param.value.is()){s+='='; s+=param.value;}
  140. }
  141. return s;
  142. }
  143. void FileParams::decode(C Str &s)
  144. {
  145. Memc<Str> strs=Split(s, '?');
  146. name=(strs.elms() ? strs[0] : S);
  147. params.setNum(strs.elms()-1); FREPA(params)
  148. {
  149. TextParam &param=params[i];
  150. Str &str =strs[i+1]; FREPA(str)if(str()[i]=='=') // find first '=' occurrence
  151. {
  152. param.value=str()+i+1;
  153. param.name =str.clip(i);
  154. goto param_set;
  155. }
  156. param.set(str);
  157. param_set:;
  158. }
  159. }
  160. /******************************************************************************/
  161. Str FileParams::Encode(C MemPtr<FileParams> &file_params)
  162. {
  163. Str s; FREPA(file_params)
  164. {
  165. if(i)s+='\n'; s+=file_params[i].encode();
  166. }
  167. return s;
  168. }
  169. Mems<FileParams> FileParams::Decode(C Str &str)
  170. {
  171. Mems<FileParams> files; if(str.is())
  172. {
  173. Memc<Str> strs=Split(str, '\n'); // get list of all files
  174. files.setNum(strs.elms()); FREPAO(files).decode(strs[i]);
  175. }
  176. return files;
  177. }
  178. Str FileParams::Merge(C Str &a, C Str &b)
  179. {
  180. return a.is() ? b.is() ? a+'\n'+b : a : b;
  181. }
  182. /******************************************************************************/
  183. static Str Encode( C Mems <FileParams> &file_params) {return FileParams::Encode(ConstCast(file_params));}
  184. static void Decode(File &f, MemPtr<FileParams> file_params) {file_params=FileParams::Decode(f.getStr());}
  185. /******************************************************************************/
  186. // MATERIAL
  187. /******************************************************************************/
  188. Material& Material::reset()
  189. {
  190. technique=MTECH_DEFAULT;
  191. cull=true;
  192. flip_normal_y=false;
  193. high_quality_ios=false;
  194. downsize_tex_mobile=0;
  195. color=1;
  196. ambient=0;
  197. specular=0;
  198. glow=0;
  199. roughness=0;
  200. bump=0;
  201. reflection=0;
  202. color_map.clear(); alpha_map.clear();
  203. bump_map.clear(); normal_map.clear();
  204. specular_map.clear();
  205. glow_map.clear();
  206. reflection_map.clear();
  207. detail_color.clear();
  208. detail_bump.clear();
  209. detail_normal.clear();
  210. macro_map.clear();
  211. light_map.clear();
  212. return T;
  213. }
  214. void Material::save(File &f)C
  215. {
  216. f.cmpUIntV(0);
  217. f<<technique<<cull<<flip_normal_y<<high_quality_ios<<downsize_tex_mobile<<color<<ambient<<specular<<glow<<roughness<<bump<<reflection
  218. <<Encode(color_map)<<Encode(alpha_map)
  219. <<Encode( bump_map)<<Encode(normal_map)
  220. <<Encode(specular_map)
  221. <<Encode(glow_map)
  222. <<Encode(reflection_map)
  223. <<Encode(detail_color)
  224. <<Encode(detail_bump)
  225. <<Encode(detail_normal)
  226. <<Encode(macro_map)
  227. <<Encode(light_map);
  228. }
  229. Bool Material::load(File &f)
  230. {
  231. switch(f.decUIntV())
  232. {
  233. case 0:
  234. {
  235. f>>technique>>cull>>flip_normal_y>>high_quality_ios>>downsize_tex_mobile>>color>>ambient>>specular>>glow>>roughness>>bump>>reflection;
  236. Decode(f, color_map); Decode(f, alpha_map);
  237. Decode(f, bump_map); Decode(f, normal_map);
  238. Decode(f, specular_map);
  239. Decode(f, glow_map);
  240. Decode(f, reflection_map);
  241. Decode(f, detail_color);
  242. Decode(f, detail_bump);
  243. Decode(f, detail_normal);
  244. Decode(f, macro_map);
  245. Decode(f, light_map);
  246. if(f.ok())return true;
  247. }break;
  248. }
  249. return false;
  250. }
  251. /******************************************************************************/
  252. // OBJ DATA
  253. /******************************************************************************/
  254. ObjChange::ObjChange()
  255. {
  256. cmd=EI_OBJ_NONE;
  257. type=PARAM_TYPE(0);
  258. id.zero();
  259. }
  260. void ObjChange:: removeParam(C UID &param_id ) {cmd=EI_OBJ_PARAM_REMOVE_ID ; T.id =param_id;}
  261. void ObjChange:: removeParam(C Str &param_name, PARAM_TYPE param_type) {cmd=EI_OBJ_PARAM_REMOVE_NAME ; T.name=param_name; T.type=param_type;}
  262. void ObjChange::restoreParam(C UID &param_id ) {cmd=EI_OBJ_PARAM_RESTORE_ID ; T.id =param_id;}
  263. void ObjChange::restoreParam(C Str &param_name, PARAM_TYPE param_type) {cmd=EI_OBJ_PARAM_RESTORE_NAME; T.name=param_name; T.type=param_type;}
  264. void ObjChange::renameParam(C UID &param_id , C Str &param_new_name ) {cmd=EI_OBJ_PARAM_RENAME_ID ; T.id =param_id ; T.param.name=param_new_name;}
  265. void ObjChange::renameParam(C Str &param_old_name, C Str &param_new_name, PARAM_TYPE param_type) {cmd=EI_OBJ_PARAM_RENAME_NAME; T.name=param_old_name; T.type=param_type; T.param.name=param_new_name;}
  266. void ObjChange::setParamTypeValue(C UID &param_id , C Param &type_value ) {cmd=EI_OBJ_PARAM_SET_TYPE_VALUE_ID ; T.id =param_id ; T.param=type_value;}
  267. void ObjChange::setParamTypeValue(C Str &param_name, C Param &type_value, PARAM_TYPE param_old_type) {cmd=EI_OBJ_PARAM_SET_TYPE_VALUE_NAME; T.name=param_name; T.type=param_old_type; T.param=type_value;}
  268. Bool ObjChange::save(File &f, CChar *path)C
  269. {
  270. f<<cmd<<type<<id<<name; return param.save(f, path) && f.ok();
  271. }
  272. Bool ObjChange::load(File &f, CChar *path)
  273. {
  274. f>>cmd>>type>>id>>name; if(param.load(f, path) && f.ok())return true;
  275. /*del();*/ return false;
  276. }
  277. /******************************************************************************/
  278. ObjData& ObjData::reset()
  279. {
  280. elm_obj_class_id.zero();
  281. access=OBJ_ACCESS_TERRAIN;
  282. path =OBJ_PATH_CREATE;
  283. params.clear();
  284. return T;
  285. }
  286. ObjData::Param* ObjData::findParam(C Str &name, PARAM_TYPE type, Bool include_removed, Bool include_inherited)
  287. {
  288. FREPA(params) // check in order, because Editor lists params from current object first (which we're the most interested in), then adds base/parent params later
  289. {
  290. Param &param=params[i];
  291. if( param.name==name // don't try to break when encountered a param with the same 'name', because there can be multiple params with the same name but different type/removed
  292. && (type==PARAM_NUM || type==param.type)
  293. && (include_removed || !param. removed)
  294. && (include_inherited || !param.inherited)
  295. )return &param;
  296. }
  297. return null;
  298. }
  299. Bool ObjData::save(File &f)C {f<<elm_obj_class_id<<access<<path; return params.save(f) && f.ok();}
  300. Bool ObjData::load(File &f) {f>>elm_obj_class_id>>access>>path; return params.load(f) && f.ok();}
  301. /******************************************************************************/
  302. // CLIENT
  303. /******************************************************************************/
  304. Bool EditorInterface:: connected() {_conn.updateState(0); return _conn.state()==CONNECT_GREETED;} // try to receive data so we check if connection got disconnected
  305. void EditorInterface::disconnect ()
  306. {
  307. _conn.del();
  308. }
  309. struct ConnectAttempt : Connection
  310. {
  311. Bool sent, bad_ver;
  312. ConnectAttempt() {sent=bad_ver=false;}
  313. void create(Int port) {clientConnectToServer(SockAddr().setLocalFast(port));}
  314. Bool update()
  315. {
  316. if(updateState(0))
  317. {
  318. if(!sent)
  319. {
  320. sent=true;
  321. data.reset().putByte(EI_VERSION_CHECK).putStr(EI_STR).cmpUIntV(EI_VER).pos(0);
  322. if(!send(data))del();
  323. }
  324. if(receive(0))
  325. {
  326. if( data.getByte()==EI_VERSION_CHECK)
  327. if(Equal(data.getStr (), EI_STR, true))
  328. {
  329. bad_ver=(data.decUIntV()!=EI_VER);
  330. if(!bad_ver)
  331. {
  332. tcpNoDelay(true);
  333. return true;
  334. }
  335. }
  336. del();
  337. }
  338. }
  339. return false;
  340. }
  341. };
  342. Bool EditorInterface::connect(Str &message, Int timeout)
  343. {
  344. disconnect();
  345. if(timeout<0)timeout=1000; UInt start_time=Time.curTimeMs();
  346. ConnectAttempt c[128]; FREPAO(c).create(65535-i);
  347. for(;;)
  348. {
  349. Bool connecting=false;
  350. FREPA(c)if(c[i].update())
  351. {
  352. message.clear();
  353. Swap(_conn, SCAST(Connection, c[i]));
  354. return true;
  355. }else if(c[i].state()!=CONNECT_INVALID)connecting=true;
  356. if(!connecting)break;
  357. if((Time.curTimeMs()-start_time)>=timeout)break; // this code was tested OK for UInt overflow
  358. Time.wait(1);
  359. }
  360. REPA(c)if(c[i].bad_ver){message="This Application version is not compatible with the opened Esenthel Editor version.\nPlease upgrade your software."; return false;}
  361. message="Esenthel Editor does not appears to be opened.\nPlease open Esenthel Editor and enable option \"Allow Incoming Connections\"."; return false;
  362. }
  363. /******************************************************************************/
  364. // PROJECTS
  365. /******************************************************************************/
  366. Str EditorInterface::projectsPath()
  367. {
  368. if(connected())
  369. {
  370. File &f=_conn.data.reset(); f.putByte(EI_GET_PROJECTS_PATH).pos(0);
  371. if(_conn.send(f))
  372. if(_conn.receive(CLIENT_WAIT_TIME))
  373. if(f.getByte()==EI_GET_PROJECTS_PATH)return f.getStr();
  374. disconnect();
  375. }
  376. return S;
  377. }
  378. Bool EditorInterface::projectsPath(C Str &path)
  379. {
  380. if(connected())
  381. {
  382. File &f=_conn.data.reset(); f.putByte(EI_SET_PROJECTS_PATH).putStr(path).pos(0);
  383. if(_conn.send(f))
  384. if(_conn.receive(CLIENT_WAIT_TIME))
  385. if(f.getByte()==EI_SET_PROJECTS_PATH)return f.getBool();
  386. disconnect();
  387. }
  388. return false;
  389. }
  390. Bool EditorInterface::getProjects(MemPtr<Project> projects)
  391. {
  392. if(connected())
  393. {
  394. File &f=_conn.data.reset(); f.putByte(EI_GET_PROJECTS).pos(0);
  395. if(_conn.send(f))
  396. if(_conn.receive(CLIENT_WAIT_TIME))
  397. if(f.getByte()==EI_GET_PROJECTS)
  398. if(projects.load(f))return true;
  399. disconnect();
  400. }
  401. projects.clear(); return false;
  402. }
  403. UID EditorInterface::curProject()
  404. {
  405. if(connected())
  406. {
  407. File &f=_conn.data.reset(); f.putByte(EI_GET_PROJECT).pos(0);
  408. if(_conn.send(f))
  409. if(_conn.receive(CLIENT_WAIT_TIME))
  410. if(f.getByte()==EI_GET_PROJECT)return f.getUID();
  411. disconnect();
  412. }
  413. return UIDZero;
  414. }
  415. Bool EditorInterface::openProject(C UID &proj_id)
  416. {
  417. if(connected())
  418. {
  419. File &f=_conn.data.reset(); f.putByte(EI_SET_PROJECT).putUID(proj_id).pos(0);
  420. if(_conn.send(f))return curProject()==proj_id;
  421. disconnect();
  422. }
  423. return false;
  424. }
  425. /******************************************************************************/
  426. // SETTINGS
  427. /******************************************************************************/
  428. Str EditorInterface::dataPath()
  429. {
  430. if(connected())
  431. {
  432. File &f=_conn.data.reset(); f.putByte(EI_GET_DATA_PATH).pos(0);
  433. if(_conn.send(f))
  434. if(_conn.receive(CLIENT_WAIT_TIME))
  435. if(f.getByte()==EI_GET_DATA_PATH)return f.getStr();
  436. disconnect();
  437. }
  438. return S;
  439. }
  440. /******************************************************************************/
  441. // ELEMENTS
  442. /******************************************************************************/
  443. Bool EditorInterface::getElms(MemPtr<Elm> elms, Bool include_removed)
  444. {
  445. if(connected())
  446. {
  447. File &f=_conn.data.reset(); f.putByte(EI_GET_ELMS).pos(0);
  448. if(_conn.send(f))
  449. if(_conn.receive(CLIENT_WAIT_TIME))
  450. if(f.getByte()==EI_GET_ELMS)
  451. {
  452. if(f.getBool()) // if success
  453. if(elms.load(f))
  454. {
  455. REPA(elms)
  456. {
  457. Elm &elm=elms[i];
  458. ElmFullData(elms, elm.id, elm.full_name, elm.final_removed, elm.final_publish); // setup full values for convenience
  459. }
  460. if(!include_removed) // call this at the end, once all elements have been setup, so we won't remove an element that still has unprocessed children, do this on the client, to avoid overloading the server
  461. REPA(elms)if(elms[i].final_removed)elms.remove(i, true); // need to keep order because elements are sorted by ID
  462. return true;
  463. }
  464. goto fail;
  465. }
  466. disconnect();
  467. }
  468. fail:;
  469. elms.clear(); return false;
  470. }
  471. Bool EditorInterface::selectedElms(MemPtr<UID> elms)
  472. {
  473. if(connected())
  474. {
  475. File &f=_conn.data.reset(); f.putByte(EI_GET_ELMS_SELECTED).pos(0);
  476. if(_conn.send(f))
  477. if(_conn.receive(CLIENT_WAIT_TIME))
  478. if(f.getByte()==EI_GET_ELMS_SELECTED)
  479. {
  480. if(f.getBool()) // if success
  481. if(elms.loadRaw(f))return true;
  482. goto fail;
  483. }
  484. disconnect();
  485. }
  486. fail:;
  487. elms.clear(); return false;
  488. }
  489. Bool EditorInterface::selectElms(C MemPtr<UID> &elms)
  490. {
  491. if(connected())
  492. {
  493. File &f=_conn.data.reset(); f.putByte(EI_SET_ELMS_SELECTED); elms.saveRaw(f); f.pos(0);
  494. if(_conn.send(f))
  495. if(_conn.receive(CLIENT_WAIT_TIME))
  496. if(f.getByte()==EI_SET_ELMS_SELECTED)return f.getBool();
  497. disconnect();
  498. }
  499. return false;
  500. }
  501. Bool EditorInterface::reloadElms(C MemPtr<UID> &elms, Bool remember_result)
  502. {
  503. if(connected())
  504. {
  505. File &f=_conn.data.reset(); f.putByte(EI_RLD_ELMS)<<remember_result; elms.saveRaw(f); f.pos(0);
  506. if(_conn.send(f))
  507. if(_conn.receive(CLIENT_WAIT_TIME))
  508. if(f.getByte()==EI_RLD_ELMS)return f.getBool();
  509. disconnect();
  510. }
  511. return false;
  512. }
  513. Bool EditorInterface::cancelReloadElms(C MemPtr<UID> &elms)
  514. {
  515. if(connected())
  516. {
  517. File &f=_conn.data.reset(); f.putByte(EI_RLD_ELMS_CANCEL); elms.saveRaw(f); f.pos(0);
  518. if(_conn.send(f))
  519. if(_conn.receive(CLIENT_WAIT_TIME))
  520. if(f.getByte()==EI_RLD_ELMS_CANCEL)return f.getBool();
  521. disconnect();
  522. }
  523. return false;
  524. }
  525. Bool EditorInterface::reloadResult(C MemPtr<UID> &elms, MemPtr< IDParam<RELOAD_RESULT> > results)
  526. {
  527. if(connected())
  528. {
  529. File &f=_conn.data.reset(); f.putByte(EI_RLD_ELMS_GET_RESULT); elms.saveRaw(f); f.pos(0);
  530. if(_conn.send(f))
  531. if(_conn.receive(CLIENT_WAIT_TIME))
  532. if(f.getByte()==EI_RLD_ELMS_GET_RESULT)
  533. {
  534. if(f.getBool())
  535. if(results.load(f))return true;
  536. goto fail;
  537. }
  538. disconnect();
  539. }
  540. fail:
  541. results.clear(); return false;
  542. }
  543. Bool EditorInterface::forgetReloadResult(C MemPtr<UID> &elms)
  544. {
  545. if(connected())
  546. {
  547. File &f=_conn.data.reset(); f.putByte(EI_RLD_ELMS_FORGET_RESULT); elms.saveRaw(f); f.pos(0);
  548. if(_conn.send(f))
  549. if(_conn.receive(CLIENT_WAIT_TIME))
  550. if(f.getByte()==EI_RLD_ELMS_FORGET_RESULT)return f.getBool();
  551. disconnect();
  552. }
  553. return false;
  554. }
  555. UID EditorInterface::newElm(ELM_TYPE type, C Str &name, C UID &parent_id)
  556. {
  557. if(connected())
  558. {
  559. File &f=_conn.data.reset(); f.putByte(EI_NEW_ELM).putByte(type).putStr(name).putUID(parent_id).pos(0);
  560. if(_conn.send(f))
  561. if(_conn.receive(CLIENT_WAIT_TIME))
  562. if(f.getByte()==EI_NEW_ELM)return f.getUID();
  563. disconnect();
  564. }
  565. return UIDZero;
  566. }
  567. UID EditorInterface::newWorld(C Str &name, Int area_size, Int terrain_res, C UID &parent_id)
  568. {
  569. if(connected())
  570. {
  571. File &f=_conn.data.reset(); f.putByte(EI_NEW_WORLD).putStr(name).putInt(area_size).putInt(terrain_res).putUID(parent_id).pos(0);
  572. if(_conn.send(f))
  573. if(_conn.receive(CLIENT_WAIT_TIME))
  574. if(f.getByte()==EI_NEW_WORLD)return f.getUID();
  575. disconnect();
  576. }
  577. return UIDZero;
  578. }
  579. /******************************************************************************/
  580. Bool EditorInterface::setElmName(C MemPtr< IDParam<Str> > &elms)
  581. {
  582. if(connected())
  583. {
  584. File &f=_conn.data.reset(); f.putByte(EI_SET_ELM_NAME); elms.save(f); f.pos(0);
  585. if(_conn.send(f))
  586. if(_conn.receive(CLIENT_WAIT_TIME))
  587. if(f.getByte()==EI_SET_ELM_NAME)return f.getBool();
  588. disconnect();
  589. }
  590. return false;
  591. }
  592. Bool EditorInterface::setElmRemoved(C MemPtr< IDParam<Bool> > &elms)
  593. {
  594. if(connected())
  595. {
  596. File &f=_conn.data.reset(); f.putByte(EI_SET_ELM_REMOVED); elms.save(f); f.pos(0);
  597. if(_conn.send(f))
  598. if(_conn.receive(CLIENT_WAIT_TIME))
  599. if(f.getByte()==EI_SET_ELM_REMOVED)return f.getBool();
  600. disconnect();
  601. }
  602. return false;
  603. }
  604. Bool EditorInterface::setElmPublish(C MemPtr< IDParam<Bool> > &elms)
  605. {
  606. if(connected())
  607. {
  608. File &f=_conn.data.reset(); f.putByte(EI_SET_ELM_PUBLISH); elms.save(f); f.pos(0);
  609. if(_conn.send(f))
  610. if(_conn.receive(CLIENT_WAIT_TIME))
  611. if(f.getByte()==EI_SET_ELM_PUBLISH)return f.getBool();
  612. disconnect();
  613. }
  614. return false;
  615. }
  616. Bool EditorInterface::setElmParent(C MemPtr< IDParam<UID> > &elms)
  617. {
  618. if(connected())
  619. {
  620. File &f=_conn.data.reset(); f.putByte(EI_SET_ELM_PARENT); elms.save(f); f.pos(0);
  621. if(_conn.send(f))
  622. if(_conn.receive(CLIENT_WAIT_TIME))
  623. if(f.getByte()==EI_SET_ELM_PARENT)return f.getBool();
  624. disconnect();
  625. }
  626. return false;
  627. }
  628. Bool EditorInterface::setElmSrcFile(C MemPtr< IDParam<Str> > &elms)
  629. {
  630. if(connected())
  631. {
  632. File &f=_conn.data.reset(); f.putByte(EI_SET_ELM_SRC_FILE); elms.save(f); f.pos(0);
  633. if(_conn.send(f))
  634. if(_conn.receive(CLIENT_WAIT_TIME))
  635. if(f.getByte()==EI_SET_ELM_SRC_FILE)return f.getBool();
  636. disconnect();
  637. }
  638. return false;
  639. }
  640. /******************************************************************************/
  641. // WORLD
  642. /******************************************************************************/
  643. UID EditorInterface::curWorld()
  644. {
  645. if(connected())
  646. {
  647. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD).pos(0);
  648. if(_conn.send(f))
  649. if(_conn.receive(CLIENT_WAIT_TIME))
  650. if(f.getByte()==EI_GET_WORLD)return f.getUID();
  651. disconnect();
  652. }
  653. return UIDZero;
  654. }
  655. Bool EditorInterface::openWorld(C UID &world_id)
  656. {
  657. if(connected())
  658. {
  659. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD).putUID(world_id).pos(0);
  660. if(_conn.send(f))
  661. if(_conn.receive(CLIENT_WAIT_TIME))
  662. if(f.getByte()==EI_SET_WORLD)return f.getBool();
  663. disconnect();
  664. }
  665. return false;
  666. }
  667. Int EditorInterface::worldAreaSize(C UID &world_id)
  668. {
  669. if(world_id.valid() && connected())
  670. {
  671. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_AREA_SIZE).putUID(world_id).pos(0);
  672. if(_conn.send(f))
  673. if(_conn.receive(CLIENT_WAIT_TIME))
  674. if(f.getByte()==EI_GET_WORLD_AREA_SIZE)return f.getInt();
  675. disconnect();
  676. }
  677. return 0;
  678. }
  679. /******************************************************************************/
  680. // WORLD TERRAIN
  681. /******************************************************************************/
  682. Int EditorInterface::worldTerrainRes(C UID &world_id)
  683. {
  684. if(world_id.valid() && connected())
  685. {
  686. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_RES).putUID(world_id).pos(0);
  687. if(_conn.send(f))
  688. if(_conn.receive(CLIENT_WAIT_TIME))
  689. if(f.getByte()==EI_GET_WORLD_TERRAIN_RES)return f.getInt();
  690. disconnect();
  691. }
  692. return 0;
  693. }
  694. Bool EditorInterface::worldTerrainAreas(C UID &world_id, RectI &areas)
  695. {
  696. if(world_id.valid() && connected())
  697. {
  698. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_AREAS).putUID(world_id).pos(0);
  699. if(_conn.send(f))
  700. if(_conn.receive(CLIENT_WAIT_TIME))
  701. if(f.getByte()==EI_GET_WORLD_TERRAIN_AREAS)
  702. {
  703. if(f.getBool()){f>>areas; return true;}
  704. goto fail;
  705. }
  706. disconnect();
  707. }
  708. fail:;
  709. areas.set(0, 0, -1, -1); return !world_id.valid();
  710. }
  711. /******************************************************************************/
  712. Bool EditorInterface::worldTerrainDel(C UID &world_id, C VecI2 &area_xy)
  713. {
  714. if(world_id.valid() && connected())
  715. {
  716. File &f=_conn.data.reset(); f.putByte(EI_DEL_WORLD_TERRAIN).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).pos(0);
  717. if(_conn.send(f))
  718. if(_conn.receive(CLIENT_WAIT_TIME))
  719. if(f.getByte()==EI_DEL_WORLD_TERRAIN)return f.getBool();
  720. disconnect();
  721. }
  722. return false;
  723. }
  724. Bool EditorInterface::worldTerrainExists(C UID &world_id, C VecI2 &area_xy)
  725. {
  726. if(world_id.valid() && connected())
  727. {
  728. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_IS).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).pos(0);
  729. if(_conn.send(f))
  730. if(_conn.receive(CLIENT_WAIT_TIME))
  731. if(f.getByte()==EI_GET_WORLD_TERRAIN_IS)return f.getBool();
  732. disconnect();
  733. }
  734. return false;
  735. }
  736. /******************************************************************************/
  737. Bool EditorInterface::worldTerrainGetHeight(C UID &world_id, C VecI2 &area_xy, Image &height)
  738. {
  739. if(world_id.valid() && connected())
  740. {
  741. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_HEIGHT).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).pos(0);
  742. if(_conn.send(f))
  743. if(_conn.receive(CLIENT_WAIT_TIME))
  744. if(f.getByte()==EI_GET_WORLD_TERRAIN_HEIGHT)
  745. {
  746. if(f.getBool())return height.load(f);
  747. goto fail;
  748. }
  749. disconnect();
  750. }
  751. fail:;
  752. height.del(); return !world_id.valid();
  753. }
  754. Bool EditorInterface::worldTerrainSetHeight(C UID &world_id, C VecI2 &area_xy, C Image &height, C UID &material_id)
  755. {
  756. if(world_id.valid() && connected())
  757. {
  758. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD_TERRAIN_HEIGHT).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).putUID(material_id); height.save(f); f.pos(0);
  759. if(_conn.send(f))
  760. if(_conn.receive(CLIENT_WAIT_TIME))
  761. if(f.getByte()==EI_SET_WORLD_TERRAIN_HEIGHT)return f.getBool();
  762. disconnect();
  763. }
  764. return false;
  765. }
  766. /******************************************************************************/
  767. Bool EditorInterface::worldTerrainGetColor(C UID &world_id, C VecI2 &area_xy, Image &color)
  768. {
  769. if(world_id.valid() && connected())
  770. {
  771. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_COLOR).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).pos(0);
  772. if(_conn.send(f))
  773. if(_conn.receive(CLIENT_WAIT_TIME))
  774. if(f.getByte()==EI_GET_WORLD_TERRAIN_COLOR)
  775. {
  776. if(f.getBool())return color.load(f);
  777. goto fail;
  778. }
  779. disconnect();
  780. }
  781. fail:;
  782. color.del(); return !world_id.valid();
  783. }
  784. Bool EditorInterface::worldTerrainSetColor(C UID &world_id, C VecI2 &area_xy, C Image &color, C UID &material_id)
  785. {
  786. if(world_id.valid() && connected())
  787. {
  788. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD_TERRAIN_COLOR).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).putUID(material_id); color.save(f); f.pos(0);
  789. if(_conn.send(f))
  790. if(_conn.receive(CLIENT_WAIT_TIME))
  791. if(f.getByte()==EI_SET_WORLD_TERRAIN_COLOR)return f.getBool();
  792. disconnect();
  793. }
  794. return false;
  795. }
  796. /******************************************************************************/
  797. Bool EditorInterface::worldTerrainGetMaterial(C UID &world_id, C VecI2 &area_xy, MaterialMap &material)
  798. {
  799. if(world_id.valid() && connected())
  800. {
  801. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN_MATERIAL).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).pos(0);
  802. if(_conn.send(f))
  803. if(_conn.receive(CLIENT_WAIT_TIME))
  804. if(f.getByte()==EI_GET_WORLD_TERRAIN_MATERIAL)
  805. {
  806. if(f.getBool())return material.load(f);
  807. goto fail;
  808. }
  809. disconnect();
  810. }
  811. fail:;
  812. material.del(); return !world_id.valid();
  813. }
  814. Bool EditorInterface::worldTerrainSetMaterial(C UID &world_id, C VecI2 &area_xy, C MaterialMap &material)
  815. {
  816. if(world_id.valid() && connected())
  817. {
  818. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD_TERRAIN_MATERIAL).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y); material.save(f); f.pos(0);
  819. if(_conn.send(f))
  820. if(_conn.receive(CLIENT_WAIT_TIME))
  821. if(f.getByte()==EI_SET_WORLD_TERRAIN_MATERIAL)return f.getBool();
  822. disconnect();
  823. }
  824. return false;
  825. }
  826. /******************************************************************************/
  827. Bool EditorInterface::worldTerrainGet(C UID &world_id, C VecI2 &area_xy, Image &height, MaterialMap &material, Image *color)
  828. {
  829. if(world_id.valid() && connected())
  830. {
  831. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_TERRAIN).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).putBool(color!=null).pos(0);
  832. if(_conn.send(f))
  833. if(_conn.receive(CLIENT_WAIT_TIME))
  834. if(f.getByte()==EI_GET_WORLD_TERRAIN)
  835. {
  836. if(f.getBool())if(height.load(f))if(material.load(f))if(color ? color->load(f) : true)return true;
  837. goto fail;
  838. }
  839. disconnect();
  840. }
  841. fail:;
  842. height.del(); material.del(); if(color)color->del(); return !world_id.valid();
  843. }
  844. Bool EditorInterface::worldTerrainSet(C UID &world_id, C VecI2 &area_xy, C Image &height, C MaterialMap &material, C Image *color)
  845. {
  846. if(world_id.valid() && connected())
  847. {
  848. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD_TERRAIN).putUID(world_id).cmpIntV(area_xy.x).cmpIntV(area_xy.y).putBool(color!=null); height.save(f); material.save(f); if(color)color->save(f); f.pos(0);
  849. if(_conn.send(f))
  850. if(_conn.receive(CLIENT_WAIT_TIME))
  851. if(f.getByte()==EI_SET_WORLD_TERRAIN)return f.getBool();
  852. disconnect();
  853. }
  854. return false;
  855. }
  856. /******************************************************************************/
  857. // WORLD OBJECTS
  858. /******************************************************************************/
  859. Bool EditorInterface::worldObjCreate(C UID &world_id, C MemPtr<WorldObjParams> &objs)
  860. {
  861. if(world_id.valid() && connected())
  862. {
  863. File &f=_conn.data.reset(); f.putByte(EI_NEW_WORLD_OBJ).putUID(world_id); objs.save(f); f.pos(0);
  864. if(_conn.send(f))
  865. if(_conn.receive(CLIENT_WAIT_TIME))
  866. if(f.getByte()==EI_NEW_WORLD_OBJ)return f.getBool();
  867. disconnect();
  868. }
  869. return false;
  870. }
  871. Bool EditorInterface::worldObjGetDesc(C UID &world_id, MemPtr<WorldObjDesc> objs, C MemPtr<UID> &world_obj_instance_ids, C RectI *areas, Bool only_selected, Bool include_removed)
  872. {
  873. if(world_id.valid() && connected())
  874. {
  875. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_OBJ_BASIC).putUID(world_id).putBool(areas!=null); if(areas)f<<*areas; f<<only_selected<<include_removed; world_obj_instance_ids.saveRaw(f); f.pos(0);
  876. if(_conn.send(f))
  877. if(_conn.receive(CLIENT_WAIT_TIME))
  878. if(f.getByte()==EI_GET_WORLD_OBJ_BASIC)
  879. {
  880. if(f.getBool())return objs.load(f);
  881. goto fail;
  882. }
  883. disconnect();
  884. }
  885. fail:
  886. objs.clear(); return !world_id.valid();
  887. }
  888. Bool EditorInterface::worldObjGetData(C UID &world_id, MemPtr<WorldObjData> objs, C MemPtr<UID> &world_obj_instance_ids, C RectI *areas, Bool only_selected, Bool include_removed, Bool include_removed_params)
  889. {
  890. if(world_id.valid() && connected())
  891. {
  892. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_OBJ_FULL).putUID(world_id).putBool(areas!=null); if(areas)f<<*areas; f<<only_selected<<include_removed<<include_removed_params; world_obj_instance_ids.saveRaw(f); f.pos(0);
  893. if(_conn.send(f))
  894. if(_conn.receive(only_selected ? CLIENT_WAIT_TIME : CLIENT_WAIT_TIME_LONG)) // if world is big then it might take some time to get all objects, so wait for a long time
  895. if(f.getByte()==EI_GET_WORLD_OBJ_FULL)
  896. {
  897. if(f.getBool())return objs.load(f);
  898. goto fail;
  899. }
  900. disconnect();
  901. }
  902. fail:
  903. objs.clear(); return !world_id.valid();
  904. }
  905. // !! when sending object data - HANDLE CORRECT REL PATH FOR OBJ PARAM ENUMS !!
  906. /******************************************************************************/
  907. // WORLD WAYPOINTS
  908. /******************************************************************************/
  909. Bool EditorInterface::worldWaypointGetList(C UID &world_id, MemPtr<UID> waypoint_ids)
  910. {
  911. if(world_id.valid() && connected())
  912. {
  913. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_WAYPOINT_LIST).putUID(world_id); f.pos(0);
  914. if(_conn.send(f))
  915. if(_conn.receive(CLIENT_WAIT_TIME))
  916. if(f.getByte()==EI_GET_WORLD_WAYPOINT_LIST)
  917. {
  918. if(f.getBool())return waypoint_ids.loadRaw(f);
  919. goto fail;
  920. }
  921. disconnect();
  922. }
  923. fail:
  924. waypoint_ids.clear(); return !world_id.valid();
  925. }
  926. /******************************************************************************/
  927. // WORLD CAMERA
  928. /******************************************************************************/
  929. Bool EditorInterface::worldCamGet(Camera &cam)
  930. {
  931. if(connected())
  932. {
  933. File &f=_conn.data.reset(); f.putByte(EI_GET_WORLD_CAM).pos(0);
  934. if(_conn.send(f))
  935. if(_conn.receive(CLIENT_WAIT_TIME))
  936. if(f.getByte()==EI_GET_WORLD_CAM)return cam.load(f);
  937. disconnect();
  938. }
  939. return false;
  940. }
  941. Bool EditorInterface::worldCamSet(C Camera &cam)
  942. {
  943. if(connected())
  944. {
  945. File &f=_conn.data.reset(); f.putByte(EI_SET_WORLD_CAM); cam.save(f); f.pos(0);
  946. if(_conn.send(f))
  947. if(_conn.receive(CLIENT_WAIT_TIME))
  948. if(f.getByte()==EI_SET_WORLD_CAM)return f.getBool();
  949. disconnect();
  950. }
  951. return false;
  952. }
  953. /******************************************************************************/
  954. // WORLD DRAW
  955. /******************************************************************************/
  956. Bool EditorInterface::worldDrawLines(C MemPtr<Line> &lines)
  957. {
  958. if(connected())
  959. {
  960. File &f=_conn.data.reset(); f.putByte(EI_DRAW_WORLD_LINES); lines.save(f); f.pos(0);
  961. if(_conn.send(f))
  962. if(_conn.receive(CLIENT_WAIT_TIME))
  963. if(f.getByte()==EI_DRAW_WORLD_LINES)return f.getBool();
  964. disconnect();
  965. }
  966. return false;
  967. }
  968. /******************************************************************************/
  969. // IMAGE
  970. /******************************************************************************/
  971. Bool EditorInterface::getImage(C UID &elm_id, Image &image)
  972. {
  973. if(elm_id.valid() && connected())
  974. {
  975. File &f=_conn.data.reset(); f.putByte(EI_GET_IMAGE).putUID(elm_id).pos(0);
  976. if(_conn.send(f))
  977. if(_conn.receive(CLIENT_WAIT_TIME))
  978. if(f.getByte()==EI_GET_IMAGE)
  979. {
  980. if(f.getBool())return image.load(f);
  981. goto fail;
  982. }
  983. disconnect();
  984. }
  985. fail:;
  986. image.del(); return !elm_id.valid();
  987. }
  988. Bool EditorInterface::setImage(C UID &elm_id, C Image &image)
  989. {
  990. if(elm_id.valid() && connected())
  991. {
  992. File &f=_conn.data.reset(); f.putByte(EI_SET_IMAGE).putUID(elm_id); image.save(f); f.pos(0);
  993. if(_conn.send(f))
  994. if(_conn.receive(CLIENT_WAIT_TIME))
  995. if(f.getByte()==EI_SET_IMAGE)return f.getBool();
  996. disconnect();
  997. }
  998. return false;
  999. }
  1000. /******************************************************************************/
  1001. // CODE
  1002. /******************************************************************************/
  1003. Bool EditorInterface::getCode(C UID &elm_id, Str &code)
  1004. {
  1005. if(elm_id.valid() && connected())
  1006. {
  1007. File &f=_conn.data.reset(); f.putByte(EI_GET_CODE).putUID(elm_id).pos(0);
  1008. if(_conn.send(f))
  1009. if(_conn.receive(CLIENT_WAIT_TIME))
  1010. if(f.getByte()==EI_GET_CODE)
  1011. {
  1012. if(f.getBool())return code.load(f);
  1013. goto fail;
  1014. }
  1015. disconnect();
  1016. }
  1017. fail:;
  1018. code.clear(); return !elm_id.valid();
  1019. }
  1020. Bool EditorInterface::setCode(C UID &elm_id, C Str &code)
  1021. {
  1022. if(elm_id.valid() && connected())
  1023. {
  1024. File &f=_conn.data.reset(); f.putByte(EI_SET_CODE).putUID(elm_id).putStr(code).pos(0);
  1025. if(_conn.send(f))
  1026. if(_conn.receive(CLIENT_WAIT_TIME))
  1027. if(f.getByte()==EI_SET_CODE)return f.getBool();
  1028. disconnect();
  1029. }
  1030. return false;
  1031. }
  1032. /******************************************************************************/
  1033. Bool EditorInterface::codeSyncImport()
  1034. {
  1035. if(connected())
  1036. {
  1037. File &f=_conn.data.reset(); f.putByte(EI_CODE_SYNC_IMPORT).pos(0);
  1038. if(_conn.send(f))
  1039. if(_conn.receive(CLIENT_WAIT_TIME))
  1040. if(f.getByte()==EI_CODE_SYNC_IMPORT)return f.getBool();
  1041. disconnect();
  1042. }
  1043. return false;
  1044. }
  1045. Bool EditorInterface::codeSyncExport()
  1046. {
  1047. if(connected())
  1048. {
  1049. File &f=_conn.data.reset(); f.putByte(EI_CODE_SYNC_EXPORT).pos(0);
  1050. if(_conn.send(f))
  1051. if(_conn.receive(CLIENT_WAIT_TIME))
  1052. if(f.getByte()==EI_CODE_SYNC_EXPORT)return f.getBool();
  1053. disconnect();
  1054. }
  1055. return false;
  1056. }
  1057. /******************************************************************************/
  1058. // FILE
  1059. /******************************************************************************/
  1060. Bool EditorInterface::getFile(C UID &elm_id, File &data)
  1061. {
  1062. if(elm_id.valid() && connected())
  1063. {
  1064. File &f=_conn.data.reset(); f.putByte(EI_GET_FILE).putUID(elm_id).pos(0);
  1065. if(_conn.send(f))
  1066. if(_conn.receive(CLIENT_WAIT_TIME))
  1067. if(f.getByte()==EI_GET_FILE)
  1068. {
  1069. if(f.getBool())return f.copy(data);
  1070. return false;
  1071. }
  1072. disconnect();
  1073. }
  1074. return !elm_id.valid();
  1075. }
  1076. Bool EditorInterface::setFile(C UID &elm_id, File &data)
  1077. {
  1078. if(elm_id.valid() && connected())
  1079. {
  1080. File &f=_conn.data.reset(); f.putByte(EI_SET_FILE).putUID(elm_id); data.copy(f); f.pos(0);
  1081. if(_conn.send(f))
  1082. if(_conn.receive(CLIENT_WAIT_TIME))
  1083. if(f.getByte()==EI_SET_FILE)return f.getBool();
  1084. disconnect();
  1085. }
  1086. return false;
  1087. }
  1088. /******************************************************************************/
  1089. // MESH
  1090. /******************************************************************************/
  1091. Bool EditorInterface::getMesh(C UID &elm_id, Mesh &mesh, Matrix *matrix)
  1092. {
  1093. if(elm_id.valid() && connected())
  1094. {
  1095. File &f=_conn.data.reset(); f.putByte(EI_GET_MESH).putUID(elm_id).pos(0);
  1096. if(_conn.send(f))
  1097. if(_conn.receive(CLIENT_WAIT_TIME))
  1098. if(f.getByte()==EI_GET_MESH)
  1099. {
  1100. if(f.getBool())
  1101. {
  1102. if(matrix)f>>*matrix;else f.skip(SIZE(*matrix));
  1103. if(!f.left()) // object may exist, but its mesh may not be set yet, in that case OK will be true, but no data available
  1104. {
  1105. mesh.del();
  1106. return true;
  1107. }
  1108. if(mesh.load(f))
  1109. {
  1110. mesh.setAutoTanBin().setRender();
  1111. return true;
  1112. }
  1113. }
  1114. return false;
  1115. }
  1116. disconnect();
  1117. }
  1118. mesh.del(); return !elm_id.valid();
  1119. }
  1120. Bool EditorInterface::setMesh(C UID &elm_id, C Mesh &mesh)
  1121. {
  1122. if(elm_id.valid() && connected())
  1123. {
  1124. File &f=_conn.data.reset(); f.putByte(EI_SET_MESH).putUID(elm_id); mesh.save(f); f.pos(0);
  1125. if(_conn.send(f))
  1126. if(_conn.receive(CLIENT_WAIT_TIME))
  1127. if(f.getByte()==EI_SET_MESH)return f.getBool();
  1128. disconnect();
  1129. }
  1130. return false;
  1131. }
  1132. /******************************************************************************/
  1133. // MATERIAL
  1134. /******************************************************************************/
  1135. UID EditorInterface::curMaterial()
  1136. {
  1137. if(connected())
  1138. {
  1139. File &f=_conn.data.reset(); f.putByte(EI_GET_MTRL_CUR).pos(0);
  1140. if(_conn.send(f))
  1141. if(_conn.receive(CLIENT_WAIT_TIME))
  1142. if(f.getByte()==EI_GET_MTRL_CUR)return f.getUID();
  1143. disconnect();
  1144. }
  1145. return UIDZero;
  1146. }
  1147. Bool EditorInterface::curMaterial(C UID &elm_id)
  1148. {
  1149. if(connected())
  1150. {
  1151. File &f=_conn.data.reset(); f.putByte(EI_SET_MTRL_CUR).putUID(elm_id).pos(0);
  1152. if(_conn.send(f))
  1153. if(_conn.receive(CLIENT_WAIT_TIME))
  1154. if(f.getByte()==EI_SET_MTRL_CUR)return f.getBool();
  1155. disconnect();
  1156. }
  1157. return false;
  1158. }
  1159. Bool EditorInterface::getMaterial(C UID &elm_id, Material &mtrl)
  1160. {
  1161. if(elm_id.valid() && connected())
  1162. {
  1163. File &f=_conn.data.reset(); f.putByte(EI_GET_MTRL).putUID(elm_id).pos(0);
  1164. if(_conn.send(f))
  1165. if(_conn.receive(CLIENT_WAIT_TIME))
  1166. if(f.getByte()==EI_GET_MTRL)
  1167. {
  1168. if(f.getBool())return mtrl.load(f);
  1169. return false;
  1170. }
  1171. disconnect();
  1172. }
  1173. mtrl.reset(); return !elm_id.valid();
  1174. }
  1175. Bool EditorInterface::setMaterial(C UID &elm_id, C Material &mtrl, Bool reload_textures, Bool adjust_params)
  1176. {
  1177. if(elm_id.valid() && connected())
  1178. {
  1179. File &f=_conn.data.reset(); f.putByte(EI_SET_MTRL).putUID(elm_id).putByte(reload_textures*1 | adjust_params*2); mtrl.save(f); f.pos(0);
  1180. if(_conn.send(f))
  1181. if(_conn.receive(reload_textures ? CLIENT_WAIT_TIME_LONG : CLIENT_WAIT_TIME)) // reloading textures may take a long time
  1182. if(f.getByte()==EI_SET_MTRL)return f.getBool();
  1183. disconnect();
  1184. }
  1185. return false;
  1186. }
  1187. Bool EditorInterface::reloadMaterialTextures(C UID &elm_id, bool base, bool reflection, bool detail, bool macro, bool light)
  1188. {
  1189. if(elm_id.valid() && connected())
  1190. {
  1191. File &f=_conn.data.reset(); f.putByte(EI_RLD_MTRL_TEX).putUID(elm_id).putByte(base*1 | reflection*2 | detail*4 | macro*8 | light*16); f.pos(0);
  1192. if(_conn.send(f))
  1193. if(_conn.receive(CLIENT_WAIT_TIME_LONG)) // reloading textures may take a long time
  1194. if(f.getByte()==EI_RLD_MTRL_TEX)return f.getBool();
  1195. disconnect();
  1196. }
  1197. return false;
  1198. }
  1199. Bool EditorInterface::mulMaterialTextureByColor(C UID &elm_id)
  1200. {
  1201. if(elm_id.valid() && connected())
  1202. {
  1203. File &f=_conn.data.reset(); f.putByte(EI_MUL_MTRL_TEX_COL).putUID(elm_id); f.pos(0);
  1204. if(_conn.send(f))
  1205. if(_conn.receive(CLIENT_WAIT_TIME_LONG)) // reloading textures may take a long time
  1206. if(f.getByte()==EI_MUL_MTRL_TEX_COL)return f.getBool();
  1207. disconnect();
  1208. }
  1209. return false;
  1210. }
  1211. /******************************************************************************/
  1212. // ANIMATION
  1213. /******************************************************************************/
  1214. UID EditorInterface::curAnimation()
  1215. {
  1216. if(connected())
  1217. {
  1218. File &f=_conn.data.reset(); f.putByte(EI_GET_ANIM_CUR).pos(0);
  1219. if(_conn.send(f))
  1220. if(_conn.receive(CLIENT_WAIT_TIME))
  1221. if(f.getByte()==EI_GET_ANIM_CUR)return f.getUID();
  1222. disconnect();
  1223. }
  1224. return UIDZero;
  1225. }
  1226. Bool EditorInterface::curAnimation(C UID &elm_id)
  1227. {
  1228. if(connected())
  1229. {
  1230. File &f=_conn.data.reset(); f.putByte(EI_SET_ANIM_CUR).putUID(elm_id).pos(0);
  1231. if(_conn.send(f))
  1232. if(_conn.receive(CLIENT_WAIT_TIME))
  1233. if(f.getByte()==EI_SET_ANIM_CUR)return f.getBool();
  1234. disconnect();
  1235. }
  1236. return false;
  1237. }
  1238. Bool EditorInterface::getAnimation(C UID &elm_id, Animation &anim)
  1239. {
  1240. if(elm_id.valid() && connected())
  1241. {
  1242. File &f=_conn.data.reset(); f.putByte(EI_GET_ANIM).putUID(elm_id).pos(0);
  1243. if(_conn.send(f))
  1244. if(_conn.receive(CLIENT_WAIT_TIME))
  1245. if(f.getByte()==EI_GET_ANIM)
  1246. {
  1247. if(f.getBool())return anim.load(f);
  1248. return false;
  1249. }
  1250. disconnect();
  1251. }
  1252. anim.del(); return !elm_id.valid();
  1253. }
  1254. Bool EditorInterface::setAnimation(C UID &elm_id, C Animation &anim)
  1255. {
  1256. if(elm_id.valid() && connected())
  1257. {
  1258. File &f=_conn.data.reset(); f.putByte(EI_SET_ANIM).putUID(elm_id); anim.save(f); f.pos(0);
  1259. if(_conn.send(f))
  1260. if(_conn.receive(CLIENT_WAIT_TIME))
  1261. if(f.getByte()==EI_SET_ANIM)return f.getBool();
  1262. disconnect();
  1263. }
  1264. return false;
  1265. }
  1266. /******************************************************************************/
  1267. // OBJECT
  1268. /******************************************************************************/
  1269. UID EditorInterface::curObject()
  1270. {
  1271. if(connected())
  1272. {
  1273. File &f=_conn.data.reset(); f.putByte(EI_GET_OBJ_CUR).pos(0);
  1274. if(_conn.send(f))
  1275. if(_conn.receive(CLIENT_WAIT_TIME))
  1276. if(f.getByte()==EI_GET_OBJ_CUR)return f.getUID();
  1277. disconnect();
  1278. }
  1279. return UIDZero;
  1280. }
  1281. Bool EditorInterface::curObject(C UID &elm_id)
  1282. {
  1283. if(connected())
  1284. {
  1285. File &f=_conn.data.reset(); f.putByte(EI_SET_OBJ_CUR).putUID(elm_id).pos(0);
  1286. if(_conn.send(f))
  1287. if(_conn.receive(CLIENT_WAIT_TIME))
  1288. if(f.getByte()==EI_SET_OBJ_CUR)return f.getBool();
  1289. disconnect();
  1290. }
  1291. return false;
  1292. }
  1293. Bool EditorInterface::getObject(C UID &elm_id, ObjData &obj, Bool include_removed_params)
  1294. {
  1295. if(elm_id.valid() && connected())
  1296. {
  1297. File &f=_conn.data.reset(); f.putByte(EI_GET_OBJ).putUID(elm_id).putBool(include_removed_params).pos(0);
  1298. if(_conn.send(f))
  1299. if(_conn.receive(CLIENT_WAIT_TIME))
  1300. if(f.getByte()==EI_GET_OBJ)
  1301. {
  1302. if(f.getBool())return obj.load(f);
  1303. return false;
  1304. }
  1305. disconnect();
  1306. }
  1307. obj.reset(); return !elm_id.valid();
  1308. }
  1309. Bool EditorInterface::modifyObject(C UID &elm_id, C MemPtr<ObjChange> &changes)
  1310. {
  1311. if(elm_id.valid() && connected())
  1312. {
  1313. File &f=_conn.data.reset(); f.putByte(EI_MODIFY_OBJ).putUID(elm_id); changes.save(f); f.pos(0);
  1314. if(_conn.send(f))
  1315. if(_conn.receive(CLIENT_WAIT_TIME))
  1316. if(f.getByte()==EI_MODIFY_OBJ)return f.getBool();
  1317. disconnect();
  1318. }
  1319. return false;
  1320. }
  1321. /******************************************************************************/
  1322. // APPLICATION
  1323. /******************************************************************************/
  1324. Bool EditorInterface::activeApp(C UID &elm_id)
  1325. {
  1326. if(connected())
  1327. {
  1328. File &f=_conn.data.reset(); f.putByte(EI_SET_ACTIVE_APP).putUID(elm_id).pos(0);
  1329. if(_conn.send(f))
  1330. if(_conn.receive(CLIENT_WAIT_TIME))
  1331. if(f.getByte()==EI_SET_ACTIVE_APP)return f.getBool();
  1332. disconnect();
  1333. }
  1334. return false;
  1335. }
  1336. Bool EditorInterface::exportApp(EXPORT_MODE mode, Bool data)
  1337. {
  1338. if(connected())
  1339. {
  1340. File &f=_conn.data.reset(); f.putByte(EI_EXPORT_APP).putByte(mode).putBool(data).pos(0);
  1341. if(_conn.send(f))
  1342. if(_conn.receive(data ? CLIENT_WAIT_TIME_PUBLISH : CLIENT_WAIT_TIME))
  1343. if(f.getByte()==EI_EXPORT_APP)return f.getBool();
  1344. disconnect();
  1345. }
  1346. return false;
  1347. }
  1348. /******************************************************************************/
  1349. // BUILD SETTINGS
  1350. /******************************************************************************/
  1351. Bool EditorInterface::buildDebug(Bool debug)
  1352. {
  1353. if(connected())
  1354. {
  1355. File &f=_conn.data.reset(); f.putByte(EI_BUILD_DEBUG).putBool(debug).pos(0);
  1356. if(_conn.send(f))
  1357. if(_conn.receive(CLIENT_WAIT_TIME))
  1358. if(f.getByte()==EI_BUILD_DEBUG)return f.getBool();
  1359. disconnect();
  1360. }
  1361. return false;
  1362. }
  1363. Bool EditorInterface::build32Bit(Bool bit32)
  1364. {
  1365. if(connected())
  1366. {
  1367. File &f=_conn.data.reset(); f.putByte(EI_BUILD_32BIT).putBool(bit32).pos(0);
  1368. if(_conn.send(f))
  1369. if(_conn.receive(CLIENT_WAIT_TIME))
  1370. if(f.getByte()==EI_BUILD_32BIT)return f.getBool();
  1371. disconnect();
  1372. }
  1373. return false;
  1374. }
  1375. Bool EditorInterface::buildDX9(Bool dx9)
  1376. {
  1377. if(connected())
  1378. {
  1379. File &f=_conn.data.reset(); f.putByte(EI_BUILD_DX9).putBool(dx9).pos(0);
  1380. if(_conn.send(f))
  1381. if(_conn.receive(CLIENT_WAIT_TIME))
  1382. if(f.getByte()==EI_BUILD_DX9)return f.getBool();
  1383. disconnect();
  1384. }
  1385. return false;
  1386. }
  1387. Bool EditorInterface::buildExe(EXE_TYPE type)
  1388. {
  1389. if(connected())
  1390. {
  1391. File &f=_conn.data.reset(); f.putByte(EI_BUILD_EXE).putByte(type).pos(0);
  1392. if(_conn.send(f))
  1393. if(_conn.receive(CLIENT_WAIT_TIME))
  1394. if(f.getByte()==EI_BUILD_EXE)return f.getBool();
  1395. disconnect();
  1396. }
  1397. return false;
  1398. }
  1399. Bool EditorInterface::buildPaths(Bool relative)
  1400. {
  1401. if(connected())
  1402. {
  1403. File &f=_conn.data.reset(); f.putByte(EI_BUILD_PATHS).putBool(relative).pos(0);
  1404. if(_conn.send(f))
  1405. if(_conn.receive(CLIENT_WAIT_TIME))
  1406. if(f.getByte()==EI_BUILD_PATHS)return f.getBool();
  1407. disconnect();
  1408. }
  1409. return false;
  1410. }
  1411. /******************************************************************************/
  1412. // SERVER
  1413. /******************************************************************************/
  1414. Bool EditorServer::Client::update()
  1415. {
  1416. if(!super::update())return false;
  1417. if(!connection_version_ok) // if not verified
  1418. if(connection.receive(0)) // check for it
  1419. {
  1420. if(!connection.address().thisDevice())return false; // allow only from this device
  1421. File &f=connection.data;
  1422. Byte cmd =f.getByte();
  1423. if( cmd==EI_VERSION_CHECK)
  1424. if(Equal(f.getStr(), EI_STR, true))
  1425. {
  1426. connection_version_ok=(f.decUIntV()==EI_VER);
  1427. f.reset().putByte(EI_VERSION_CHECK).putStr(EI_STR).cmpUIntV(EI_VER).pos(0);
  1428. connection.tcpNoDelay(true);
  1429. connection.send(f);
  1430. }
  1431. if(!connection_version_ok)return false; // if received something that wasn't correct version match then remove
  1432. }
  1433. return true;
  1434. }
  1435. /******************************************************************************/
  1436. static Int CompareElm(C Elm &elm, C UID &id) {return Compare(elm.id, id);}
  1437. Elm* FindElm(MemPtr<Elm> elms, C UID &elm_id ) {return elms.binaryFind(elm_id, CompareElm);}
  1438. Elm* FindElm(MemPtr<Elm> elms, C UID &elm_id, ELM_TYPE type) {if(Elm *elm=FindElm(elms, elm_id))if(elm->type==type)return elm; return null;}
  1439. static Elm* FindChild(MemPtr<Elm> elms, C UID &parent_id, ELM_TYPE type)
  1440. {
  1441. REPA(elms)
  1442. {
  1443. Elm &child=elms[i]; if(child.parent_id==parent_id && child.type==type)return &child;
  1444. }
  1445. return null;
  1446. }
  1447. Elm* FindElm(MemPtr<Elm> elms, C Str &full_name, ELM_TYPE type)
  1448. {
  1449. REPA(elms)
  1450. {
  1451. Elm &elm=elms[i]; if(EqualPath(elm.full_name, full_name))
  1452. {
  1453. if(elm.type==type)return &elm;
  1454. switch(elm.type)
  1455. {
  1456. case ELM_MESH: if( type==ELM_SKEL || type==ELM_PHYS)if(Elm *child=FindChild(elms, elm.id, type))return child; break; // allow SKEL and PHYS to be children of MESH
  1457. case ELM_OBJ : if(type==ELM_MESH || type==ELM_SKEL || type==ELM_PHYS)REPA(elms) // allow MESH SKEL and PHYS to be children of OBJ
  1458. {
  1459. Elm &child=elms[i]; if(child.parent_id==elm.id)
  1460. {
  1461. if(child.type==type )return &child;
  1462. if(child.type==ELM_MESH)if(type==ELM_SKEL || type==ELM_PHYS)if(Elm *sub=FindChild(elms, child.id, type))return sub;
  1463. }
  1464. }break;
  1465. }
  1466. }
  1467. }
  1468. return null;
  1469. }
  1470. Bool ContainsElm(MemPtr<Elm> elms, C UID &parent_id, C UID &child_id)
  1471. {
  1472. if(parent_id.valid()) // if parent valid
  1473. {
  1474. Memt<UID> ids;
  1475. for(C UID *id=&child_id; id->valid() && ids.binaryInclude(*id, Compare); ) // if valid and not checked yet
  1476. {
  1477. if(*id==parent_id)return true;
  1478. if(Elm *elm=FindElm(elms, *id))id=&elm->parent_id;else break;
  1479. }
  1480. }
  1481. return false;
  1482. }
  1483. /******************************************************************************/
  1484. }}
  1485. /******************************************************************************/