Elm.cpp 177 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. /******************************************************************************/
  4. cchar8 *ElmTypeName[]= // !! these names are saved in Project TextData, do not change !!
  5. {
  6. "None",
  7. "Folder",
  8. "Enum",
  9. "Image",
  10. "Image Atlas",
  11. "Font",
  12. "Text Style",
  13. "Panel",
  14. "Gui",
  15. "Shader",
  16. "Material",
  17. "Water Material",
  18. "Physics Material",
  19. "Object Class",
  20. "Object",
  21. "Mesh",
  22. "Skeleton",
  23. "Physical Body",
  24. "Animation",
  25. "Panel Image",
  26. "Icon",
  27. "Environment",
  28. "World",
  29. "Sound",
  30. "Video",
  31. "File",
  32. "Code",
  33. "Library",
  34. "Application",
  35. "Icon Settings",
  36. "Mini Map",
  37. "Gui Skin",
  38. "Any",
  39. };
  40. cchar8 *ElmTypeClass[]=
  41. {
  42. "",
  43. "", // Folder
  44. "Enum, Enum*, Enums",
  45. "Image, ImagePtr, Images",
  46. "ImageAtlas, ImageAtlasPtr, ImageAtlases",
  47. "Font, Font*, Fonts",
  48. "TextStyle, TextStylePtr, TextStyles",
  49. "Panel, PanelPtr, Panels",
  50. "GuiObjs",
  51. "Shader, Shader*, Shaders",
  52. "Material, MaterialPtr, Materials",
  53. "WaterMtrl, WaterMtrlPtr, WaterMtrls",
  54. "PhysMtrl, PhysMtrl*, PhysMtrls",
  55. "Object, ObjectPtr, Objects",
  56. "Object, ObjectPtr, Objects",
  57. "Mesh, MeshPtr, Meshes",
  58. "Skeleton, Skeleton*, Skeletons",
  59. "PhysBody, PhysBodyPtr, PhysBodies",
  60. "Animation, Animation*, Animations",
  61. "PanelImage, PanelImagePtr, PanelImages",
  62. "Image, ImagePtr, Images",
  63. "Environment, EnvironmentPtr, Environments",
  64. "Game.WorldManager",
  65. "Sound",
  66. "Video",
  67. "File",
  68. "", // Code
  69. "", // Library
  70. "", // Application
  71. "", // Icon Settings
  72. "Game.MiniMap",
  73. "GuiSkin, GuiSkinPtr, GuiSkins",
  74. };
  75. cchar8 *ElmTypeDesc[]=
  76. {
  77. null, //"None"
  78. "Folder is mainly used for better organization of project elements by storing multiple elements inside it.\nFolder doesn't have any special properties.",
  79. "Enum allows to create C++ style enums using a visual editor.\nEach enum that is created this way will be automatically available in the C++ codes.\nAdditionally it will be stored as a game file resource in project data.\nSuch enums can be used for Object parameter types and values.",
  80. "Image can be used for displaying it on the screen through codes, as Image of a Gui Object, as a Material texture or for other custom purpose.\nIt can be a 2D / 3D / Cube / Software texture.",
  81. "Image Atlas is a set of multiple Images stored in as few textures as possible.\nThis is achieved by combining multiple Images into the same texture.\nImage Atlas is perfectly suited for storing 2D sprite animations.",
  82. null, //"Font",
  83. "Text Style is a set of properties related to drawing text.\nSuch as font, color, alignment, shadow, etc.",
  84. "Panel is a set of properties related to drawing Gui Frames (like window borders).\nSuch as background Image, border, corner and top Images, shadow, etc.",
  85. "Gui is a set of multiple Gui Objects such as Windows, Buttons, etc.",
  86. null, //"Shader",
  87. "Material is a set of properties used for rendering 3D meshes.\nSuch as Color, Normal, Specular textures, opacity and various other parameters.",
  88. "Water Material is a set of properties used for rendering 3D water surfaces.\nSuch as Color, Normal Textures, opacity and various other parameters.",
  89. "Physics Material is a set of properties for Physical Actors.\nSuch as Friction, Bounciness, etc.",
  90. "Object Class is a type of Object.\nEach Object can have only one Class.\nHere are few examples of Object Classes: Characters, Items, Vehicles, ..\nEach Object Class can have a set of base parameters that all Objects of this Class will automatically inherit.",
  91. "Object is a set of multiple properties, such as Mesh, Physical Body, Object Parameters, Object Class, etc.",
  92. null, //"Mesh",
  93. null, //"Skeleton",
  94. null, //"Physical Body",
  95. "Animation is a set of KeyFrames which are used for animating an Object.",
  96. "Panel Image is a specially created Image which supports stretching while preserving scale on borders, it is used for creating Panels (Gui Frames).",
  97. "Icon is a 2D Image which is made out of a 3D Object.",
  98. "Environment is a set of properties describing a World Environment, such as Sun, Clouds, Ambient Light, Fog, etc.\nEnvironment elements can be drag and dropped onto opened Worlds, to set them as default environment for edited world.",
  99. "World is a set of multiple World Areas in which can be stored Terrain Heightmaps, Objects, etc.",
  100. null, //"Sound",
  101. null, //"Video",
  102. "Custom binary file, allows you to include custom type of files.\nThey will be imported to the project directly in the same format as the source file.",
  103. "Source Code file which can contain functions, variables, classes, etc.",
  104. "Library is meant to work as a Folder for Source Code files which are used by all Applications in the Project.\nPlease store inside it only Source Code files and Folders.\nLibraries are useful for example in networked applications, where there is Client Application, Server Application and they both use some shared set of Codes.\nIn that case shared Codes should be stored separately outside of the Applications, inside Library element.\nThis will make all of the Code files from Library element to be accessible by all Applications.",
  105. "Application is a set of Source Code files which upon compilation create an executable, such as EXE DLL APP APK.\nIn general you should not store other elements than Folders and Codes in an Application.\nIncluding other elements in an Application will make them automatically embedded inside the executable file, making it bigger.\nBy default project resources are stored in separate \"Project.pak\" file.\nHowever for certain applications such as Installers it may be desirable to distribute only the executable file without any additional files.\nIn such case you can embed some of the resources such as Images used by the installer in its executable file, allowing it to access the resources without additional pak files.",
  106. "Icon Settings contains information required for creating 2D Icon elements from 3D Objects, such as icon resolution, camera placement, lighting, etc.\nOne Icon Settings element can be used for multiple Icons.",
  107. "Mini Map is a set of multiple Images of a World from the bird's eye view.",
  108. "Gui Skin is a set of images used to define a Graphical User Interface",
  109. };
  110. ElmTypeNameNoSpace ElmTypeNameNoSpaceDummy; // !! this needs to exist so that constructor is called !!
  111. bool ElmCompressable(ELM_TYPE type) {return type==ELM_MESH || type==ELM_SKEL || type==ELM_PHYS || type==ELM_ANIM || type==ELM_FILE || type==ELM_FONT || type==ELM_PANEL_IMAGE || type==ELM_SOUND || type==ELM_GUI || type==ELM_IMAGE_ATLAS;} // if element file should be compressed before sending to server (don't compress ELM_IMAGE because it's already stored as JPG/PNG/WEBP), for 'ElmSendBoth' then only game version will be compressed, and edit will not (so it can be synchronized per-member on the server) !! don't change this for existing elements because this defines how element files are stored on the server (compressed or not) !!
  112. bool ElmHasFile (ELM_TYPE type) {return type==ELM_MESH || type==ELM_MTRL || type==ELM_SKEL || type==ELM_PHYS || type==ELM_ANIM || type==ELM_IMAGE || type==ELM_ICON || type==ELM_OBJ || type==ELM_ENUM || type==ELM_FILE || type==ELM_FONT || type==ELM_PANEL_IMAGE || type==ELM_GUI || type==ELM_SOUND || type==ELM_VIDEO || type==ELM_OBJ_CLASS || type==ELM_TEXT_STYLE || type==ELM_PANEL || type==ELM_GUI_SKIN || type==ELM_WATER_MTRL || type==ELM_PHYS_MTRL || type==ELM_ENV || type==ELM_ICON_SETTS || type==ELM_IMAGE_ATLAS/* || type==ELM_CODE*/;} // if element has a file, because ELM_CODE is synchronized manually, then it's not included here
  113. bool ElmFileInShort (ELM_TYPE type) {return type==ELM_ENUM || type==ELM_FONT || type==ELM_PANEL_IMAGE || type==ELM_OBJ || type==ELM_MTRL || type==ELM_TEXT_STYLE || type==ELM_PANEL || type==ELM_GUI_SKIN || type==ELM_OBJ_CLASS || type==ELM_WATER_MTRL || type==ELM_PHYS_MTRL || type==ELM_ENV || type==ELM_ICON_SETTS/* || type==ELM_CODE*/;} // if include file data in CS_SET_ELM_SHORT, because ELM_CODE is synchronized manually, then it's not included here
  114. bool ElmEdit (ELM_TYPE type) {return type==ELM_MESH || type==ELM_MTRL || type==ELM_SKEL || type==ELM_OBJ || type==ELM_ENUM || type==ELM_FONT || type==ELM_PANEL_IMAGE || type==ELM_IMAGE || type==ELM_OBJ_CLASS || type==ELM_TEXT_STYLE || type==ELM_PANEL || type==ELM_GUI_SKIN || type==ELM_WATER_MTRL || type==ELM_PHYS_MTRL || type==ELM_ENV || type==ELM_ICON_SETTS;} // if element file is stored in the "edit" folder
  115. bool ElmGame (ELM_TYPE type) {return type==ELM_ENUM || type==ELM_IMAGE || type==ELM_IMAGE_ATLAS || type==ELM_FONT || type==ELM_TEXT_STYLE || type==ELM_PANEL || type==ELM_GUI || type==ELM_MTRL || type==ELM_WATER_MTRL || type==ELM_PHYS_MTRL || type==ELM_OBJ_CLASS || type==ELM_OBJ || type==ELM_MESH || type==ELM_SKEL || type==ELM_PHYS || type==ELM_ANIM || type==ELM_PANEL_IMAGE || type==ELM_ICON || type==ELM_ENV || type==ELM_SOUND || type==ELM_VIDEO || type==ELM_FILE || type==ELM_GUI_SKIN;} // if element file is stored in the "game" folder
  116. bool ElmSendBoth (ELM_TYPE type) {return type==ELM_SKEL || type==ELM_FONT || type==ELM_PANEL_IMAGE;} // if both Edit and Game file data should be sent in client<->server synchronization
  117. bool ElmInFolder (ELM_TYPE type) {return type==ELM_WORLD || type==ELM_MINI_MAP;} // if element data is stored inside a folder
  118. bool ElmManualSync (ELM_TYPE type) {return type==ELM_CODE || type==ELM_APP;}
  119. bool ElmPublish (ELM_TYPE type) {return type!=ELM_NONE && type!=ELM_FOLDER && type!=ELM_LIB && type!=ELM_APP && type!=ELM_CODE && type!=ELM_ICON_SETTS;} // if element should be included in publishing
  120. bool ElmPublishNoCompress(ELM_TYPE type) {return type==ELM_SOUND || type==ELM_VIDEO;} // if element should have disabled compression when publishing data
  121. bool ElmCanAccessID (ELM_TYPE type) {return type!=ELM_NONE;} // allow ELM_CODE too if user wants to set/get code data, and ELM_APP if it will be used for activating app using Editor Interface
  122. bool ElmImageLike (ELM_TYPE type ) {return type==ELM_IMAGE || type==ELM_ICON;}
  123. bool ElmCompatible(ELM_TYPE src, ELM_TYPE dest) {return src==dest || (ElmImageLike(src) && ElmImageLike(dest)) || (src==ELM_ANY || dest==ELM_ANY);}
  124. bool ElmMovable (ELM_TYPE type) {return type!=ELM_MESH && type!=ELM_SKEL && type!=ELM_PHYS;}
  125. bool ElmVisible (ELM_TYPE type) {return type!=ELM_MESH && type!=ELM_SKEL && type!=ELM_PHYS;}
  126. bool ElmCanHaveChildren(ELM_TYPE type) {return type!=ELM_MESH && type!=ELM_SKEL && type!=ELM_PHYS;}
  127. bool EqualID(C UID &id, C UID &src_id) {return id==src_id;}
  128. bool NewerID(C UID &id, C UID &src_id) {return Compare(id, src_id)>0;} // if 'id' is newer than 'src_id'. Since no timestamp is provided for this function, it will choose the ID which is bigger, so that 'UIDZero' is always replaced
  129. bool SyncID( UID &id, C UID &src_id) {if(NewerID(src_id, id)){id=src_id; return true;} return false;}
  130. bool UndoID( UID &id, C UID &src_id) {if(NewerID(src_id, id)){id=src_id; return true;} return false;}
  131. /******************************************************************************/
  132. /******************************************************************************/
  133. NameDesc ElmImage::ImageTypes[]= // !! These names are saved !!
  134. {
  135. {u"Compressed" , u"Image will be stored as a compressed texture\nLower quality, smaller size, 4/8-bit per pixel"},
  136. {u"Compressed+", u"Image will be stored as a compressed texture\nGood quality, small size, 8-bit per pixel"},
  137. {u"Full" , u"Image will be stored in full size\nBest quality, biggest size, 32-bit per pixel"},
  138. {u"Alpha" , u"Image will be stored as Alpha channel only\n8-bit per pixel"},
  139. };
  140. int ElmImage::ImageTypesElms=Elms(ImageTypes);
  141. ::ElmImage::ImageMode ElmImage::ImageModes[]= // !! These names are saved !!
  142. {
  143. {IMAGE_SOFT, "Soft"},
  144. {IMAGE_2D , "2D" },
  145. {IMAGE_3D , "3D" },
  146. {IMAGE_CUBE, "Cube"},
  147. };
  148. const uint ElmIcon::InheritVariation=~0;
  149. ::ElmApp::StorageMode ElmApp::StorageModes[]= // !! These names are saved !!
  150. {
  151. {Edit::STORAGE_INTERNAL, "Internal"},
  152. {Edit::STORAGE_EXTERNAL, "External"},
  153. {Edit::STORAGE_AUTO , "Auto" },
  154. };
  155. /******************************************************************************/
  156. ElmTypeNameNoSpace::ElmTypeNameNoSpace() {REPAO(names)=Replace(ElmTypeName[i], ' ', '\0');}
  157. bool ElmData::equal(C ElmData &src)C {return src_file_time==src.src_file_time;}
  158. bool ElmData::newer(C ElmData &src)C {return src_file_time> src.src_file_time;}
  159. bool ElmData::mayContain(C UID &id)C {return true;}
  160. bool ElmData::containsTex(C UID &id, bool test_merged)C {return false;}
  161. void ElmData::listTexs(MemPtr<UID> texs)C {}
  162. void ElmData::newVer() {ver.randomize();}
  163. void ElmData::newData() {newVer(); src_file_time++;}
  164. void ElmData::setSrcFile(C Str &src_file, C TimeStamp &time) {T.src_file=src_file; T.src_file_time=time;}
  165. uint ElmData::undoSrcFile(C ElmData &src) {return Undo(src_file_time, src.src_file_time, src_file, src.src_file)*CHANGE_NORMAL;}
  166. uint ElmData::undo(C ElmData &src)
  167. {
  168. uint changed=0;
  169. //changed|=undoSrcFile(src); // this should not be undone here, because this method is called inside the element editors, however none of these editors provide GUI for the 'src_file', instead the 'src_file' is changed using a separate 'ReloadElm' GUI. So if Element is opened in its Editor, some change is made, then it's reloaded from different source file, and in Editor some change is made, and undos presed to the start, then original source file would be restored, which is not what we want
  170. return changed;
  171. }
  172. uint ElmData::sync(C ElmData &src)
  173. {
  174. return Sync(src_file_time, src.src_file_time, src_file, src.src_file)*CHANGE_NORMAL;
  175. }
  176. void ElmData::clearLinked() {}
  177. bool ElmData::save(File &f)C
  178. {
  179. f.cmpUIntV(2);
  180. f<<ver<<src_file<<src_file_time;
  181. return f.ok();
  182. }
  183. bool ElmData::load(File &f)
  184. {
  185. switch(f.decUIntV())
  186. {
  187. case 2:
  188. {
  189. f>>ver>>src_file>>src_file_time;
  190. if(f.ok())return true;
  191. }break;
  192. case 1:
  193. {
  194. f>>ver; GetStr2(f, src_file); f>>src_file_time;
  195. if(f.ok())return true;
  196. }break;
  197. case 0:
  198. {
  199. f>>ver;
  200. GetStr(f, src_file);
  201. src_file_time=src_file.is();
  202. if(f.ok())return true;
  203. }break;
  204. }
  205. return false;
  206. }
  207. void ElmData::save(MemPtr<TextNode> nodes)C
  208. {
  209. nodes.New().set("Version" , ver.ver);
  210. if(src_file .is())nodes.New().set("SrcFile" , src_file);
  211. if(src_file_time.is())nodes.New().set("SrcFileTime", src_file_time.text());
  212. }
  213. void ElmData::load(C MemPtr<TextNode> &nodes)
  214. {
  215. REPA(nodes)
  216. {
  217. C TextNode &n=nodes[i];
  218. if(n.name=="Version" )n.getValue(ver.ver );else
  219. if(n.name=="SrcFile" )n.getValue(src_file);else
  220. if(n.name=="SrcFileTime")src_file_time=n.asText();
  221. }
  222. }
  223. ElmData::~ElmData() {}
  224. bool ElmObjClass::ovrAccess()C {return FlagTest( flag, OVR_ACCESS );}
  225. void ElmObjClass::ovrAccess(bool on ) {FlagSet(flag, OVR_ACCESS, on);}
  226. bool ElmObjClass::terrain()C {return FlagTest( flag, TERRAIN );}
  227. void ElmObjClass::terrain(bool on ) {FlagSet(flag, TERRAIN , on);}
  228. bool ElmObjClass::ovrPath()C {return FlagTest( flag, OVR_PATH );}
  229. void ElmObjClass::ovrPath(bool on ) {FlagSet(flag, OVR_PATH , on);}
  230. OBJ_PATH ElmObjClass::pathSelf()C {return OBJ_PATH((flag>>PATH_SHIFT)&PATH_MASK);}
  231. void ElmObjClass::pathSelf(OBJ_PATH path) {FlagDisable(flag, PATH_MASK<<PATH_SHIFT); flag|=((path&PATH_MASK)<<PATH_SHIFT);}
  232. void ElmObjClass::from(C EditObject &params)
  233. {
  234. flag=0;
  235. ovrAccess(FlagTest(params.flag, EditObject::OVR_ACCESS)); terrain (params.access==OBJ_ACCESS_TERRAIN);
  236. ovrPath (FlagTest(params.flag, EditObject::OVR_PATH )); pathSelf(params.path );
  237. }
  238. uint ElmObjClass::undo(C ElmObjClass &src) {return ::ElmData::undo(src);}
  239. uint ElmObjClass::sync(C ElmObjClass &src) {return ::ElmData::sync(src);}
  240. bool ElmObjClass::save(File &f)C
  241. {
  242. ::ElmData::save(f);
  243. f.cmpUIntV(0);
  244. f<<flag;
  245. return f.ok();
  246. }
  247. bool ElmObjClass::load(File &f)
  248. {
  249. if(::ElmData::load(f))switch(f.decUIntV())
  250. {
  251. case 0:
  252. {
  253. f>>flag;
  254. if(f.ok())return true;
  255. }break;
  256. }
  257. return false;
  258. }
  259. void ElmObjClass::save(MemPtr<TextNode> nodes)C
  260. {
  261. ::ElmData::save(nodes);
  262. if(ovrAccess())nodes.New().set("OverrideAccess");
  263. if(ovrPath ())nodes.New().set("OverridePath" );
  264. nodes.New().set("Terrain", terrain ());
  265. nodes.New().set("Path" , pathSelf());
  266. }
  267. void ElmObjClass::load(C MemPtr<TextNode> &nodes)
  268. {
  269. ::ElmData::load(nodes);
  270. REPA(nodes)
  271. {
  272. C TextNode &n=nodes[i];
  273. if(n.name=="OverrideAccess")ovrAccess( n.asBool1());else
  274. if(n.name=="OverridePath" )ovrPath ( n.asBool1());else
  275. if(n.name=="Terrain" )terrain ( n.asBool1());else
  276. if(n.name=="Path" )pathSelf ((OBJ_PATH)n.asUInt ());
  277. }
  278. }
  279. bool ElmObj::equal(C ElmObj &src)C {return ::ElmData::equal(src) && EqualID(mesh_id, src.mesh_id);}
  280. bool ElmObj::newer(C ElmObj &src)C {return ::ElmData::newer(src) || NewerID(mesh_id, src.mesh_id);}
  281. void ElmObj::clearLinked(){mesh_id.zero();}
  282. uint ElmObj::undo(C ElmObj &src)
  283. {
  284. uint changed =::ElmObjClass::undo(src);
  285. changed|=UndoID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  286. return changed; // don't adjust 'ver' here because it also relies on 'EditObject', because of that this is included in 'ElmFileInShort'
  287. }
  288. uint ElmObj::sync(C ElmObj &src)
  289. {
  290. uint changed =::ElmObjClass::sync(src);
  291. changed|=SyncID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  292. return changed; // don't adjust 'ver' here because it also relies on 'EditObject', because of that this is included in 'ElmFileInShort'
  293. }
  294. void ElmObj::from(C EditObject &params)
  295. {
  296. ::ElmObjClass::from(params);
  297. base_id=params.base.id();
  298. }
  299. bool ElmObj::save(File &f)C
  300. {
  301. ::ElmObjClass::save(f);
  302. f.cmpUIntV(0);
  303. f<<mesh_id<<base_id;
  304. return f.ok();
  305. }
  306. bool ElmObj::load(File &f)
  307. {
  308. if(::ElmObjClass::load(f))switch(f.decUIntV())
  309. {
  310. case 0:
  311. {
  312. f>>mesh_id>>base_id;
  313. if(f.ok())return true;
  314. }break;
  315. }
  316. return false;
  317. }
  318. void ElmObj::save(MemPtr<TextNode> nodes)C
  319. {
  320. ::ElmObjClass::save(nodes);
  321. if(mesh_id.valid())nodes.New().setFN("Mesh", mesh_id);
  322. if(base_id.valid())nodes.New().setFN("Base", base_id);
  323. }
  324. void ElmObj::load(C MemPtr<TextNode> &nodes)
  325. {
  326. ::ElmObjClass::load(nodes);
  327. REPA(nodes)
  328. {
  329. C TextNode &n=nodes[i];
  330. if(n.name=="Mesh")n.getValue(mesh_id);else
  331. if(n.name=="Base")n.getValue(base_id);
  332. }
  333. }
  334. bool ElmMesh::equal(C ElmMesh &src)C {return ::ElmData::equal(src) && file_time==src.file_time && body_time==src.body_time && draw_group_time==src.draw_group_time && transform_time==src.transform_time && EqualID(obj_id, src.obj_id) && EqualID(skel_id, src.skel_id) && EqualID(phys_id, src.phys_id);}
  335. bool ElmMesh::newer(C ElmMesh &src)C {return ::ElmData::newer(src) || file_time> src.file_time || body_time> src.body_time || draw_group_time> src.draw_group_time || transform_time> src.transform_time || NewerID(obj_id, src.obj_id) || NewerID(skel_id, src.skel_id) || NewerID(phys_id, src.phys_id);}
  336. bool ElmMesh::mayContain(C UID &id)C {return id==obj_id || id==skel_id || id==phys_id || id==body_id || id==draw_group_id || mtrl_ids.binaryHas(id, Compare);}
  337. void ElmMesh::clearLinked(){obj_id.zero(); skel_id.zero(); phys_id.zero();}
  338. flt ElmMesh::posScale()C {return 1/transform.scale;}
  339. flt ElmMesh::vtxDupPosEps()C {return VtxDupPosEps*posScale();}
  340. bool ElmMesh::canHaveCustomTransform()C {return !body_id.valid();}
  341. void ElmMesh::newData()
  342. {
  343. ::ElmData::newData();
  344. file_time++;
  345. body_time++;
  346. draw_group_time++;
  347. transform_time++;
  348. }
  349. void ElmMesh::fromMtrl(C Mesh &mesh)
  350. {
  351. mtrl_ids.clear();
  352. REPD(l, mesh.lods())
  353. {
  354. C MeshLod &lod=mesh.lod(l); REPA(lod)
  355. {
  356. C MeshPart &part=lod.parts[i];
  357. if(!(part.part_flag&MSHP_HIDDEN)) // skip hidden parts
  358. {
  359. REP(4)if(C MaterialPtr &mtrl=part.multiMaterial(i))
  360. {
  361. UID mtrl_id=mtrl.id();
  362. if( mtrl_id.valid())mtrl_ids.binaryInclude(mtrl_id, Compare);
  363. }
  364. REP(part.variations())if(i)if(C MaterialPtr &mtrl=part.variation(i))
  365. {
  366. UID mtrl_id=mtrl.id();
  367. if( mtrl_id.valid())mtrl_ids.binaryInclude(mtrl_id, Compare);
  368. }
  369. }
  370. }
  371. }
  372. }
  373. void ElmMesh::from(C Mesh &game_mesh) // game version of mesh must be passed here
  374. {
  375. fromMtrl(game_mesh);
  376. if(game_mesh.is())box=game_mesh.ext;else box.set(Vec(0), Vec(-1));
  377. }
  378. uint ElmMesh::undo(C ElmMesh &src)
  379. {
  380. uint changed=::ElmData::undo(src);
  381. changed|=UndoID( obj_id, src. obj_id)*CHANGE_NORMAL;
  382. changed|=UndoID(skel_id, src.skel_id)*CHANGE_AFFECT_FILE;
  383. changed|=UndoID(phys_id, src.phys_id)*CHANGE_NORMAL;
  384. changed|=Undo( body_time, src. body_time, body_id, src. body_id)*CHANGE_AFFECT_FILE;
  385. changed|=Undo(draw_group_time, src.draw_group_time, draw_group_id, src.draw_group_id)*CHANGE_AFFECT_FILE;
  386. //changed|=Undo( transform_time, src. transform_time, transform , src.transform )*CHANGE_AFFECT_FILE; transform is not undone here
  387. if(changed)newVer();
  388. return changed;
  389. }
  390. uint ElmMesh::sync(C ElmMesh &src)
  391. {
  392. uint changed=::ElmData::sync(src);
  393. changed|=SyncID( obj_id, src. obj_id)*CHANGE_NORMAL;
  394. changed|=SyncID(skel_id, src.skel_id)*CHANGE_AFFECT_FILE;
  395. changed|=SyncID(phys_id, src.phys_id)*CHANGE_NORMAL;
  396. changed|=Sync( body_time, src. body_time, body_id, src. body_id)*CHANGE_AFFECT_FILE;
  397. changed|=Sync(draw_group_time, src.draw_group_time, draw_group_id, src.draw_group_id)*CHANGE_AFFECT_FILE;
  398. changed|=Sync( transform_time, src. transform_time, transform , src.transform )*CHANGE_AFFECT_FILE;
  399. if(equal(src))ver=src.ver;else if(changed)newVer();
  400. return changed;
  401. }
  402. bool ElmMesh::syncFile(C ElmMesh &src)
  403. {
  404. bool changed=false;
  405. if(Sync(file_time, src.file_time)){changed|=true; mtrl_ids=src.mtrl_ids;}
  406. if(equal(src))ver=src.ver;else if(changed)newVer();
  407. return changed;
  408. }
  409. bool ElmMesh::save(File &f)C
  410. {
  411. ::ElmData::save(f);
  412. f.cmpUIntV(2);
  413. f<<transform<<obj_id<<skel_id<<body_id<<phys_id<<draw_group_id; f.cmpUIntV(mtrl_ids.elms()); FREPA(mtrl_ids)f<<mtrl_ids[i]; f<<box;
  414. f<<file_time<<body_time<<transform_time<<draw_group_time;
  415. return f.ok();
  416. }
  417. bool ElmMesh::load(File &f)
  418. {
  419. if(::ElmData::load(f))switch(f.decUIntV())
  420. {
  421. case 2:
  422. {
  423. f>>transform>>obj_id>>skel_id>>body_id>>phys_id>>draw_group_id; mtrl_ids.setNum(f.decUIntV()); FREPA(mtrl_ids)f>>mtrl_ids[i]; f>>box;
  424. f>>file_time>>body_time>>transform_time>>draw_group_time;
  425. if(f.ok())return true;
  426. }break;
  427. case 1:
  428. {
  429. obj_id.zero();
  430. f>>transform>>skel_id>>body_id>>phys_id>>draw_group_id; mtrl_ids.setNum(f.decUIntV()); FREPA(mtrl_ids)f>>mtrl_ids[i]; f>>box;
  431. f>>file_time>>body_time>>transform_time>>draw_group_time;
  432. if(f.ok())return true;
  433. }break;
  434. case 0:
  435. {
  436. obj_id.zero();
  437. f>>transform>>skel_id>>body_id>>phys_id; draw_group_id.zero(); mtrl_ids.setNum(f.decUIntV()); FREPA(mtrl_ids)f>>mtrl_ids[i]; f>>box;
  438. f>>file_time>>body_time>>transform_time; draw_group_time.zero();
  439. if(f.ok())return true;
  440. }break;
  441. }
  442. return false;
  443. }
  444. void ElmMesh::save(MemPtr<TextNode> nodes)C
  445. {
  446. ::ElmData::save(nodes);
  447. nodes.New().setRaw("Pose" , transform);
  448. nodes.New().setRaw("Box" , box );
  449. if( obj_id.valid())nodes.New().setFN ("Object" , obj_id );
  450. if( skel_id.valid())nodes.New().setFN ("Skeleton" , skel_id );
  451. if( phys_id.valid())nodes.New().setFN ("PhysBody" , phys_id );
  452. if( body_id.valid())nodes.New().setFN ("Body" , body_id );
  453. if(draw_group_id.valid())nodes.New().setFN ("DrawGroup" , draw_group_id);
  454. nodes.New().set ("FileTime" , file_time.text());
  455. nodes.New().set ("BodyTime" , body_time.text());
  456. nodes.New().set ("DrawGroupTime", draw_group_time.text());
  457. nodes.New().set ("PoseTime" , transform_time.text());
  458. if(mtrl_ids.elms())
  459. {
  460. TextNode &mtrls=nodes.New().setName("Materials");
  461. FREPA(mtrl_ids)mtrls.nodes.New().setValueFN(mtrl_ids[i]); // list in order
  462. }
  463. }
  464. void ElmMesh::load(C MemPtr<TextNode> &nodes)
  465. {
  466. ::ElmData::load(nodes);
  467. REPA(nodes)
  468. {
  469. C TextNode &n=nodes[i];
  470. if(n.name=="Pose" )n.getValueRaw(transform );else
  471. if(n.name=="Box" )n.getValueRaw(box );else
  472. if(n.name=="Object" )n.getValue ( obj_id );else
  473. if(n.name=="Skeleton" )n.getValue (skel_id );else
  474. if(n.name=="PhysBody" )n.getValue (phys_id );else
  475. if(n.name=="Body" )n.getValue (body_id );else
  476. if(n.name=="DrawGroup" )n.getValue (draw_group_id);else
  477. if(n.name=="FileTime" ) file_time=n.asText();else
  478. if(n.name=="BodyTime" ) body_time=n.asText();else
  479. if(n.name=="DrawGroupTime")draw_group_time=n.asText();else
  480. if(n.name=="PoseTime" ) transform_time=n.asText();else
  481. if(n.name=="Materials" )
  482. {
  483. FREPA(n.nodes) // get in order
  484. {
  485. UID id; if(n.nodes[i].getValue(id) && id.valid())mtrl_ids.binaryInclude(id, Compare);
  486. }
  487. }
  488. }
  489. }
  490. bool ElmMaterial::equal(C ElmMaterial &src)C {return ::ElmData::equal(src);}
  491. bool ElmMaterial::newer(C ElmMaterial &src)C {return ::ElmData::newer(src);}
  492. bool ElmMaterial::usesTexAlpha()C {return FlagTest(flag, USES_TEX_ALPHA );}
  493. void ElmMaterial::usesTexAlpha(bool on) {return FlagSet(flag, USES_TEX_ALPHA , on);}
  494. bool ElmMaterial::usesTexBump()C {return FlagTest(flag, USES_TEX_BUMP );}
  495. void ElmMaterial::usesTexBump(bool on) {return FlagSet(flag, USES_TEX_BUMP , on);}
  496. bool ElmMaterial::usesTexGlow()C {return FlagTest(flag, USES_TEX_GLOW );}
  497. void ElmMaterial::usesTexGlow(bool on) {return FlagSet(flag, USES_TEX_GLOW , on);}
  498. bool ElmMaterial::texQualityiOS()C {return FlagTest(flag, TEX_QUALITY_IOS);}
  499. void ElmMaterial::texQualityiOS(bool on) {return FlagSet(flag, TEX_QUALITY_IOS, on);}
  500. bool ElmMaterial::mayContain(C UID &id)C {return false;}
  501. bool ElmMaterial::containsTex(C UID &id, bool test_merged)C
  502. {
  503. if(id.valid())
  504. {
  505. if(base_0_tex==id || base_1_tex==id || detail_tex==id || macro_tex==id || reflection_tex==id || light_tex==id)return true;
  506. if(test_merged && MergedBaseTexturesID(base_0_tex, base_1_tex)==id)return true;
  507. }
  508. return false;
  509. }
  510. void ElmMaterial::listTexs(MemPtr<UID> texs)C
  511. {
  512. if( base_0_tex.valid())texs.binaryInclude( base_0_tex, Compare);
  513. if( base_1_tex.valid())texs.binaryInclude( base_1_tex, Compare);
  514. if( detail_tex.valid())texs.binaryInclude( detail_tex, Compare);
  515. if( macro_tex.valid())texs.binaryInclude( macro_tex, Compare);
  516. if(reflection_tex.valid())texs.binaryInclude(reflection_tex, Compare);
  517. if( light_tex.valid())texs.binaryInclude( light_tex, Compare);
  518. }
  519. void ElmMaterial::from(C EditMaterial &src)
  520. {
  521. base_0_tex=src. base_0_tex;
  522. base_1_tex=src. base_1_tex;
  523. detail_tex=src. detail_tex;
  524. macro_tex=src. macro_tex;
  525. reflection_tex=src.reflection_tex;
  526. light_tex=src. light_tex;
  527. downsize_tex_mobile=src.downsize_tex_mobile;
  528. usesTexAlpha (src.usesTexAlpha());
  529. usesTexBump (src.usesTexBump ());
  530. usesTexGlow (src.usesTexGlow ());
  531. texQualityiOS(src.high_quality_ios);
  532. }
  533. uint ElmMaterial::undo(C ElmMaterial &src) // don't undo 'downsize_tex_mobile', 'flag' because they should be set only in 'from'
  534. {
  535. uint changed=::ElmData::undo(src);
  536. return changed; // don't adjust 'ver' here because it also relies on 'EditMaterial', because of that this is included in 'ElmFileInShort'
  537. }
  538. uint ElmMaterial::sync(C ElmMaterial &src) // don't sync 'downsize_tex_mobile', 'flag' because they should be set only in 'from'
  539. {
  540. uint changed=::ElmData::sync(src);
  541. return changed; // don't adjust 'ver' here because it also relies on 'EditMaterial', because of that this is included in 'ElmFileInShort'
  542. }
  543. bool ElmMaterial::save(File &f)C
  544. {
  545. ::ElmData::save(f);
  546. f.cmpUIntV(4);
  547. f<<base_0_tex<<base_1_tex<<detail_tex<<macro_tex<<reflection_tex<<light_tex<<downsize_tex_mobile<<flag;
  548. return f.ok();
  549. }
  550. bool ElmMaterial::load(File &f)
  551. {
  552. if(::ElmData::load(f))switch(f.decUIntV())
  553. {
  554. case 4:
  555. {
  556. f>>base_0_tex>>base_1_tex>>detail_tex>>macro_tex>>reflection_tex>>light_tex>>downsize_tex_mobile>>flag;
  557. if(f.ok())return true;
  558. }break;
  559. case 3:
  560. {
  561. byte max_tex_size; f>>max_tex_size>>base_0_tex>>base_1_tex>>detail_tex>>macro_tex>>reflection_tex>>light_tex; downsize_tex_mobile=(max_tex_size>=1 && max_tex_size<=10); flag=0;
  562. if(f.ok())return true;
  563. }break;
  564. case 2:
  565. {
  566. byte max_tex_size; UID mesh_id; f>>max_tex_size>>base_0_tex>>base_1_tex>>detail_tex>>macro_tex>>reflection_tex>>light_tex>>mesh_id; downsize_tex_mobile=(max_tex_size>=1 && max_tex_size<=10); flag=0;
  567. if(f.ok())return true;
  568. }break;
  569. case 1:
  570. {
  571. UID mesh_id; f>>base_0_tex>>base_1_tex>>detail_tex>>macro_tex>>reflection_tex>>light_tex>>mesh_id; downsize_tex_mobile=0; flag=0;
  572. if(f.ok())return true;
  573. }break;
  574. case 0:
  575. {
  576. UID mesh_id; f>>base_0_tex>>base_1_tex>>detail_tex>>macro_tex>>reflection_tex>>mesh_id; downsize_tex_mobile=0; flag=0; light_tex.zero();
  577. if(f.ok())return true;
  578. }break;
  579. }
  580. return false;
  581. }
  582. void ElmMaterial::save(MemPtr<TextNode> nodes)C
  583. {
  584. ::ElmData::save(nodes);
  585. if( base_0_tex.valid())nodes.New().setFN("Base0" , base_0_tex);
  586. if( base_1_tex.valid())nodes.New().setFN("Base1" , base_1_tex);
  587. if( detail_tex.valid())nodes.New().setFN("Detail" , detail_tex);
  588. if( macro_tex.valid())nodes.New().setFN("Macro" , macro_tex);
  589. if(reflection_tex.valid())nodes.New().setFN("Reflection" , reflection_tex);
  590. if( light_tex.valid())nodes.New().setFN("Light" , light_tex);
  591. if( downsize_tex_mobile )nodes.New().set ("MobileTexDownsize", downsize_tex_mobile);
  592. nodes.New().set ("iOSTexQuality" , texQualityiOS());
  593. if(usesTexAlpha())nodes.New().set("UsesTexAlpha");
  594. if(usesTexBump ())nodes.New().set("UsesTexBump" );
  595. if(usesTexGlow ())nodes.New().set("UsesTexGlow" );
  596. }
  597. void ElmMaterial::load(C MemPtr<TextNode> &nodes)
  598. {
  599. ::ElmData::load(nodes);
  600. REPA(nodes)
  601. {
  602. C TextNode &n=nodes[i];
  603. if(n.name=="Base0" )n.getValue( base_0_tex);else
  604. if(n.name=="Base1" )n.getValue( base_1_tex);else
  605. if(n.name=="Detail" )n.getValue( detail_tex);else
  606. if(n.name=="Macro" )n.getValue( macro_tex);else
  607. if(n.name=="Reflection" )n.getValue(reflection_tex);else
  608. if(n.name=="Light" )n.getValue( light_tex);else
  609. if(n.name=="MobileTexDownsize")downsize_tex_mobile =n.asInt () ;else
  610. if(n.name=="iOSTexQuality" )texQualityiOS (n.asBool());else
  611. if(n.name=="UsesTexAlpha" )FlagSet(flag, USES_TEX_ALPHA, n.asBool1());else
  612. if(n.name=="UsesTexBump" )FlagSet(flag, USES_TEX_BUMP , n.asBool1());else
  613. if(n.name=="UsesTexGlow" )FlagSet(flag, USES_TEX_GLOW , n.asBool1());
  614. }
  615. }
  616. bool ElmWaterMtrl::equal(C ElmMaterial &src)C {return ::ElmData::equal(src);}
  617. bool ElmWaterMtrl::newer(C ElmMaterial &src)C {return ::ElmData::newer(src);}
  618. bool ElmWaterMtrl::usesTexAlpha()C {return FlagTest(flag, USES_TEX_ALPHA );}
  619. void ElmWaterMtrl::usesTexAlpha(bool on) {return FlagSet(flag, USES_TEX_ALPHA , on);}
  620. bool ElmWaterMtrl::usesTexBump()C {return FlagTest(flag, USES_TEX_BUMP );}
  621. void ElmWaterMtrl::usesTexBump(bool on) {return FlagSet(flag, USES_TEX_BUMP , on);}
  622. bool ElmWaterMtrl::usesTexGlow()C {return FlagTest(flag, USES_TEX_GLOW );}
  623. void ElmWaterMtrl::usesTexGlow(bool on) {return FlagSet(flag, USES_TEX_GLOW , on);}
  624. bool ElmWaterMtrl::texQualityiOS()C {return FlagTest(flag, TEX_QUALITY_IOS);}
  625. void ElmWaterMtrl::texQualityiOS(bool on) {return FlagSet(flag, TEX_QUALITY_IOS, on);}
  626. bool ElmWaterMtrl::equal(C ElmWaterMtrl &src)C {return ::ElmData::equal(src);}
  627. bool ElmWaterMtrl::newer(C ElmWaterMtrl &src)C {return ::ElmData::newer(src);}
  628. bool ElmWaterMtrl::mayContain(C UID &id)C {return false;}
  629. bool ElmWaterMtrl::containsTex(C UID &id, bool test_merged)C
  630. {
  631. if(id.valid())
  632. {
  633. if(base_0_tex==id || base_1_tex==id || reflection_tex==id)return true;
  634. if(test_merged && MergedBaseTexturesID(base_0_tex, base_1_tex)==id)return true;
  635. }
  636. return false;
  637. }
  638. void ElmWaterMtrl::listTexs(MemPtr<UID> texs)C
  639. {
  640. if( base_0_tex.valid())texs.binaryInclude( base_0_tex, Compare);
  641. if( base_1_tex.valid())texs.binaryInclude( base_1_tex, Compare);
  642. if(reflection_tex.valid())texs.binaryInclude(reflection_tex, Compare);
  643. }
  644. void ElmWaterMtrl::from(C EditWaterMtrl &src)
  645. {
  646. base_0_tex=src. base_0_tex;
  647. base_1_tex=src. base_1_tex;
  648. reflection_tex=src.reflection_tex;
  649. usesTexAlpha (src.usesTexAlpha());
  650. usesTexBump (src.usesTexBump ());
  651. usesTexGlow (src.usesTexGlow ());
  652. texQualityiOS(src.high_quality_ios);
  653. }
  654. uint ElmWaterMtrl::undo(C ElmWaterMtrl &src) {return ::ElmData::undo(src);}
  655. uint ElmWaterMtrl::sync(C ElmWaterMtrl &src) {return ::ElmData::sync(src);}
  656. bool ElmWaterMtrl::save(File &f)C
  657. {
  658. ::ElmData::save(f);
  659. f.cmpUIntV(1);
  660. f<<base_0_tex<<base_1_tex<<reflection_tex<<flag;
  661. return f.ok();
  662. }
  663. bool ElmWaterMtrl::load(File &f)
  664. {
  665. if(::ElmData::load(f))switch(f.decUIntV())
  666. {
  667. case 1:
  668. {
  669. f>>base_0_tex>>base_1_tex>>reflection_tex>>flag;
  670. if(f.ok())return true;
  671. }break;
  672. case 0:
  673. {
  674. f>>base_0_tex>>base_1_tex>>reflection_tex; flag=0;
  675. if(f.ok())return true;
  676. }break;
  677. }
  678. return false;
  679. }
  680. void ElmWaterMtrl::save(MemPtr<TextNode> nodes)C
  681. {
  682. ::ElmData::save(nodes);
  683. if( base_0_tex.valid())nodes.New().setFN("Base0" , base_0_tex);
  684. if( base_1_tex.valid())nodes.New().setFN("Base1" , base_1_tex);
  685. if(reflection_tex.valid())nodes.New().setFN("Reflection" , reflection_tex);
  686. nodes.New().set ("iOSTexQuality", texQualityiOS());
  687. if(usesTexAlpha() )nodes.New().set ("UsesTexAlpha");
  688. if(usesTexBump () )nodes.New().set ("UsesTexBump" );
  689. if(usesTexGlow () )nodes.New().set ("UsesTexGlow" );
  690. }
  691. void ElmWaterMtrl::load(C MemPtr<TextNode> &nodes)
  692. {
  693. ::ElmData::load(nodes);
  694. REPA(nodes)
  695. {
  696. C TextNode &n=nodes[i];
  697. if(n.name=="Base0" )n.getValue( base_0_tex);else
  698. if(n.name=="Base1" )n.getValue( base_1_tex);else
  699. if(n.name=="Reflection" )n.getValue(reflection_tex);else
  700. if(n.name=="iOSTexQuality")texQualityiOS(n.asBool());else
  701. if(n.name=="UsesTexAlpha" )FlagSet(flag, USES_TEX_ALPHA, n.asBool1());else
  702. if(n.name=="UsesTexBump" )FlagSet(flag, USES_TEX_BUMP , n.asBool1());else
  703. if(n.name=="UsesTexGlow" )FlagSet(flag, USES_TEX_GLOW , n.asBool1());
  704. }
  705. }
  706. bool ElmPhysMtrl::equal(C ElmPhysMtrl &src)C {return ::ElmData::equal(src);}
  707. bool ElmPhysMtrl::newer(C ElmPhysMtrl &src)C {return ::ElmData::newer(src);}
  708. bool ElmPhysMtrl::mayContain(C UID &id)C {return false;}
  709. void ElmPhysMtrl::from(C EditPhysMtrl &src) {}
  710. uint ElmPhysMtrl::undo(C ElmPhysMtrl &src) {return ::ElmData::undo(src);}
  711. uint ElmPhysMtrl::sync(C ElmPhysMtrl &src) {return ::ElmData::sync(src);}
  712. bool ElmPhysMtrl::save(File &f)C
  713. {
  714. ::ElmData::save(f);
  715. f.cmpUIntV(0);
  716. return f.ok();
  717. }
  718. bool ElmPhysMtrl::load(File &f)
  719. {
  720. if(::ElmData::load(f))switch(f.decUIntV())
  721. {
  722. case 0:
  723. {
  724. if(f.ok())return true;
  725. }break;
  726. }
  727. return false;
  728. }
  729. void ElmPhysMtrl::save(MemPtr<TextNode> nodes)C
  730. {
  731. ::ElmData::save(nodes);
  732. }
  733. void ElmPhysMtrl::load(C MemPtr<TextNode> &nodes)
  734. {
  735. ::ElmData::load(nodes);
  736. REPA(nodes)
  737. {
  738. C TextNode &n=nodes[i];
  739. }
  740. }
  741. bool ElmSkel::equal(C ElmSkel &src)C {return ::ElmData::equal(src) && file_time==src.file_time && EqualID(mesh_id, src.mesh_id);}
  742. bool ElmSkel::newer(C ElmSkel &src)C {return ::ElmData::newer(src) || file_time> src.file_time || NewerID(mesh_id, src.mesh_id);}
  743. bool ElmSkel::mayContain(C UID &id)C {return id==mesh_id;}
  744. void ElmSkel::clearLinked( ) {mesh_id.zero();}
  745. void ElmSkel::newData()
  746. {
  747. ::ElmData::newData();
  748. file_time++;
  749. }
  750. uint ElmSkel::undo(C ElmSkel &src)
  751. {
  752. uint changed=::ElmData::undo(src);
  753. changed|=UndoID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  754. if(changed)newVer();
  755. return changed;
  756. }
  757. uint ElmSkel::sync(C ElmSkel &src)
  758. {
  759. uint changed=::ElmData::sync(src);
  760. changed|=SyncID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  761. if(equal(src))ver=src.ver;else if(changed)newVer();
  762. return changed;
  763. }
  764. bool ElmSkel::syncFile(C ElmSkel &src)
  765. {
  766. bool changed=false;
  767. if(Sync(file_time, src.file_time)){changed|=true; transform=src.transform;}
  768. if(equal(src))ver=src.ver;else if(changed)newVer();
  769. return changed;
  770. }
  771. bool ElmSkel::save(File &f)C
  772. {
  773. ::ElmData::save(f);
  774. f.cmpUIntV(0);
  775. f<<mesh_id<<transform<<file_time;
  776. return f.ok();
  777. }
  778. bool ElmSkel::load(File &f)
  779. {
  780. if(::ElmData::load(f))switch(f.decUIntV())
  781. {
  782. case 0:
  783. {
  784. f>>mesh_id>>transform>>file_time;
  785. if(f.ok())return true;
  786. }break;
  787. }
  788. return false;
  789. }
  790. void ElmSkel::save(MemPtr<TextNode> nodes)C
  791. {
  792. ::ElmData::save(nodes);
  793. nodes.New().setRaw("Pose" , transform);
  794. if(mesh_id.valid())nodes.New().setFN ("Mesh" , mesh_id);
  795. nodes.New().set ("FileTime", file_time.text());
  796. }
  797. void ElmSkel::load(C MemPtr<TextNode> &nodes)
  798. {
  799. ::ElmData::load(nodes);
  800. REPA(nodes)
  801. {
  802. C TextNode &n=nodes[i];
  803. if(n.name=="Pose" )n.getValueRaw(transform);else
  804. if(n.name=="Mesh" )n.getValue (mesh_id );else
  805. if(n.name=="FileTime")file_time=n.asText();
  806. }
  807. }
  808. bool ElmPhys::hasBody()C {return box.valid();}
  809. bool ElmPhys::equal(C ElmPhys &src)C {return ::ElmData::equal(src) && file_time==src.file_time && mtrl_time==src.mtrl_time && density_time==src.density_time && EqualID(mesh_id, src.mesh_id);}
  810. bool ElmPhys::newer(C ElmPhys &src)C {return ::ElmData::newer(src) || file_time> src.file_time || mtrl_time> src.mtrl_time || density_time> src.density_time || NewerID(mesh_id, src.mesh_id);}
  811. bool ElmPhys::mayContain(C UID &id)C {return id==mesh_id || id==mtrl_id;}
  812. void ElmPhys::clearLinked( ) {mesh_id.zero();}
  813. void ElmPhys::newData()
  814. {
  815. ::ElmData::newData();
  816. file_time++;
  817. mtrl_time++;
  818. density_time++;
  819. }
  820. uint ElmPhys::undo(C ElmPhys &src)
  821. {
  822. uint changed=::ElmData::undo(src);
  823. changed|=UndoID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  824. changed|=Undo( mtrl_time, src. mtrl_time, mtrl_id, src.mtrl_id)*CHANGE_AFFECT_FILE;
  825. changed|=Undo(density_time, src.density_time, density, src.density)*CHANGE_AFFECT_FILE;
  826. if(Undo(file_time, src.file_time)){changed|=CHANGE_AFFECT_FILE; transform=src.transform; box=src.box;}
  827. if(changed)newVer();
  828. return changed;
  829. }
  830. uint ElmPhys::sync(C ElmPhys &src)
  831. {
  832. uint changed=::ElmData::sync(src);
  833. changed|=SyncID(mesh_id, src.mesh_id)*CHANGE_NORMAL;
  834. changed|=Sync( mtrl_time, src. mtrl_time, mtrl_id, src.mtrl_id)*CHANGE_AFFECT_FILE;
  835. changed|=Sync(density_time, src.density_time, density, src.density)*CHANGE_AFFECT_FILE;
  836. if(equal(src))ver=src.ver;else if(changed)newVer();
  837. return changed;
  838. }
  839. bool ElmPhys::syncFile(C ElmPhys &src)
  840. {
  841. bool changed=false;
  842. if(Sync(file_time, src.file_time)){changed|=true; transform=src.transform; box=src.box;}
  843. if(equal(src))ver=src.ver;else if(changed)newVer();
  844. return changed;
  845. }
  846. void ElmPhys::from(C PhysBody &game_phys) // game version of phys must be passed here
  847. {
  848. if(game_phys.is())box=game_phys.box;else box.set(Vec(0), Vec(-1));
  849. }
  850. bool ElmPhys::save(File &f)C
  851. {
  852. ::ElmData::save(f);
  853. f.cmpUIntV(0);
  854. f<<mesh_id<<mtrl_id<<density<<transform<<box<<file_time<<mtrl_time<<density_time;
  855. return f.ok();
  856. }
  857. bool ElmPhys::load(File &f)
  858. {
  859. if(::ElmData::load(f))switch(f.decUIntV())
  860. {
  861. case 0:
  862. {
  863. f>>mesh_id>>mtrl_id>>density>>transform>>box>>file_time>>mtrl_time>>density_time;
  864. if(f.ok())return true;
  865. }break;
  866. }
  867. return false;
  868. }
  869. void ElmPhys::save(MemPtr<TextNode> nodes)C
  870. {
  871. ::ElmData::save(nodes);
  872. nodes.New().setRaw("Pose" , transform);
  873. nodes.New().setRaw("Box" , box );
  874. nodes.New().setRaw("Density" , density );
  875. if(mesh_id.valid())nodes.New().setFN ("Mesh" , mesh_id );
  876. if(mtrl_id.valid())nodes.New().setFN ("Material" , mtrl_id );
  877. nodes.New().set ("FileTime" , file_time.text());
  878. nodes.New().set ("MaterialTime", mtrl_time.text());
  879. nodes.New().set ("DensityTime" , density_time.text());
  880. }
  881. void ElmPhys::load(C MemPtr<TextNode> &nodes)
  882. {
  883. ::ElmData::load(nodes);
  884. REPA(nodes)
  885. {
  886. C TextNode &n=nodes[i];
  887. if(n.name=="Pose" )n.getValueRaw(transform);else
  888. if(n.name=="Box" )n.getValueRaw(box );else
  889. if(n.name=="Density" )n.getValueRaw(density );else
  890. if(n.name=="Mesh" )n.getValue (mesh_id );else
  891. if(n.name=="Material" )n.getValue (mtrl_id );else
  892. if(n.name=="FileTime" ) file_time=n.asText();else
  893. if(n.name=="MaterialTime") mtrl_time=n.asText();else
  894. if(n.name=="DensityTime" )density_time=n.asText();
  895. }
  896. }
  897. bool ElmAnim::loop()C {return FlagTest(flag, LOOP );}
  898. ElmAnim& ElmAnim::loop(bool on) {FlagSet(flag, LOOP , on); return T;}
  899. bool ElmAnim::linear()C {return FlagTest(flag, LINEAR);}
  900. ElmAnim& ElmAnim::linear(bool on) {FlagSet(flag, LINEAR, on); return T;}
  901. bool ElmAnim::equal(C ElmAnim &src)C {return ::ElmData::equal(src) && loop_time==src.loop_time && linear_time==src.linear_time && skel_time==src.skel_time && file_time==src.file_time;}
  902. bool ElmAnim::newer(C ElmAnim &src)C {return ::ElmData::newer(src) || loop_time> src.loop_time || linear_time> src.linear_time || skel_time> src.skel_time || file_time> src.file_time;}
  903. bool ElmAnim::rootMove( )C {return !EqualMem(root_move, VecZero);}
  904. bool ElmAnim::rootRot( )C {return !EqualMem(root_rot , VecZero);}
  905. void ElmAnim::rootMoveZero( ) {root_move.zero();}
  906. void ElmAnim::rootRotZero( ) {root_rot .zero();}
  907. void ElmAnim::rootMove(C Vec &move) {root_move=move; if(!rootMove())CHSSB(root_move.x);}
  908. void ElmAnim::rootRot(C Vec &rot ) {root_rot =rot ; if(!rootRot ())CHSSB(root_rot .x);}
  909. uint ElmAnim::rootFlags( )C
  910. {
  911. uint f=0;
  912. if(flag&ROOT_DEL_POS_X)f|=::ROOT_DEL_POSITION_X;
  913. if(flag&ROOT_DEL_POS_Y)f|=::ROOT_DEL_POSITION_Y;
  914. if(flag&ROOT_DEL_POS_Z)f|=::ROOT_DEL_POSITION_Z;
  915. if(flag&ROOT_DEL_ROT_X)f|=::ROOT_DEL_ROTATION_X;
  916. if(flag&ROOT_DEL_ROT_Y)f|=::ROOT_DEL_ROTATION_Y;
  917. if(flag&ROOT_DEL_ROT_Z)f|=::ROOT_DEL_ROTATION_Z;
  918. if(flag&ROOT_2_KEYS )f|=::ROOT_2_KEYS;
  919. if(flag&ROOT_FROM_BODY)f|=::ROOT_BONE_POSITION|::ROOT_START_IDENTITY;
  920. return f;
  921. }
  922. void ElmAnim::setRoot(Animation &anim) {SetRootMoveRot(anim, rootMove() ? &(root_move*transform.scale) : null, rootRot() ? &root_rot : null);}
  923. bool ElmAnim::mayContain(C UID &id)C {return id==skel_id;}
  924. void ElmAnim::newData()
  925. {
  926. ::ElmData::newData();
  927. loop_time++;
  928. linear_time++;
  929. skel_time++;
  930. file_time++;
  931. }
  932. void ElmAnim::from(C Animation &anim) {}
  933. uint ElmAnim::undo(C ElmAnim &src)
  934. {
  935. uint changed=::ElmData::undo(src);
  936. changed|=Undo(skel_time, src.skel_time, skel_id, src.skel_id)*CHANGE_NORMAL;
  937. if(Undo( loop_time, src. loop_time)){changed|=CHANGE_AFFECT_FILE; loop (src.loop ());}
  938. if(Undo(linear_time, src.linear_time)){changed|=CHANGE_AFFECT_FILE; linear(src.linear());}
  939. if(Undo( file_time, src. file_time)){changed|=CHANGE_AFFECT_FILE; transform=src.transform; root_move=src.root_move; root_rot=src.root_rot; FlagCopy(flag, src.flag, ROOT_ALL);}
  940. if(changed)newVer();
  941. return changed;
  942. }
  943. uint ElmAnim::sync(C ElmAnim &src)
  944. {
  945. uint changed=::ElmData::sync(src);
  946. changed|=Sync(skel_time, src.skel_time, skel_id, src.skel_id)*CHANGE_NORMAL;
  947. if(Sync( loop_time, src. loop_time)){changed|=CHANGE_AFFECT_FILE; loop (src.loop ());}
  948. if(Sync(linear_time, src.linear_time)){changed|=CHANGE_AFFECT_FILE; linear(src.linear());}
  949. if(equal(src))ver=src.ver;else if(changed)newVer();
  950. return changed;
  951. }
  952. bool ElmAnim::syncFile(C ElmAnim &src)
  953. {
  954. bool changed=false;
  955. if(Sync(file_time, src.file_time)){changed|=true; transform=src.transform; root_move=src.root_move; root_rot=src.root_rot; FlagCopy(flag, src.flag, ROOT_ALL);}
  956. if(equal(src))ver=src.ver;else if(changed)newVer();
  957. return true;
  958. }
  959. uint ElmAnim::OldFlag(byte old)
  960. {
  961. uint f=0;
  962. if(old&(1<<0))f|=LOOP;
  963. if(old&(1<<1))f|=LINEAR;
  964. if(old&(1<<2))f|=ROOT_DEL_POS_X;
  965. if(old&(1<<3))f|=ROOT_DEL_POS_Y;
  966. if(old&(1<<4))f|=ROOT_DEL_POS_Z;
  967. if(old&(1<<5))f|=ROOT_DEL_ROT;
  968. if(old&(1<<6))f|=ROOT_2_KEYS;
  969. if(old&(1<<7))f|=ROOT_FROM_BODY;
  970. return f;
  971. }
  972. bool ElmAnim::save(File &f)C
  973. {
  974. ::ElmData::save(f);
  975. f.cmpUIntV(3);
  976. f<<skel_id<<transform<<root_move<<root_rot<<flag<<loop_time<<linear_time<<skel_time<<file_time;
  977. return f.ok();
  978. }
  979. bool ElmAnim::load(File &f)
  980. {
  981. if(::ElmData::load(f))switch(f.decUIntV())
  982. {
  983. case 3:
  984. {
  985. f>>skel_id>>transform>>root_move>>root_rot>>flag>>loop_time>>linear_time>>skel_time>>file_time;
  986. if(f.ok())return true;
  987. }break;
  988. case 2:
  989. {
  990. f>>skel_id>>transform>>root_move>>root_rot; flag=OldFlag(f.getByte()); f>>loop_time>>linear_time>>skel_time>>file_time;
  991. if(f.ok())return true;
  992. }break;
  993. case 1:
  994. {
  995. f>>skel_id>>transform>>root_move; flag=OldFlag(f.getByte()); f>>loop_time>>linear_time>>skel_time>>file_time; rootRotZero();
  996. if(f.ok())return true;
  997. }break;
  998. case 0:
  999. {
  1000. f>>skel_id>>transform; flag=OldFlag(f.getByte()); f>>loop_time>>linear_time>>skel_time>>file_time; rootMoveZero(); rootRotZero();
  1001. if(f.ok())return true;
  1002. }break;
  1003. }
  1004. return false;
  1005. }
  1006. void ElmAnim::save(MemPtr<TextNode> nodes)C
  1007. {
  1008. ::ElmData::save(nodes);
  1009. if(skel_id.valid())nodes.New().setFN ("Skeleton" , skel_id);
  1010. nodes.New().setRaw("Pose" , transform);
  1011. nodes.New().set ("Loop" , loop());
  1012. nodes.New().set ("Linear" , linear());
  1013. if(rootMove() )nodes.New().setRaw("RootMove" , root_move);
  1014. if(rootRot () )nodes.New().setRaw("RootRot" , root_rot );
  1015. if(flag&ROOT_DEL_POS)nodes.New().set ("RootDelPos" , FlagAll(flag, ROOT_DEL_POS) ? S : S+(FlagTest(flag, ROOT_DEL_POS_X) ? 'X' : '\0')+(FlagTest(flag, ROOT_DEL_POS_Y) ? 'Y' : '\0')+(FlagTest(flag, ROOT_DEL_POS_Z) ? 'Z' : '\0'));
  1016. if(flag&ROOT_DEL_ROT)nodes.New().set ("RootDelRot" , FlagAll(flag, ROOT_DEL_ROT) ? S : S+(FlagTest(flag, ROOT_DEL_ROT_X) ? 'X' : '\0')+(FlagTest(flag, ROOT_DEL_ROT_Y) ? 'Y' : '\0')+(FlagTest(flag, ROOT_DEL_ROT_Z) ? 'Z' : '\0'));
  1017. if(flag&ROOT_2_KEYS )nodes.New().set ("Root2Keys" );
  1018. nodes.New().set ("LoopTime" , loop_time.text());
  1019. nodes.New().set ("LinearTime" , linear_time.text());
  1020. nodes.New().set ("SkeletonTime", skel_time.text());
  1021. nodes.New().set ("FileTime" , file_time.text());
  1022. }
  1023. void ElmAnim::load(C MemPtr<TextNode> &nodes)
  1024. {
  1025. ::ElmData::load(nodes);
  1026. REPA(nodes)
  1027. {
  1028. C TextNode &n=nodes[i];
  1029. if(n.name=="Skeleton" )n.getValue (skel_id);else
  1030. if(n.name=="Pose" )n.getValueRaw(transform);else
  1031. if(n.name=="RootMove" )n.getValueRaw(root_move);else
  1032. if(n.name=="RootRot" )n.getValueRaw(root_rot);else
  1033. if(n.name=="Loop" )loop (n.asBool1());else
  1034. if(n.name=="Linear" )linear(n.asBool1());else
  1035. if(n.name=="Root2Keys" )FlagSet(flag, ROOT_2_KEYS, n.asBool1());else
  1036. if(n.name=="LoopTime" ) loop_time=n.asText();else
  1037. if(n.name=="LinearTime" )linear_time=n.asText();else
  1038. if(n.name=="SkeletonTime") skel_time=n.asText();else
  1039. if(n.name=="FileTime" ) file_time=n.asText();else
  1040. if(n.name=="RootDelPos" )
  1041. {
  1042. if( !n.value.is() )FlagEnable(flag, ROOT_DEL_POS);else
  1043. if(CharFlag(n.value[0])&CHARF_DIG)FlagSet (flag, ROOT_DEL_POS, n.asBool());else
  1044. {
  1045. FlagSet(flag, ROOT_DEL_POS_X, Contains(n.value, 'x'));
  1046. FlagSet(flag, ROOT_DEL_POS_Y, Contains(n.value, 'y'));
  1047. FlagSet(flag, ROOT_DEL_POS_Z, Contains(n.value, 'z'));
  1048. }
  1049. }else
  1050. if(n.name=="RootDelRot")
  1051. {
  1052. if( !n.value.is() )FlagEnable(flag, ROOT_DEL_ROT);else
  1053. if(CharFlag(n.value[0])&CHARF_DIG)FlagSet (flag, ROOT_DEL_ROT, n.asBool());else
  1054. {
  1055. FlagSet(flag, ROOT_DEL_ROT_X, Contains(n.value, 'x'));
  1056. FlagSet(flag, ROOT_DEL_ROT_Y, Contains(n.value, 'y'));
  1057. FlagSet(flag, ROOT_DEL_ROT_Z, Contains(n.value, 'z'));
  1058. }
  1059. }
  1060. }
  1061. }
  1062. ElmEnv::ElmEnv() : sun_id(UIDZero), star_id(UIDZero), skybox_id(UIDZero) {REPAO(cloud_id).zero();}
  1063. void ElmEnv::from(C EditEnv &src)
  1064. {
  1065. sun_id=src.sun_id; star_id=src.star_id; skybox_id=src.skybox_id; REPAO(cloud_id)=src.cloud_id[i];
  1066. }
  1067. uint ElmEnv::undo(C ElmEnv &src) {return ::ElmData::undo(src);}
  1068. uint ElmEnv::sync(C ElmEnv &src) {return ::ElmData::sync(src);}
  1069. bool ElmEnv::mayContain(C UID &id)C {return id==sun_id || id==star_id || id==skybox_id || id==cloud_id[0] || id==cloud_id[1] || id==cloud_id[2] || id==cloud_id[3];}
  1070. bool ElmEnv::save(File &f)C
  1071. {
  1072. ::ElmData::save(f);
  1073. f.cmpUIntV(0);
  1074. f<<sun_id<<star_id<<skybox_id<<cloud_id;
  1075. return f.ok();
  1076. }
  1077. bool ElmEnv::load(File &f)
  1078. {
  1079. if(::ElmData::load(f))switch(f.decUIntV())
  1080. {
  1081. case 0:
  1082. {
  1083. f>>sun_id>>star_id>>skybox_id>>cloud_id;
  1084. if(f.ok())return true;
  1085. }break;
  1086. }
  1087. return false;
  1088. }
  1089. void ElmEnv::save(MemPtr<TextNode> nodes)C
  1090. {
  1091. ::ElmData::save(nodes);
  1092. if( sun_id.valid())nodes.New().setFN("Sun" , sun_id);
  1093. if( star_id.valid())nodes.New().setFN("Stars" , star_id);
  1094. if(skybox_id.valid())nodes.New().setFN("SkyBox", skybox_id);
  1095. {
  1096. TextNode &clouds=nodes.New().setName("Clouds");
  1097. FREPA(cloud_id) // list in order
  1098. {
  1099. TextParam &cloud=clouds.nodes.New();
  1100. if(cloud_id[i].valid())cloud.setValueFN(cloud_id[i]);
  1101. }
  1102. }
  1103. }
  1104. void ElmEnv::load(C MemPtr<TextNode> &nodes)
  1105. {
  1106. ::ElmData::load(nodes);
  1107. REPA(nodes)
  1108. {
  1109. C TextNode &n=nodes[i];
  1110. if(n.name=="Sun" )n.getValue( sun_id);else
  1111. if(n.name=="Stars" )n.getValue( star_id);else
  1112. if(n.name=="SkyBox")n.getValue(skybox_id);else
  1113. if(n.name=="Clouds")
  1114. {
  1115. REP(Min(n.nodes.elms(), Elms(cloud_id)))n.nodes[i].getValue(cloud_id[i]);
  1116. }
  1117. }
  1118. }
  1119. bool ElmWorld::valid()C {return area_size>0;}
  1120. bool ElmWorld::equal(C ElmWorld &src)C
  1121. {
  1122. return ::ElmData::equal(src)
  1123. && hm_res_time==src.hm_res_time
  1124. && ctrl_r_time==src.ctrl_r_time && ctrl_h_time==src.ctrl_h_time && max_climb_time==src.max_climb_time && max_slope_time==src.max_slope_time && cell_size_time==src.cell_size_time && cell_h_time==src.cell_h_time
  1125. && env_time==src.env_time;
  1126. }
  1127. bool ElmWorld::newer(C ElmWorld &src)C
  1128. {
  1129. return ::ElmData::newer(src)
  1130. || hm_res_time>src.hm_res_time
  1131. || ctrl_r_time>src.ctrl_r_time || ctrl_h_time>src.ctrl_h_time || max_climb_time>src.max_climb_time || max_slope_time>src.max_slope_time || cell_size_time>src.cell_size_time || cell_h_time>src.cell_h_time
  1132. || env_time>src.env_time;
  1133. }
  1134. int ElmWorld::hmRes()C {return hm_res ? NearestPow2(hm_res)+1 : 0;}
  1135. ElmWorld& ElmWorld::ctrlRadius(flt r ) {ctrl_r =Max(r , 0); ctrl_r_time .getUTC(); newVer(); return T;}
  1136. ElmWorld& ElmWorld::ctrlHeight(flt h ) {ctrl_h =Max(h , 0); ctrl_h_time .getUTC(); newVer(); return T;}
  1137. ElmWorld& ElmWorld::maxClimb(flt climb) {max_climb=Max(climb, 0); max_climb_time.getUTC(); newVer(); return T;}
  1138. ElmWorld& ElmWorld::maxSlope(flt slope) {max_slope=Mid(slope, 0.0f, PI_2); max_slope_time.getUTC(); newVer(); return T;}
  1139. ElmWorld& ElmWorld::cellSize(flt size ) {cell_size=Max(size , 0.001f); cell_size_time.getUTC(); newVer(); return T;}
  1140. ElmWorld& ElmWorld::cellHeight(flt h ) {cell_h =Max(h , 0.001f); cell_h_time .getUTC(); newVer(); return T;}
  1141. ElmWorld& ElmWorld::env(C UID &id) {env_id =id ; env_time .getUTC(); newVer(); return T;}
  1142. void ElmWorld::newData()
  1143. {
  1144. ::ElmData::newData();
  1145. hm_res_time++;
  1146. ctrl_r_time++;
  1147. ctrl_h_time++;
  1148. max_climb_time++;
  1149. max_slope_time++;
  1150. cell_size_time++;
  1151. cell_h_time++;
  1152. env_time++;
  1153. }
  1154. void ElmWorld::copyTo(Game::WorldSettings &settings, C Project &proj)C
  1155. {
  1156. settings.environment=proj.gamePath(env_id);
  1157. settings.areaSize(area_size).hmRes(hm_res);
  1158. }
  1159. void ElmWorld::copyTo(PathSettings &settings)C
  1160. {
  1161. settings.areaSize(area_size).ctrlRadius(ctrl_r).ctrlHeight(ctrl_h).maxClimb(max_climb).maxSlope(max_slope).cellSize(cell_size).cellHeight(cell_h);
  1162. }
  1163. uint ElmWorld::undo(C ElmWorld &src)
  1164. {
  1165. uint changed=::ElmData::undo(src);
  1166. if(!area_size && src.area_size){area_size=src.area_size; changed|=CHANGE_AFFECT_FILE;}
  1167. changed|=Undo(hm_res_time , src.hm_res_time , hm_res , src.hm_res )*CHANGE_AFFECT_FILE;
  1168. changed|=Undo(ctrl_r_time , src.ctrl_r_time , ctrl_r , src.ctrl_r )*CHANGE_AFFECT_FILE;
  1169. changed|=Undo(ctrl_h_time , src.ctrl_h_time , ctrl_h , src.ctrl_h )*CHANGE_AFFECT_FILE;
  1170. changed|=Undo(max_climb_time, src.max_climb_time, max_climb, src.max_climb)*CHANGE_AFFECT_FILE;
  1171. changed|=Undo(max_slope_time, src.max_slope_time, max_slope, src.max_slope)*CHANGE_AFFECT_FILE;
  1172. changed|=Undo(cell_size_time, src.cell_size_time, cell_size, src.cell_size)*CHANGE_AFFECT_FILE;
  1173. changed|=Undo(cell_h_time , src.cell_h_time , cell_h , src.cell_h )*CHANGE_AFFECT_FILE;
  1174. changed|=Undo(env_time , src.env_time , env_id , src.env_id )*CHANGE_AFFECT_FILE;
  1175. if(changed)newVer();
  1176. return changed;
  1177. }
  1178. uint ElmWorld::sync(C ElmWorld &src)
  1179. {
  1180. uint changed=::ElmData::sync(src);
  1181. if(!area_size && src.area_size){area_size=src.area_size; changed|=CHANGE_AFFECT_FILE;}
  1182. changed|=Sync(hm_res_time , src.hm_res_time , hm_res , src.hm_res )*CHANGE_AFFECT_FILE;
  1183. changed|=Sync(ctrl_r_time , src.ctrl_r_time , ctrl_r , src.ctrl_r )*CHANGE_AFFECT_FILE;
  1184. changed|=Sync(ctrl_h_time , src.ctrl_h_time , ctrl_h , src.ctrl_h )*CHANGE_AFFECT_FILE;
  1185. changed|=Sync(max_climb_time, src.max_climb_time, max_climb, src.max_climb)*CHANGE_AFFECT_FILE;
  1186. changed|=Sync(max_slope_time, src.max_slope_time, max_slope, src.max_slope)*CHANGE_AFFECT_FILE;
  1187. changed|=Sync(cell_size_time, src.cell_size_time, cell_size, src.cell_size)*CHANGE_AFFECT_FILE;
  1188. changed|=Sync(cell_h_time , src.cell_h_time , cell_h , src.cell_h )*CHANGE_AFFECT_FILE;
  1189. changed|=Sync(env_time , src.env_time , env_id , src.env_id )*CHANGE_AFFECT_FILE;
  1190. if(equal(src))ver=src.ver;else if(changed)newVer();
  1191. return changed;
  1192. }
  1193. bool ElmWorld::save(File &f)C
  1194. {
  1195. ::ElmData::save(f);
  1196. f.cmpUIntV(0);
  1197. f<<area_size<<hm_res<<hm_res_time<<ctrl_r<<ctrl_h<<max_climb<<max_slope<<cell_size<<cell_h<<env_id<<ctrl_r_time<<ctrl_h_time<<max_climb_time<<max_slope_time<<cell_size_time<<cell_h_time<<env_time;
  1198. return f.ok();
  1199. }
  1200. bool ElmWorld::load(File &f)
  1201. {
  1202. if(::ElmData::load(f))switch(f.decUIntV())
  1203. {
  1204. case 0:
  1205. {
  1206. f>>area_size>>hm_res>>hm_res_time>>ctrl_r>>ctrl_h>>max_climb>>max_slope>>cell_size>>cell_h>>env_id>>ctrl_r_time>>ctrl_h_time>>max_climb_time>>max_slope_time>>cell_size_time>>cell_h_time>>env_time;
  1207. if(f.ok())return true;
  1208. }break;
  1209. }
  1210. return false;
  1211. }
  1212. void ElmWorld::save(MemPtr<TextNode> nodes)C
  1213. {
  1214. ::ElmData::save(nodes);
  1215. nodes.New().set ("AreaSize" , area_size);
  1216. nodes.New().set ("HeightmapResolution", hm_res);
  1217. nodes.New().setRaw("ControllerRadius" , ctrl_r);
  1218. nodes.New().setRaw("ControllerHeight" , ctrl_h);
  1219. nodes.New().setRaw("MaxClimb" , max_climb);
  1220. nodes.New().setRaw("MaxSlope" , max_slope);
  1221. nodes.New().setRaw("CellSize" , cell_size);
  1222. nodes.New().setRaw("CellHeight" , cell_h);
  1223. if(env_id.valid())nodes.New().setFN ("Environment" , env_id);
  1224. nodes.New().set ("HeightmapResolutionTime", hm_res_time.text());
  1225. nodes.New().set ("ControllerRadiusTime" , ctrl_r_time.text());
  1226. nodes.New().set ("ControllerHeightTime" , ctrl_h_time.text());
  1227. nodes.New().set ("MaxClimbTime" , max_climb_time.text());
  1228. nodes.New().set ("MaxSlopeTime" , max_slope_time.text());
  1229. nodes.New().set ("CellSizeTime" , cell_size_time.text());
  1230. nodes.New().set ("CellHeightTime" , cell_h_time.text());
  1231. nodes.New().set ("EnvironmentTime" , env_time.text());
  1232. }
  1233. void ElmWorld::load(C MemPtr<TextNode> &nodes)
  1234. {
  1235. ::ElmData::load(nodes);
  1236. REPA(nodes)
  1237. {
  1238. C TextNode &n=nodes[i];
  1239. if(n.name=="AreaSize" )n.getValue (area_size);else
  1240. if(n.name=="HeightmapResolution")n.getValue (hm_res );else
  1241. if(n.name=="ControllerRadius" )n.getValueRaw(ctrl_r );else
  1242. if(n.name=="ControllerHeight" )n.getValueRaw(ctrl_h );else
  1243. if(n.name=="MaxClimb" )n.getValueRaw(max_climb);else
  1244. if(n.name=="MaxSlope" )n.getValueRaw(max_slope);else
  1245. if(n.name=="CellSize" )n.getValueRaw(cell_size);else
  1246. if(n.name=="CellHeight" )n.getValueRaw(cell_h );else
  1247. if(n.name=="Environment" )n.getValue (env_id );else
  1248. if(n.name=="HeightmapResolutionTime") hm_res_time=n.asText();else
  1249. if(n.name=="ControllerRadiusTime" ) ctrl_r_time=n.asText();else
  1250. if(n.name=="ControllerHeightTime" ) ctrl_h_time=n.asText();else
  1251. if(n.name=="MaxClimbTime" )max_climb_time=n.asText();else
  1252. if(n.name=="MaxSlopeTime" )max_slope_time=n.asText();else
  1253. if(n.name=="CellSizeTime" )cell_size_time=n.asText();else
  1254. if(n.name=="CellHeightTime" ) cell_h_time=n.asText();else
  1255. if(n.name=="EnvironmentTime" ) env_time=n.asText();
  1256. }
  1257. }
  1258. bool ElmEnum::mayContain(C UID &id)C {return false;}
  1259. void ElmEnum::from(C EditEnums &enums) {type=enums.type;}
  1260. uint ElmEnum::undo(C ElmEnum &src) {return ::ElmData::undo(src);}
  1261. uint ElmEnum::sync(C ElmEnum &src) {return ::ElmData::sync(src);}
  1262. bool ElmEnum::save(File &f)C
  1263. {
  1264. ::ElmData::save(f);
  1265. f.cmpUIntV(1)<<type;
  1266. return f.ok();
  1267. }
  1268. bool ElmEnum::load(File &f)
  1269. {
  1270. if(::ElmData::load(f))switch(f.decUIntV())
  1271. {
  1272. case 1:
  1273. {
  1274. f>>type;
  1275. if(f.ok())return true;
  1276. }break;
  1277. case 0:
  1278. {
  1279. type=EditEnums::DEFAULT;
  1280. if(f.ok())return true;
  1281. }break;
  1282. }
  1283. return false;
  1284. }
  1285. void ElmEnum::save(MemPtr<TextNode> nodes)C
  1286. {
  1287. ::ElmData::save(nodes);
  1288. if(type)nodes.New().set("Type", type);
  1289. }
  1290. void ElmEnum::load(C MemPtr<TextNode> &nodes)
  1291. {
  1292. ::ElmData::load(nodes);
  1293. REPA(nodes)
  1294. {
  1295. C TextNode &n=nodes[i];
  1296. if(n.name=="Type")type=EditEnums::TYPE(n.asInt());
  1297. }
  1298. }
  1299. bool ElmImage::ignoreAlpha()C {return mode==IMAGE_CUBE;}
  1300. bool ElmImage::mipMaps()C {return FlagTest(flag, MIP_MAPS );}
  1301. void ElmImage::mipMaps(bool on) {FlagSet(flag, MIP_MAPS , on);}
  1302. bool ElmImage::pow2()C {return FlagTest(flag, POW2 );}
  1303. void ElmImage::pow2(bool on) {FlagSet(flag, POW2 , on);}
  1304. bool ElmImage::alphaLum()C {return FlagTest(flag, ALPHA_LUM);}
  1305. void ElmImage::alphaLum(bool on) {FlagSet(flag, ALPHA_LUM, on);}
  1306. bool ElmImage::hasColor()C {return FlagTest(flag, HAS_COLOR);}
  1307. void ElmImage::hasColor(bool on) {FlagSet(flag, HAS_COLOR, on);}
  1308. bool ElmImage::hasAlpha()C {return FlagTest(flag, HAS_ALPHA);}
  1309. void ElmImage::hasAlpha(bool on) {FlagSet(flag, HAS_ALPHA, on);}
  1310. bool ElmImage::hasAlpha2()C {return hasAlpha() || alphaLum();}
  1311. bool ElmImage::hasAlpha3()C {return ignoreAlpha() ? false : hasAlpha2();}
  1312. IMAGE_TYPE ElmImage::androidType()C {return (type==COMPRESSED || type==COMPRESSED2) ? hasAlpha3() ? IMAGE_ETC2_A8 : ((AndroidETC2 || type==COMPRESSED2) ? IMAGE_ETC2 : IMAGE_ETC1) : IMAGE_NONE;}
  1313. IMAGE_TYPE ElmImage::iOSType()C {return (type==COMPRESSED || type==COMPRESSED2) ? IMAGE_PVRTC1_4 : IMAGE_NONE;}
  1314. IMAGE_TYPE ElmImage::webType()C {return (!WebBC7 && (type==COMPRESSED || type==COMPRESSED2) && hasAlpha3()) ? IMAGE_BC3 : IMAGE_NONE;}
  1315. bool ElmImage::equal(C ElmImage &src)C {return ::ElmData::equal(src) && mip_maps_time==src.mip_maps_time && pow2_time==src.pow2_time && alpha_lum_time==src.alpha_lum_time && type_time==src.type_time && mode_time==src.mode_time && size_time==src.size_time && file_time==src.file_time;}
  1316. bool ElmImage::newer(C ElmImage &src)C {return ::ElmData::newer(src) || mip_maps_time> src.mip_maps_time || pow2_time> src.pow2_time || alpha_lum_time> src.alpha_lum_time || type_time> src.type_time || mode_time> src.mode_time || size_time> src.size_time || file_time> src.file_time;}
  1317. bool ElmImage::mayContain(C UID &id)C {return false;}
  1318. void ElmImage::newData()
  1319. {
  1320. ::ElmData::newData(); mip_maps_time++; pow2_time++; alpha_lum_time++; type_time++; mode_time++; size_time++; file_time++;
  1321. }
  1322. uint ElmImage::undo(C ElmImage &src)
  1323. {
  1324. uint changed=::ElmData::undo(src);
  1325. changed|=Undo(type_time, src.type_time, type, src.type)*CHANGE_AFFECT_FILE;
  1326. changed|=Undo(mode_time, src.mode_time, mode, src.mode)*CHANGE_AFFECT_FILE;
  1327. changed|=Undo(size_time, src.size_time, size, src.size)*CHANGE_AFFECT_FILE;
  1328. if(Undo( mip_maps_time, src. mip_maps_time)){changed|=CHANGE_AFFECT_FILE; mipMaps (src.mipMaps ());}
  1329. if(Undo( pow2_time, src. pow2_time)){changed|=CHANGE_AFFECT_FILE; pow2 (src.pow2 ());}
  1330. if(Undo(alpha_lum_time, src.alpha_lum_time)){changed|=CHANGE_AFFECT_FILE; alphaLum(src.alphaLum());}
  1331. // do not undo 'hasColor, hasAlpha' as they're inherited from image data
  1332. if(changed)newVer();
  1333. return changed;
  1334. }
  1335. uint ElmImage::sync(C ElmImage &src)
  1336. {
  1337. uint changed=::ElmData::sync(src);
  1338. changed|=Sync(type_time, src.type_time, type, src.type)*CHANGE_AFFECT_FILE;
  1339. changed|=Sync(mode_time, src.mode_time, mode, src.mode)*CHANGE_AFFECT_FILE;
  1340. changed|=Sync(size_time, src.size_time, size, src.size)*CHANGE_AFFECT_FILE;
  1341. if(Sync( mip_maps_time, src. mip_maps_time)){changed|=CHANGE_AFFECT_FILE; mipMaps (src.mipMaps ());}
  1342. if(Sync( pow2_time, src. pow2_time)){changed|=CHANGE_AFFECT_FILE; pow2 (src.pow2 ());}
  1343. if(Sync(alpha_lum_time, src.alpha_lum_time)){changed|=CHANGE_AFFECT_FILE; alphaLum(src.alphaLum());}
  1344. // do not sync 'hasColor, hasAlpha' as they're inherited from image data
  1345. if(equal(src))ver=src.ver;else if(changed)newVer();
  1346. return changed;
  1347. }
  1348. bool ElmImage::syncFile(C ElmImage &src)
  1349. {
  1350. bool changed=false;
  1351. if(Sync(file_time, src.file_time)){changed|=true; hasColor(src.hasColor()); hasAlpha(src.hasAlpha());}
  1352. if(equal(src))ver=src.ver;else if(changed)newVer();
  1353. return changed;
  1354. }
  1355. bool ElmImage::save(File &f)C
  1356. {
  1357. ::ElmData::save(f);
  1358. f.cmpUIntV(2);
  1359. f<<flag<<type<<mode<<size<<mip_maps_time<<pow2_time<<alpha_lum_time<<type_time<<mode_time<<size_time<<file_time;
  1360. return f.ok();
  1361. }
  1362. bool ElmImage::load(File &f)
  1363. {
  1364. if(::ElmData::load(f))switch(f.decUIntV())
  1365. {
  1366. case 2:
  1367. {
  1368. f>>flag>>type>>mode>>size>>mip_maps_time>>pow2_time>>alpha_lum_time>>type_time>>mode_time>>size_time>>file_time;
  1369. if(f.ok())return true;
  1370. }break;
  1371. case 1:
  1372. {
  1373. f>>flag>>type>>mode>>size>>mip_maps_time>>pow2_time>>alpha_lum_time>>type_time>>mode_time>>size_time>>file_time; if(type>=1)type=ElmImage::TYPE(type+1);
  1374. if(f.ok())return true;
  1375. }break;
  1376. case 0:
  1377. {
  1378. f>>flag>>type>>mode>>mip_maps_time>>pow2_time>>alpha_lum_time>>type_time>>mode_time>>file_time; size=0; size_time.zero(); if(type>=1)type=ElmImage::TYPE(type+1);
  1379. if(f.ok())return true;
  1380. }break;
  1381. }
  1382. return false;
  1383. }
  1384. void ElmImage::save(MemPtr<TextNode> nodes)C
  1385. {
  1386. ::ElmData::save(nodes);
  1387. if(InRange(type, ImageTypes))nodes.New().set("Type", ImageTypes[type].name);
  1388. REPA(ImageModes)if(mode==ImageModes[i].mode){nodes.New().set("Mode", ImageModes[i].name); break;}
  1389. if(size.any())nodes.New().set("Size" , size);
  1390. nodes.New().set("MipMaps", mipMaps());
  1391. if(pow2 ())nodes.New().set("Pow2");
  1392. if(alphaLum())nodes.New().set("AlphaFromLum");
  1393. if(hasColor())nodes.New().set("HasColor");
  1394. if(hasAlpha())nodes.New().set("HasAlpha");
  1395. nodes.New().set("MipMapsTime" , mip_maps_time.text());
  1396. nodes.New().set("Pow2Time" , pow2_time.text());
  1397. nodes.New().set("AlphaFromLumTime", alpha_lum_time.text());
  1398. nodes.New().set("TypeTime" , type_time.text());
  1399. nodes.New().set("ModeTime" , mode_time.text());
  1400. nodes.New().set("SizeTime" , size_time.text());
  1401. nodes.New().set("FileTime" , file_time.text());
  1402. }
  1403. void ElmImage::load(C MemPtr<TextNode> &nodes)
  1404. {
  1405. ::ElmData::load(nodes);
  1406. REPA(nodes)
  1407. {
  1408. C TextNode &n=nodes[i];
  1409. if(n.name=="Type"){REPA(ImageTypes)if(n.value==ImageTypes[i].name){type= TYPE(i) ; break;}}else
  1410. if(n.name=="Mode"){REPA(ImageModes)if(n.value==ImageModes[i].name){mode=ImageModes[i].mode; break;}}else
  1411. if(n.name=="Size" )n.getValue(size);else
  1412. if(n.name=="MipMaps" )mipMaps (n.asBool1());else
  1413. if(n.name=="Pow2" )pow2 (n.asBool1());else
  1414. if(n.name=="AlphaFromLum")alphaLum(n.asBool1());else
  1415. if(n.name=="HasColor" )hasColor(n.asBool1());else
  1416. if(n.name=="HasAlpha" )hasAlpha(n.asBool1());else
  1417. if(n.name=="MipMapsTime" ) mip_maps_time=n.value;else
  1418. if(n.name=="Pow2Time" ) pow2_time=n.value;else
  1419. if(n.name=="AlphaFromLumTime")alpha_lum_time=n.value;else
  1420. if(n.name=="TypeTime" ) type_time=n.value;else
  1421. if(n.name=="ModeTime" ) mode_time=n.value;else
  1422. if(n.name=="SizeTime" ) size_time=n.value;else
  1423. if(n.name=="FileTime" ) file_time=n.value;
  1424. }
  1425. }
  1426. int ElmImageAtlas::Img::Compare(C Img &img, C UID &id) {return ::Compare(img.id, id);}
  1427. bool ElmImageAtlas::Img::equal(C Img &src)C {return removed_time==src.removed_time;}
  1428. bool ElmImageAtlas::Img::newer(C Img &src)C {return removed_time> src.removed_time;}
  1429. bool ElmImageAtlas::Img::undo(C Img &src) {return Undo(removed_time, src.removed_time, removed, src.removed);}
  1430. C ::ElmImageAtlas::Img* ElmImageAtlas::find(C UID &id)C {return ConstCast(T).find(id);}
  1431. ::ElmImageAtlas::Img* ElmImageAtlas::find(C UID &id) { return images.binaryFind (id, Img::Compare);}
  1432. ::ElmImageAtlas::Img& ElmImageAtlas::get(C UID &id) {int i; return images.binarySearch(id, i, Img::Compare) ? images[i] : images.NewAt(i);}
  1433. void ElmImageAtlas::newData(){::ElmData::newData(); file_time++; mip_maps_time++;}
  1434. bool ElmImageAtlas::equal(C ElmImageAtlas &src)C
  1435. {
  1436. if(file_time!=src.file_time || mip_maps_time!=src.mip_maps_time)return false;
  1437. if(images.elms()!=src.images.elms())return false;
  1438. REPA(images){C Img &img=images[i]; C Img *s=src.find(img.id); if(!s || !img.equal(*s))return false;}
  1439. return ::ElmData::equal(src);
  1440. }
  1441. bool ElmImageAtlas::newer(C ElmImageAtlas &src)C
  1442. {
  1443. if(file_time>src.file_time || mip_maps_time>src.mip_maps_time)return true;
  1444. REPA(images){C Img &img=images[i]; C Img *s=src.find(img.id); if(!s || img.newer(*s))return true;}
  1445. return ::ElmData::newer(src);
  1446. }
  1447. bool ElmImageAtlas::mayContain(C UID &id)C {REPA(images)if(id==images[i].id)return true; return false;}
  1448. uint ElmImageAtlas::undo(C ElmImageAtlas &src)
  1449. {
  1450. uint changed=::ElmData::undo(src);
  1451. changed|=Undo(mip_maps_time, src.mip_maps_time, mip_maps, src.mip_maps)*CHANGE_AFFECT_FILE;
  1452. // mark as removed those that aren't present in 'src'
  1453. REPA(images)
  1454. {
  1455. Img &img=images[i];
  1456. if( !img.removed && !src.find(img.id)){img.removed=true; img.removed_time++; changed|=CHANGE_AFFECT_FILE;}
  1457. }
  1458. // undo/insert from 'src'
  1459. REPA(src.images)
  1460. {
  1461. C Img &s=src.images[i];
  1462. Img *t=find(s.id);
  1463. if(t)changed|=t->undo(s)*CHANGE_AFFECT_FILE;else{get(s.id)=s; changed|=CHANGE_AFFECT_FILE;}
  1464. }
  1465. if(changed)newVer();
  1466. return changed;
  1467. }
  1468. uint ElmImageAtlas::sync(C ElmImageAtlas &src)
  1469. {
  1470. uint changed=::ElmData::sync(src);
  1471. changed|=Sync(mip_maps_time, src.mip_maps_time, mip_maps, src.mip_maps)*CHANGE_AFFECT_FILE;
  1472. REPA(src.images)
  1473. {
  1474. C Img &s=src.images[i];
  1475. Img &d=get(s.id); if(!d.id.valid()){d.id=s.id; changed|=CHANGE_AFFECT_FILE;}
  1476. changed|=Sync(d.removed_time, s.removed_time, d.removed, s.removed)*CHANGE_AFFECT_FILE;
  1477. }
  1478. if(equal(src))ver=src.ver;else if(changed)newVer();
  1479. return changed;
  1480. }
  1481. bool ElmImageAtlas::syncFile(C ElmImageAtlas &src)
  1482. {
  1483. bool changed=false;
  1484. changed|=Sync(file_time, src.file_time);
  1485. if(equal(src))ver=src.ver;else if(changed)newVer();
  1486. return changed;
  1487. }
  1488. bool ElmImageAtlas::save(File &f)C
  1489. {
  1490. ::ElmData::save(f);
  1491. f.cmpUIntV(1);
  1492. f<<mip_maps<<file_time<<mip_maps_time;
  1493. f.cmpUIntV(images.elms());
  1494. FREPA(images)f<<images[i].removed<<images[i].id<<images[i].removed_time;
  1495. return f.ok();
  1496. }
  1497. bool ElmImageAtlas::load(File &f)
  1498. {
  1499. if(::ElmData::load(f))switch(f.decUIntV())
  1500. {
  1501. case 1:
  1502. {
  1503. f>>mip_maps>>file_time>>mip_maps_time;
  1504. images.setNum(f.decUIntV());
  1505. FREPA(images)f>>images[i].removed>>images[i].id>>images[i].removed_time;
  1506. if(f.ok())return true;
  1507. }break;
  1508. case 0:
  1509. {
  1510. mip_maps=true; mip_maps_time=1;
  1511. f>>file_time;
  1512. images.setNum(f.decUIntV());
  1513. FREPA(images)f>>images[i].removed>>images[i].id>>images[i].removed_time;
  1514. if(f.ok())return true;
  1515. }break;
  1516. }
  1517. return false;
  1518. }
  1519. void ElmImageAtlas::save(MemPtr<TextNode> nodes)C
  1520. {
  1521. ::ElmData::save(nodes);
  1522. nodes.New().set("MipMaps" , mip_maps);
  1523. nodes.New().set("MipMapsTime", mip_maps_time.text());
  1524. nodes.New().set("FileTime" , file_time.text());
  1525. TextNode &images=nodes.New().setName("Images"); FREPA(T.images) // list in order
  1526. {
  1527. C Img &src =T.images[i];
  1528. TextNode &dest=images.nodes.New().setName(src.id.asFileName());
  1529. if(src.removed )dest.nodes.New().set("Removed");
  1530. if(src.removed_time.is())dest.nodes.New().set("RemovedTime", src.removed_time.text());
  1531. }
  1532. }
  1533. void ElmImageAtlas::load(C MemPtr<TextNode> &nodes)
  1534. {
  1535. ::ElmData::load(nodes);
  1536. REPA(nodes)
  1537. {
  1538. C TextNode &n=nodes[i];
  1539. if(n.name=="MipMaps" )mip_maps =n.asBool1();else
  1540. if(n.name=="MipMapsTime")mip_maps_time=n.value ;else
  1541. if(n.name=="FileTime" ) file_time=n.value ;else
  1542. if(n.name=="Images" )FREPA(n.nodes) // get in order
  1543. {
  1544. C TextNode &src=n.nodes[i]; UID id; if(id.fromText(src.name) && id.valid())
  1545. {
  1546. Img &dest=images.New(); dest.id=id;
  1547. REPA(src.nodes)
  1548. {
  1549. C TextNode &n=src.nodes[i];
  1550. if(n.name=="Removed" )dest.removed =n.asBool1();else
  1551. if(n.name=="RemovedTime")dest.removed_time=n.asText ();
  1552. }
  1553. }
  1554. }
  1555. }
  1556. }
  1557. bool ElmIconSetts::mayContain(C UID &id)C {return false;}
  1558. void ElmIconSetts::from(C IconSettings &src) {type=src.type;}
  1559. uint ElmIconSetts::undo(C ElmIconSetts &src) {return ::ElmData::undo(src);}
  1560. uint ElmIconSetts::sync(C ElmIconSetts &src) {return ::ElmData::sync(src);}
  1561. bool ElmIconSetts::save(File &f)C
  1562. {
  1563. ::ElmData::save(f);
  1564. f.cmpUIntV(1);
  1565. f<<type;
  1566. return f.ok();
  1567. }
  1568. bool ElmIconSetts::load(File &f)
  1569. {
  1570. if(::ElmData::load(f))switch(f.decUIntV())
  1571. {
  1572. case 1:
  1573. {
  1574. f>>type;
  1575. if(f.ok())return true;
  1576. }break;
  1577. case 0:
  1578. {
  1579. f>>type; if(type>=1)type=ElmImage::TYPE(type+1);
  1580. if(f.ok())return true;
  1581. }break;
  1582. }
  1583. return false;
  1584. }
  1585. void ElmIconSetts::save(MemPtr<TextNode> nodes)C
  1586. {
  1587. ::ElmData::save(nodes);
  1588. if(InRange(type, ElmImage::ImageTypes))nodes.New().set("Type", ElmImage::ImageTypes[type].name);
  1589. }
  1590. void ElmIconSetts::load(C MemPtr<TextNode> &nodes)
  1591. {
  1592. ::ElmData::load(nodes);
  1593. REPA(nodes)
  1594. {
  1595. C TextNode &n=nodes[i];
  1596. if(n.name=="Type"){REPA(ElmImage::ImageTypes)if(n.value==ElmImage::ImageTypes[i].name){type=ElmImage::TYPE(i); break;}}
  1597. }
  1598. }
  1599. ElmImage::TYPE ElmIcon::type(Project *proj)C {if(proj)if(Elm *elm=proj->findElm(icon_settings_id))if(ElmIconSetts *data=elm->iconSettsData())return data->type; return ElmImage::COMPRESSED;}
  1600. bool ElmIcon::hasColor( )C {return FlagTest(flag, HAS_COLOR);}
  1601. ElmIcon& ElmIcon::hasColor(bool on) {FlagSet(flag, HAS_COLOR, on); return T;}
  1602. bool ElmIcon::hasAlpha( )C {return FlagTest(flag, HAS_ALPHA);}
  1603. ElmIcon& ElmIcon::hasAlpha(bool on) {FlagSet(flag, HAS_ALPHA, on); return T;}
  1604. IMAGE_TYPE ElmIcon::androidType(Project *proj)C {ElmImage::TYPE type=T.type(proj); return (type==ElmImage::COMPRESSED || type==ElmImage::COMPRESSED2) ? hasAlpha() ? IMAGE_ETC2_A8 : ((AndroidETC2 || type==ElmImage::COMPRESSED2) ? IMAGE_ETC2 : IMAGE_ETC1) : IMAGE_NONE;}
  1605. IMAGE_TYPE ElmIcon::iOSType(Project *proj)C {ElmImage::TYPE type=T.type(proj); return (type==ElmImage::COMPRESSED || type==ElmImage::COMPRESSED2) ? IMAGE_PVRTC1_4 : IMAGE_NONE;}
  1606. IMAGE_TYPE ElmIcon::webType(Project *proj)C {ElmImage::TYPE type=T.type(proj); return (!WebBC7 && (type==ElmImage::COMPRESSED || type==ElmImage::COMPRESSED2) && hasAlpha()) ? IMAGE_BC3 : IMAGE_NONE;}
  1607. bool ElmIcon::equal(C ElmIcon &src)C {return ::ElmData::equal(src) && icon_settings_time==src.icon_settings_time && obj_time==src.obj_time && file_time==src.file_time && anim_id_time==src.anim_id_time && anim_pos_time==src.anim_pos_time && variation_time==src.variation_time;}
  1608. bool ElmIcon::newer(C ElmIcon &src)C {return ::ElmData::newer(src) || icon_settings_time> src.icon_settings_time || obj_time> src.obj_time || file_time> src.file_time || anim_id_time> src.anim_id_time || anim_pos_time> src.anim_pos_time || variation_time> src.variation_time;}
  1609. bool ElmIcon::mayContain(C UID &id)C {return id==icon_settings_id || id==obj_id || id==anim_id;}
  1610. void ElmIcon::newData()
  1611. {
  1612. ::ElmData::newData();
  1613. icon_settings_time++;
  1614. obj_time++;
  1615. file_time++;
  1616. anim_id_time++;
  1617. anim_pos_time++;
  1618. variation_time++;
  1619. }
  1620. uint ElmIcon::undo(C ElmIcon &src)
  1621. {
  1622. uint changed=::ElmData::undo(src);
  1623. changed|=Undo(icon_settings_time, src.icon_settings_time, icon_settings_id, src.icon_settings_id)*CHANGE_AFFECT_FILE;
  1624. changed|=Undo( obj_time, src. obj_time, obj_id, src. obj_id)*CHANGE_AFFECT_FILE;
  1625. changed|=Undo( anim_id_time, src. anim_id_time, anim_id, src. anim_id)*CHANGE_AFFECT_FILE;
  1626. changed|=Undo( anim_pos_time, src. anim_pos_time, anim_pos, src. anim_pos)*CHANGE_AFFECT_FILE;
  1627. changed|=Undo( variation_time, src. variation_time, variation_id, src. variation_id)*CHANGE_AFFECT_FILE;
  1628. if(changed)newVer();
  1629. return changed;
  1630. }
  1631. uint ElmIcon::sync(C ElmIcon &src)
  1632. {
  1633. uint changed=::ElmData::sync(src);
  1634. changed|=Sync(icon_settings_time, src.icon_settings_time, icon_settings_id, src.icon_settings_id)*CHANGE_AFFECT_FILE;
  1635. changed|=Sync( obj_time, src. obj_time, obj_id, src. obj_id)*CHANGE_AFFECT_FILE;
  1636. changed|=Sync( anim_id_time, src. anim_id_time, anim_id, src. anim_id)*CHANGE_AFFECT_FILE;
  1637. changed|=Sync( anim_pos_time, src. anim_pos_time, anim_pos, src. anim_pos)*CHANGE_AFFECT_FILE;
  1638. changed|=Sync( variation_time, src. variation_time, variation_id, src. variation_id)*CHANGE_AFFECT_FILE;
  1639. if(equal(src))ver=src.ver;else if(changed)newVer();
  1640. return changed;
  1641. }
  1642. bool ElmIcon::syncFile(C ElmIcon &src)
  1643. {
  1644. bool changed=false;
  1645. if(Sync(file_time, src.file_time)){changed|=true; hasColor(src.hasColor()); hasAlpha(src.hasAlpha());}
  1646. if(equal(src))ver=src.ver;else if(changed)newVer();
  1647. return changed;
  1648. }
  1649. bool ElmIcon::save(File &f)C
  1650. {
  1651. ::ElmData::save(f);
  1652. f.cmpUIntV(2);
  1653. f<<flag<<icon_settings_id<<obj_id<<anim_id<<anim_pos<<variation_id<<icon_settings_time<<obj_time<<anim_id_time<<anim_pos_time<<file_time<<variation_time;
  1654. return f.ok();
  1655. }
  1656. bool ElmIcon::load(File &f)
  1657. {
  1658. if(::ElmData::load(f))switch(f.decUIntV())
  1659. {
  1660. case 2:
  1661. {
  1662. f>>flag>>icon_settings_id>>obj_id>>anim_id>>anim_pos>>variation_id>>icon_settings_time>>obj_time>>anim_id_time>>anim_pos_time>>file_time>>variation_time;
  1663. if(f.ok())return true;
  1664. }break;
  1665. case 1:
  1666. {
  1667. f>>flag>>icon_settings_id>>obj_id>>anim_id>>anim_pos>>icon_settings_time>>obj_time>>anim_id_time>>anim_pos_time>>file_time;
  1668. if(f.ok())return true;
  1669. }break;
  1670. case 0:
  1671. {
  1672. f>>flag>>icon_settings_id>>obj_id>>icon_settings_time>>obj_time>>file_time; anim_id.zero(); anim_pos=0;
  1673. if(f.ok())return true;
  1674. }break;
  1675. }
  1676. return false;
  1677. }
  1678. void ElmIcon::save(MemPtr<TextNode> nodes)C
  1679. {
  1680. ::ElmData::save(nodes);
  1681. if(icon_settings_id.valid())nodes.New().setFN ("IconSettings" , icon_settings_id);
  1682. if( obj_id.valid())nodes.New().setFN ("Object" , obj_id);
  1683. if( anim_id.valid())nodes.New().setFN ("Animation" , anim_id);
  1684. nodes.New().set ("Variation" , variation_id);
  1685. if(anim_pos )nodes.New().setRaw("AnimationPosition", anim_pos);
  1686. if(hasColor() )nodes.New().set ("HasColor");
  1687. if(hasAlpha() )nodes.New().set ("HasAlpha");
  1688. nodes.New().set ("IconSettingsTime" , icon_settings_time.text());
  1689. nodes.New().set ("ObjectTime" , obj_time.text());
  1690. nodes.New().set ("FileTime" , file_time.text());
  1691. nodes.New().set ("AnimationTime" , anim_id_time.text());
  1692. nodes.New().set ("AnimationPositionTime", anim_pos_time.text());
  1693. nodes.New().set ("VariationTime" , variation_time.text());
  1694. }
  1695. void ElmIcon::load(C MemPtr<TextNode> &nodes)
  1696. {
  1697. ::ElmData::load(nodes);
  1698. REPA(nodes)
  1699. {
  1700. C TextNode &n=nodes[i];
  1701. if(n.name=="IconSettings" )n.getValue (icon_settings_id);else
  1702. if(n.name=="Object" )n.getValue ( obj_id);else
  1703. if(n.name=="Animation" )n.getValue ( anim_id);else
  1704. if(n.name=="Variation" )n.getValue ( variation_id);else
  1705. if(n.name=="AnimationPosition")n.getValueRaw( anim_pos);else
  1706. if(n.name=="HasColor" )hasColor(n.asBool1());else
  1707. if(n.name=="HasAlpha" )hasAlpha(n.asBool1());else
  1708. if(n.name=="IconSettingsTime" )icon_settings_time=n.asText();else
  1709. if(n.name=="ObjectTime" ) obj_time=n.asText();else
  1710. if(n.name=="FileTime" ) file_time=n.asText();else
  1711. if(n.name=="AnimationTime" ) anim_id_time=n.asText();else
  1712. if(n.name=="AnimationPositionTime") anim_pos_time=n.asText();else
  1713. if(n.name=="VariationTime" ) variation_time=n.asText();
  1714. }
  1715. }
  1716. bool ElmFont::mayContain(C UID &id)C {return false;}
  1717. void ElmFont::from(C EditFont &font) {}
  1718. uint ElmFont::undo(C ElmFont &src) {return ::ElmData::undo(src);}
  1719. uint ElmFont::sync(C ElmFont &src) {return ::ElmData::sync(src);}
  1720. bool ElmFont::save(File &f)C
  1721. {
  1722. ::ElmData::save(f);
  1723. f.cmpUIntV(0);
  1724. return f.ok();
  1725. }
  1726. bool ElmFont::load(File &f)
  1727. {
  1728. if(::ElmData::load(f))switch(f.decUIntV())
  1729. {
  1730. case 0:
  1731. {
  1732. if(f.ok())return true;
  1733. }break;
  1734. }
  1735. return false;
  1736. }
  1737. void ElmFont::save(MemPtr<TextNode> nodes)C
  1738. {
  1739. ::ElmData::save(nodes);
  1740. }
  1741. void ElmFont::load(C MemPtr<TextNode> &nodes)
  1742. {
  1743. ::ElmData::load(nodes);
  1744. REPA(nodes)
  1745. {
  1746. C TextNode &n=nodes[i];
  1747. }
  1748. }
  1749. bool ElmTextStyle::mayContain(C UID &id)C {return id==font_id;}
  1750. void ElmTextStyle::from(C EditTextStyle &ts ) {font_id=ts.font;}
  1751. uint ElmTextStyle::undo(C ElmTextStyle &src) {return ::ElmData::undo(src);}
  1752. uint ElmTextStyle::sync(C ElmTextStyle &src) {return ::ElmData::sync(src);}
  1753. bool ElmTextStyle::save(File &f)C
  1754. {
  1755. ::ElmData::save(f);
  1756. f.cmpUIntV(0);
  1757. f<<font_id;
  1758. return f.ok();
  1759. }
  1760. bool ElmTextStyle::load(File &f)
  1761. {
  1762. if(::ElmData::load(f))switch(f.decUIntV())
  1763. {
  1764. case 0:
  1765. {
  1766. f>>font_id;
  1767. if(f.ok())return true;
  1768. }break;
  1769. }
  1770. return false;
  1771. }
  1772. void ElmTextStyle::save(MemPtr<TextNode> nodes)C
  1773. {
  1774. ::ElmData::save(nodes);
  1775. if(font_id.valid())nodes.New().setFN("Font", font_id);
  1776. }
  1777. void ElmTextStyle::load(C MemPtr<TextNode> &nodes)
  1778. {
  1779. ::ElmData::load(nodes);
  1780. REPA(nodes)
  1781. {
  1782. C TextNode &n=nodes[i];
  1783. if(n.name=="Font")n.getValue(font_id);
  1784. }
  1785. }
  1786. bool ElmPanelImage::mayContain(C UID &id)C {return image_ids.binaryHas(id, Compare);}
  1787. void ElmPanelImage::from(C EditPanelImage &pi)
  1788. {
  1789. Memt<UID> temp; pi.base.includeIDs(temp); image_ids=temp;
  1790. compressed=pi.base.compressed;
  1791. }
  1792. uint ElmPanelImage::undo(C ElmPanelImage &src) {return ::ElmData::undo(src);}
  1793. uint ElmPanelImage::sync(C ElmPanelImage &src) {return ::ElmData::sync(src);}
  1794. bool ElmPanelImage::save(File &f)C
  1795. {
  1796. ::ElmData::save(f);
  1797. f.cmpUIntV(0);
  1798. f<<compressed;
  1799. image_ids.saveRaw(f);
  1800. return f.ok();
  1801. }
  1802. bool ElmPanelImage::load(File &f)
  1803. {
  1804. if(::ElmData::load(f))switch(f.decUIntV())
  1805. {
  1806. case 0:
  1807. {
  1808. f>>compressed;
  1809. if(image_ids.loadRaw(f))
  1810. if(f.ok())return true;
  1811. }break;
  1812. }
  1813. return false;
  1814. }
  1815. void ElmPanelImage::save(MemPtr<TextNode> nodes)C
  1816. {
  1817. ::ElmData::save(nodes);
  1818. nodes.New().set("Compressed", compressed);
  1819. {
  1820. TextNode &images=nodes.New().setName("Images");
  1821. FREPA(image_ids)images.nodes.New().setValueFN(image_ids[i]); // list in order
  1822. }
  1823. }
  1824. void ElmPanelImage::load(C MemPtr<TextNode> &nodes)
  1825. {
  1826. ::ElmData::load(nodes);
  1827. REPA(nodes)
  1828. {
  1829. C TextNode &n=nodes[i];
  1830. if(n.name=="Compressed")compressed=n.asBool1();else
  1831. if(n.name=="Images")
  1832. {
  1833. FREPA(n.nodes) // add in order
  1834. {
  1835. UID id; if(n.nodes[i].getValue(id) && id.valid())image_ids.binaryInclude(id, Compare);
  1836. }
  1837. }
  1838. }
  1839. }
  1840. bool ElmPanel::mayContain(C UID &id)C {return image_ids.binaryHas(id, Compare);}
  1841. void ElmPanel::from(C EditPanel &panel)
  1842. {
  1843. Memt<UID> temp; panel.includeIDs(temp); image_ids=temp;
  1844. }
  1845. uint ElmPanel::undo(C ElmPanel &src) {return ::ElmData::undo(src);}
  1846. uint ElmPanel::sync(C ElmPanel &src) {return ::ElmData::sync(src);}
  1847. bool ElmPanel::save(File &f)C
  1848. {
  1849. ::ElmData::save(f);
  1850. f.cmpUIntV(2);
  1851. image_ids.saveRaw(f);
  1852. return f.ok();
  1853. }
  1854. bool ElmPanel::load(File &f)
  1855. {
  1856. if(::ElmData::load(f))switch(f.decUIntV())
  1857. {
  1858. case 2:
  1859. {
  1860. if(image_ids.loadRaw(f))
  1861. if(f.ok())return true;
  1862. }break;
  1863. case 1: {Memt<UID> temp; REP(6)Include(temp, f.getUID()); image_ids=temp;} if(f.ok())return true; break;
  1864. case 0: {Memt<UID> temp; REP(4)Include(temp, f.getUID()); image_ids=temp;} if(f.ok())return true; break;
  1865. }
  1866. return false;
  1867. }
  1868. void ElmPanel::save(MemPtr<TextNode> nodes)C
  1869. {
  1870. ::ElmData::save(nodes);
  1871. {
  1872. TextNode &images=nodes.New().setName("Images");
  1873. FREPA(image_ids)images.nodes.New().setValueFN(image_ids[i]); // list in order
  1874. }
  1875. }
  1876. void ElmPanel::load(C MemPtr<TextNode> &nodes)
  1877. {
  1878. ::ElmData::load(nodes);
  1879. REPA(nodes)
  1880. {
  1881. C TextNode &n=nodes[i];
  1882. if(n.name=="Images")
  1883. {
  1884. FREPA(n.nodes) // add in order
  1885. {
  1886. UID id; if(n.nodes[i].getValue(id) && id.valid())image_ids.binaryInclude(id, Compare);
  1887. }
  1888. }
  1889. }
  1890. }
  1891. bool ElmGuiSkin::mayContain(C UID &id)C {return elm_ids.binaryHas(id, Compare);}
  1892. void ElmGuiSkin::from(C EditGuiSkin &pi)
  1893. {
  1894. Memt<UID> temp; pi.base.includeIDs(temp); elm_ids=temp;
  1895. }
  1896. uint ElmGuiSkin::undo(C ElmGuiSkin &src) {return ::ElmData::undo(src);}
  1897. uint ElmGuiSkin::sync(C ElmGuiSkin &src) {return ::ElmData::sync(src);}
  1898. bool ElmGuiSkin::save(File &f)C
  1899. {
  1900. ::ElmData::save(f);
  1901. f.cmpUIntV(0);
  1902. elm_ids.saveRaw(f);
  1903. return f.ok();
  1904. }
  1905. bool ElmGuiSkin::load(File &f)
  1906. {
  1907. if(::ElmData::load(f))switch(f.decUIntV())
  1908. {
  1909. case 0:
  1910. {
  1911. if(elm_ids.loadRaw(f))
  1912. if(f.ok())return true;
  1913. }break;
  1914. }
  1915. return false;
  1916. }
  1917. void ElmGuiSkin::save(MemPtr<TextNode> nodes)C
  1918. {
  1919. ::ElmData::save(nodes);
  1920. {
  1921. TextNode &elms=nodes.New().setName("Elements");
  1922. FREPA(elm_ids)elms.nodes.New().setValueFN(elm_ids[i]); // list in order
  1923. }
  1924. }
  1925. void ElmGuiSkin::load(C MemPtr<TextNode> &nodes)
  1926. {
  1927. ::ElmData::load(nodes);
  1928. REPA(nodes)
  1929. {
  1930. C TextNode &n=nodes[i];
  1931. if(n.name=="Elements")
  1932. {
  1933. FREPA(n.nodes) // add in order
  1934. {
  1935. UID id; if(n.nodes[i].getValue(id) && id.valid())elm_ids.binaryInclude(id, Compare);
  1936. }
  1937. }
  1938. }
  1939. }
  1940. bool ElmGui::equal(C ElmGui &src)C {return ::ElmData::equal(src) && file_time==src.file_time;}
  1941. bool ElmGui::newer(C ElmGui &src)C {return ::ElmData::newer(src) || file_time> src.file_time;}
  1942. void ElmGui::newData()
  1943. {
  1944. ::ElmData::newData();
  1945. file_time++;
  1946. }
  1947. uint ElmGui::undo(C ElmGui &src)
  1948. {
  1949. uint changed=::ElmData::undo(src);
  1950. if( changed)newVer();
  1951. return changed;
  1952. }
  1953. uint ElmGui::sync(C ElmGui &src)
  1954. {
  1955. uint changed=::ElmData::sync(src);
  1956. if(equal(src))ver=src.ver;else if(changed)newVer();
  1957. return changed;
  1958. }
  1959. bool ElmGui::syncFile(C ElmGui &src)
  1960. {
  1961. bool changed=false;
  1962. changed|=Sync(file_time, src.file_time);
  1963. if(equal(src))ver=src.ver;else if(changed)newVer();
  1964. return changed;
  1965. }
  1966. bool ElmGui::save(File &f)C
  1967. {
  1968. ::ElmData::save(f);
  1969. f.cmpUIntV(0);
  1970. f<<file_time;
  1971. return f.ok();
  1972. }
  1973. bool ElmGui::load(File &f)
  1974. {
  1975. if(::ElmData::load(f))switch(f.decUIntV())
  1976. {
  1977. case 0:
  1978. {
  1979. f>>file_time;
  1980. if(f.ok())return true;
  1981. }break;
  1982. }
  1983. return false;
  1984. }
  1985. void ElmGui::save(MemPtr<TextNode> nodes)C
  1986. {
  1987. ::ElmData::save(nodes);
  1988. nodes.New().set("FileTime", file_time.text());
  1989. }
  1990. void ElmGui::load(C MemPtr<TextNode> &nodes)
  1991. {
  1992. ::ElmData::load(nodes);
  1993. REPA(nodes)
  1994. {
  1995. C TextNode &n=nodes[i];
  1996. if(n.name=="FileTime")file_time=n.asText();
  1997. }
  1998. }
  1999. bool ElmSound::equal(C ElmSound &src)C {return ::ElmData::equal(src) && file_time==src.file_time;}
  2000. bool ElmSound::newer(C ElmSound &src)C {return ::ElmData::newer(src) || file_time> src.file_time;}
  2001. bool ElmSound::mayContain(C UID &id)C {return false;}
  2002. void ElmSound::newData()
  2003. {
  2004. ::ElmData::newData();
  2005. file_time++;
  2006. }
  2007. uint ElmSound::undo(C ElmSound &src)
  2008. {
  2009. uint changed=::ElmData::undo(src);
  2010. if( changed)newVer();
  2011. return changed;
  2012. }
  2013. uint ElmSound::sync(C ElmSound &src)
  2014. {
  2015. uint changed=::ElmData::sync(src);
  2016. if(equal(src))ver=src.ver;else if(changed)newVer();
  2017. return changed;
  2018. }
  2019. bool ElmSound::syncFile(C ElmSound &src)
  2020. {
  2021. bool changed=false;
  2022. changed|=Sync(file_time, src.file_time);
  2023. if(equal(src))ver=src.ver;else if(changed)newVer();
  2024. return changed;
  2025. }
  2026. bool ElmSound::save(File &f)C
  2027. {
  2028. ::ElmData::save(f);
  2029. f.cmpUIntV(0);
  2030. f<<file_time;
  2031. return f.ok();
  2032. }
  2033. bool ElmSound::load(File &f)
  2034. {
  2035. if(::ElmData::load(f))switch(f.decUIntV())
  2036. {
  2037. case 0:
  2038. {
  2039. f>>file_time;
  2040. if(f.ok())return true;
  2041. }break;
  2042. }
  2043. return false;
  2044. }
  2045. void ElmSound::save(MemPtr<TextNode> nodes)C
  2046. {
  2047. ::ElmData::save(nodes);
  2048. nodes.New().set("FileTime", file_time.text());
  2049. }
  2050. void ElmSound::load(C MemPtr<TextNode> &nodes)
  2051. {
  2052. ::ElmData::load(nodes);
  2053. REPA(nodes)
  2054. {
  2055. C TextNode &n=nodes[i];
  2056. if(n.name=="FileTime")file_time=n.asText();
  2057. }
  2058. }
  2059. bool ElmVideo::equal(C ElmVideo &src)C {return ::ElmData::equal(src) && file_time==src.file_time;}
  2060. bool ElmVideo::newer(C ElmVideo &src)C {return ::ElmData::newer(src) || file_time> src.file_time;}
  2061. bool ElmVideo::mayContain(C UID &id)C {return false;}
  2062. void ElmVideo::newData()
  2063. {
  2064. ::ElmData::newData();
  2065. file_time++;
  2066. }
  2067. uint ElmVideo::undo(C ElmVideo &src)
  2068. {
  2069. uint changed=::ElmData::undo(src);
  2070. if( changed)newVer();
  2071. return changed;
  2072. }
  2073. uint ElmVideo::sync(C ElmVideo &src)
  2074. {
  2075. uint changed=::ElmData::sync(src);
  2076. if(equal(src))ver=src.ver;else if(changed)newVer();
  2077. return changed;
  2078. }
  2079. bool ElmVideo::syncFile(C ElmVideo &src)
  2080. {
  2081. bool changed=false;
  2082. changed|=Sync(file_time, src.file_time);
  2083. if(equal(src))ver=src.ver;else if(changed)newVer();
  2084. return changed;
  2085. }
  2086. bool ElmVideo::save(File &f)C
  2087. {
  2088. ::ElmData::save(f);
  2089. f.cmpUIntV(0);
  2090. f<<file_time;
  2091. return f.ok();
  2092. }
  2093. bool ElmVideo::load(File &f)
  2094. {
  2095. if(::ElmData::load(f))switch(f.decUIntV())
  2096. {
  2097. case 0:
  2098. {
  2099. f>>file_time;
  2100. if(f.ok())return true;
  2101. }break;
  2102. }
  2103. return false;
  2104. }
  2105. void ElmVideo::save(MemPtr<TextNode> nodes)C
  2106. {
  2107. ::ElmData::save(nodes);
  2108. nodes.New().set("FileTime", file_time.text());
  2109. }
  2110. void ElmVideo::load(C MemPtr<TextNode> &nodes)
  2111. {
  2112. ::ElmData::load(nodes);
  2113. REPA(nodes)
  2114. {
  2115. C TextNode &n=nodes[i];
  2116. if(n.name=="FileTime")file_time=n.asText();
  2117. }
  2118. }
  2119. bool ElmFile::equal(C ElmFile &src)C {return ::ElmData::equal(src) && file_time==src.file_time;}
  2120. bool ElmFile::newer(C ElmFile &src)C {return ::ElmData::newer(src) || file_time> src.file_time;}
  2121. bool ElmFile::mayContain(C UID &id)C {return false;}
  2122. void ElmFile::newData()
  2123. {
  2124. ::ElmData::newData();
  2125. file_time++;
  2126. }
  2127. uint ElmFile::undo(C ElmFile &src)
  2128. {
  2129. uint changed=::ElmData::undo(src);
  2130. if( changed)newVer();
  2131. return changed;
  2132. }
  2133. uint ElmFile::sync(C ElmFile &src)
  2134. {
  2135. uint changed=::ElmData::sync(src);
  2136. if(equal(src))ver=src.ver;else if(changed)newVer();
  2137. return changed;
  2138. }
  2139. bool ElmFile::syncFile(C ElmFile &src)
  2140. {
  2141. bool changed=false;
  2142. changed|=Sync(file_time, src.file_time);
  2143. if(equal(src))ver=src.ver;else if(changed)newVer();
  2144. return changed;
  2145. }
  2146. bool ElmFile::save(File &f)C
  2147. {
  2148. ::ElmData::save(f);
  2149. f.cmpUIntV(0);
  2150. f<<file_time;
  2151. return f.ok();
  2152. }
  2153. bool ElmFile::load(File &f)
  2154. {
  2155. if(::ElmData::load(f))switch(f.decUIntV())
  2156. {
  2157. case 0:
  2158. {
  2159. f>>file_time;
  2160. if(f.ok())return true;
  2161. }break;
  2162. }
  2163. return false;
  2164. }
  2165. void ElmFile::save(MemPtr<TextNode> nodes)C
  2166. {
  2167. ::ElmData::save(nodes);
  2168. nodes.New().set("FileTime", file_time.text());
  2169. }
  2170. void ElmFile::load(C MemPtr<TextNode> &nodes)
  2171. {
  2172. ::ElmData::load(nodes);
  2173. REPA(nodes)
  2174. {
  2175. C TextNode &n=nodes[i];
  2176. if(n.name=="FileTime")file_time=n.asText();
  2177. }
  2178. }
  2179. uint ElmCode::undo(C ElmCode &src) {return ::ElmData::undo(src);}
  2180. uint ElmCode::sync(C ElmCode &src) {return ::ElmData::sync(src);}
  2181. void ElmCode::from(C Str &code) {}
  2182. bool ElmCode::save(File &f)C
  2183. {
  2184. ::ElmData::save(f);
  2185. f.cmpUIntV(0);
  2186. return f.ok();
  2187. }
  2188. bool ElmCode::load(File &f)
  2189. {
  2190. if(::ElmData::load(f))switch(f.decUIntV())
  2191. {
  2192. case 0:
  2193. {
  2194. if(f.ok())return true;
  2195. }break;
  2196. }
  2197. return false;
  2198. }
  2199. void ElmCode::save(MemPtr<TextNode> nodes)C
  2200. {
  2201. ::ElmData::save(nodes);
  2202. }
  2203. void ElmCode::load(C MemPtr<TextNode> &nodes)
  2204. {
  2205. ::ElmData::load(nodes);
  2206. REPA(nodes)
  2207. {
  2208. C TextNode &n=nodes[i];
  2209. }
  2210. }
  2211. bool ElmApp::equal(C ElmApp &src)C
  2212. {
  2213. return ::ElmData::equal(src)
  2214. && dirs_windows_time==src.dirs_windows_time && dirs_nonwindows_time==src.dirs_nonwindows_time
  2215. && headers_windows_time==src.headers_windows_time && headers_mac_time==src.headers_mac_time && headers_linux_time==src.headers_linux_time && headers_android_time==src.headers_android_time && headers_ios_time==src.headers_ios_time
  2216. && libs_windows_time==src.libs_windows_time && libs_mac_time==src.libs_mac_time && libs_linux_time==src.libs_linux_time && libs_android_time==src.libs_android_time && libs_ios_time==src.libs_ios_time
  2217. && package_time==src.package_time && android_license_key_time==src.android_license_key_time && location_usage_reason_time==src.location_usage_reason_time && build_time==src.build_time
  2218. && fb_app_id_time==src.fb_app_id_time
  2219. && cb_app_id_ios_time==src.cb_app_id_ios_time && cb_app_signature_ios_time==src.cb_app_signature_ios_time && cb_app_id_google_time==src.cb_app_id_google_time && cb_app_signature_google_time==src.cb_app_signature_google_time
  2220. && storage_time==src.storage_time && supported_orientations_time==src.supported_orientations_time
  2221. && embed_engine_data_time==src.embed_engine_data_time && publish_proj_data_time==src.publish_proj_data_time && publish_physx_dll_time==src.publish_physx_dll_time && publish_steam_dll_time==src.publish_steam_dll_time && publish_open_vr_dll_time==src.publish_open_vr_dll_time && publish_data_as_pak_time==src.publish_data_as_pak_time && android_expansion_time==src.android_expansion_time
  2222. && icon_time==src.icon_time && notification_icon_time==src.notification_icon_time && image_portrait_time==src.image_portrait_time && image_landscape_time==src.image_landscape_time && gui_skin_time==src.gui_skin_time;
  2223. }
  2224. bool ElmApp::newer(C ElmApp &src)C
  2225. {
  2226. return ::ElmData::newer(src)
  2227. || dirs_windows_time>src.dirs_windows_time || dirs_nonwindows_time>src.dirs_nonwindows_time
  2228. || headers_windows_time>src.headers_windows_time || headers_mac_time>src.headers_mac_time || headers_linux_time>src.headers_linux_time || headers_android_time>src.headers_android_time || headers_ios_time>src.headers_ios_time
  2229. || libs_windows_time>src.libs_windows_time || libs_mac_time>src.libs_mac_time || libs_linux_time>src.libs_linux_time || libs_android_time>src.libs_android_time || libs_ios_time>src.libs_ios_time
  2230. || package_time>src.package_time || android_license_key_time>src.android_license_key_time || location_usage_reason_time>src.location_usage_reason_time || build_time>src.build_time
  2231. || fb_app_id_time>src.fb_app_id_time
  2232. || cb_app_id_ios_time>src.cb_app_id_ios_time || cb_app_signature_ios_time>src.cb_app_signature_ios_time || cb_app_id_google_time>src.cb_app_id_google_time || cb_app_signature_google_time>src.cb_app_signature_google_time
  2233. || storage_time>src.storage_time || supported_orientations_time>src.supported_orientations_time
  2234. || embed_engine_data_time>src.embed_engine_data_time || publish_proj_data_time>src.publish_proj_data_time || publish_physx_dll_time>src.publish_physx_dll_time || publish_steam_dll_time>src.publish_steam_dll_time || publish_open_vr_dll_time>src.publish_open_vr_dll_time || publish_data_as_pak_time>src.publish_data_as_pak_time || android_expansion_time>src.android_expansion_time
  2235. || icon_time>src.icon_time || notification_icon_time>src.notification_icon_time || image_portrait_time>src.image_portrait_time || image_landscape_time>src.image_landscape_time || gui_skin_time>src.gui_skin_time;
  2236. }
  2237. bool ElmApp::mayContain(C UID &id)C {return id==icon || id==notification_icon || id==image_portrait || id==image_landscape || id==gui_skin;}
  2238. int ElmApp::embedEngineData( )C {return FlagTest(flag, EMBED_ENGINE_DATA) ? FlagTest(flag, EMBED_ENGINE_DATA_FULL) ? 2 : 1 : 0;}
  2239. ElmApp& ElmApp::embedEngineData(int e) { FlagSet (flag, EMBED_ENGINE_DATA, e!=0); FlagSet(flag, EMBED_ENGINE_DATA_FULL, e>1); return T;}
  2240. bool ElmApp::publishProjData()C {return FlagTest(flag, PUBLISH_PROJ_DATA );}
  2241. ElmApp& ElmApp::publishProjData(bool on) {FlagSet(flag, PUBLISH_PROJ_DATA , on); return T;}
  2242. bool ElmApp::publishPhysxDll()C {return FlagTest(flag, PUBLISH_PHYSX_DLL );}
  2243. ElmApp& ElmApp::publishPhysxDll(bool on) {FlagSet(flag, PUBLISH_PHYSX_DLL , on); return T;}
  2244. bool ElmApp::publishSteamDll()C {return FlagTest(flag, PUBLISH_STEAM_DLL );}
  2245. ElmApp& ElmApp::publishSteamDll(bool on) {FlagSet(flag, PUBLISH_STEAM_DLL , on); return T;}
  2246. bool ElmApp::publishOpenVRDll()C {return FlagTest(flag, PUBLISH_OPEN_VR_DLL);}
  2247. ElmApp& ElmApp::publishOpenVRDll(bool on) {FlagSet(flag, PUBLISH_OPEN_VR_DLL, on); return T;}
  2248. bool ElmApp::publishDataAsPak()C {return FlagTest(flag, PUBLISH_DATA_AS_PAK);}
  2249. ElmApp& ElmApp::publishDataAsPak(bool on) {FlagSet(flag, PUBLISH_DATA_AS_PAK, on); return T;}
  2250. bool ElmApp::androidExpansion()C {return FlagTest(flag, ANDROID_EXPANSION );}
  2251. ElmApp& ElmApp::androidExpansion(bool on) {FlagSet(flag, ANDROID_EXPANSION , on); return T;}
  2252. void ElmApp::newData()
  2253. {
  2254. ::ElmData::newData();
  2255. dirs_windows_time++; dirs_nonwindows_time++;
  2256. headers_windows_time++; headers_mac_time++; headers_linux_time++; headers_android_time++; headers_ios_time++;
  2257. libs_windows_time++; libs_mac_time++; libs_linux_time++; libs_android_time++; libs_ios_time++;
  2258. fb_app_id_time++;
  2259. cb_app_id_ios_time++; cb_app_signature_ios_time++; cb_app_id_google_time++; cb_app_signature_google_time++;
  2260. package_time++; android_license_key_time++; location_usage_reason_time++; build_time++; storage_time++; supported_orientations_time++;
  2261. embed_engine_data_time++; publish_proj_data_time++; publish_physx_dll_time++; publish_steam_dll_time++; publish_open_vr_dll_time++; publish_data_as_pak_time++; android_expansion_time++;
  2262. icon_time++; notification_icon_time++; image_portrait_time++; image_landscape_time++; gui_skin_time++;
  2263. }
  2264. uint ElmApp::undo(C ElmApp &src)
  2265. {
  2266. uint changed=::ElmData::undo(src);
  2267. bool ch =false;
  2268. {
  2269. ch|=Undo( dirs_windows_time, src. dirs_windows_time, dirs_windows , src.dirs_windows );
  2270. ch|=Undo( dirs_nonwindows_time, src. dirs_nonwindows_time, dirs_nonwindows , src.dirs_nonwindows );
  2271. ch|=Undo( headers_windows_time, src. headers_windows_time, headers_windows , src.headers_windows );
  2272. ch|=Undo( headers_mac_time, src. headers_mac_time, headers_mac , src.headers_mac );
  2273. ch|=Undo( headers_linux_time, src. headers_linux_time, headers_linux , src.headers_linux );
  2274. ch|=Undo( headers_android_time, src. headers_android_time, headers_android , src.headers_android );
  2275. ch|=Undo( headers_ios_time, src. headers_ios_time, headers_ios , src.headers_ios );
  2276. ch|=Undo( libs_windows_time, src. libs_windows_time, libs_windows , src.libs_windows );
  2277. ch|=Undo( libs_mac_time, src. libs_mac_time, libs_mac , src.libs_mac );
  2278. ch|=Undo( libs_linux_time, src. libs_linux_time, libs_linux , src.libs_linux );
  2279. ch|=Undo( libs_android_time, src. libs_android_time, libs_android , src.libs_android );
  2280. ch|=Undo( libs_ios_time, src. libs_ios_time, libs_ios , src.libs_ios );
  2281. ch|=Undo( package_time, src. package_time, package , src.package );
  2282. ch|=Undo( android_license_key_time, src. android_license_key_time, android_license_key , src.android_license_key );
  2283. ch|=Undo( location_usage_reason_time, src. location_usage_reason_time, location_usage_reason , src.location_usage_reason );
  2284. ch|=Undo( build_time, src. build_time, build , src.build );
  2285. ch|=Undo( storage_time, src. storage_time, storage , src.storage );
  2286. ch|=Undo( fb_app_id_time, src. fb_app_id_time, fb_app_id , src.fb_app_id );
  2287. ch|=Undo( cb_app_id_ios_time, src. cb_app_id_ios_time, cb_app_id_ios , src.cb_app_id_ios );
  2288. ch|=Undo( cb_app_signature_ios_time, src. cb_app_signature_ios_time, cb_app_signature_ios , src.cb_app_signature_ios );
  2289. ch|=Undo( cb_app_id_google_time, src. cb_app_id_google_time, cb_app_id_google , src.cb_app_id_google );
  2290. ch|=Undo(cb_app_signature_google_time, src.cb_app_signature_google_time, cb_app_signature_google, src.cb_app_signature_google);
  2291. if(Undo(embed_engine_data_time , src.embed_engine_data_time )){ch=true; embedEngineData (src.embedEngineData ());}
  2292. if(Undo(publish_proj_data_time , src.publish_proj_data_time )){ch=true; publishProjData (src.publishProjData ());}
  2293. if(Undo(publish_physx_dll_time , src.publish_physx_dll_time )){ch=true; publishPhysxDll (src.publishPhysxDll ());}
  2294. if(Undo(publish_steam_dll_time , src.publish_steam_dll_time )){ch=true; publishSteamDll (src.publishSteamDll ());}
  2295. if(Undo(publish_open_vr_dll_time, src.publish_open_vr_dll_time)){ch=true; publishOpenVRDll(src.publishOpenVRDll());}
  2296. if(Undo(publish_data_as_pak_time, src.publish_data_as_pak_time)){ch=true; publishDataAsPak(src.publishDataAsPak());}
  2297. if(Undo(android_expansion_time , src.android_expansion_time )){ch=true; androidExpansion(src.androidExpansion());}
  2298. //if(Undo(windows_code_sign_time , src.windows_code_sign_time )){ch=true; windowsCodeSign (src.windowsCodeSign ());}
  2299. }
  2300. ch|=Undo(supported_orientations_time, src.supported_orientations_time, supported_orientations, src.supported_orientations);
  2301. ch|=Undo( icon_time, src. icon_time, icon , src.icon );
  2302. ch|=Undo( notification_icon_time, src. notification_icon_time, notification_icon , src.notification_icon );
  2303. ch|=Undo( image_portrait_time, src. image_portrait_time, image_portrait , src.image_portrait );
  2304. ch|=Undo( image_landscape_time, src. image_landscape_time, image_landscape , src.image_landscape );
  2305. ch|=Undo( gui_skin_time, src. gui_skin_time, gui_skin , src.gui_skin );
  2306. changed|=ch*CHANGE_NORMAL;
  2307. if(changed)newVer();
  2308. return changed;
  2309. }
  2310. uint ElmApp::sync(C ElmApp &src, bool manual)
  2311. {
  2312. uint changed=::ElmData::sync(src);
  2313. bool ch =false;
  2314. if(manual) // these are advanced settings and can be synced only manually
  2315. {
  2316. ch|=Sync( dirs_windows_time, src. dirs_windows_time, dirs_windows , src.dirs_windows );
  2317. ch|=Sync( dirs_nonwindows_time, src. dirs_nonwindows_time, dirs_nonwindows , src.dirs_nonwindows );
  2318. ch|=Sync( headers_windows_time, src. headers_windows_time, headers_windows , src.headers_windows );
  2319. ch|=Sync( headers_mac_time, src. headers_mac_time, headers_mac , src.headers_mac );
  2320. ch|=Sync( headers_linux_time, src. headers_linux_time, headers_linux , src.headers_linux );
  2321. ch|=Sync( headers_android_time, src. headers_android_time, headers_android , src.headers_android );
  2322. ch|=Sync( headers_ios_time, src. headers_ios_time, headers_ios , src.headers_ios );
  2323. ch|=Sync( libs_windows_time, src. libs_windows_time, libs_windows , src.libs_windows );
  2324. ch|=Sync( libs_mac_time, src. libs_mac_time, libs_mac , src.libs_mac );
  2325. ch|=Sync( libs_linux_time, src. libs_linux_time, libs_linux , src.libs_linux );
  2326. ch|=Sync( libs_android_time, src. libs_android_time, libs_android , src.libs_android );
  2327. ch|=Sync( libs_ios_time, src. libs_ios_time, libs_ios , src.libs_ios );
  2328. ch|=Sync( package_time, src. package_time, package , src.package );
  2329. ch|=Sync( android_license_key_time, src. android_license_key_time, android_license_key , src.android_license_key );
  2330. ch|=Sync( location_usage_reason_time, src. location_usage_reason_time, location_usage_reason , src.location_usage_reason );
  2331. ch|=Sync( build_time, src. build_time, build , src.build );
  2332. ch|=Sync( storage_time, src. storage_time, storage , src.storage );
  2333. ch|=Sync( fb_app_id_time, src. fb_app_id_time, fb_app_id , src.fb_app_id );
  2334. ch|=Sync( cb_app_id_ios_time, src. cb_app_id_ios_time, cb_app_id_ios , src.cb_app_id_ios );
  2335. ch|=Sync( cb_app_signature_ios_time, src. cb_app_signature_ios_time, cb_app_signature_ios , src.cb_app_signature_ios );
  2336. ch|=Sync( cb_app_id_google_time, src. cb_app_id_google_time, cb_app_id_google , src.cb_app_id_google );
  2337. ch|=Sync(cb_app_signature_google_time, src.cb_app_signature_google_time, cb_app_signature_google, src.cb_app_signature_google);
  2338. if(Sync(embed_engine_data_time , src.embed_engine_data_time )){ch=true; embedEngineData (src.embedEngineData ());}
  2339. if(Sync(publish_proj_data_time , src.publish_proj_data_time )){ch=true; publishProjData (src.publishProjData ());}
  2340. if(Sync(publish_physx_dll_time , src.publish_physx_dll_time )){ch=true; publishPhysxDll (src.publishPhysxDll ());}
  2341. if(Sync(publish_steam_dll_time , src.publish_steam_dll_time )){ch=true; publishSteamDll (src.publishSteamDll ());}
  2342. if(Sync(publish_open_vr_dll_time, src.publish_open_vr_dll_time)){ch=true; publishOpenVRDll(src.publishOpenVRDll());}
  2343. if(Sync(publish_data_as_pak_time, src.publish_data_as_pak_time)){ch=true; publishDataAsPak(src.publishDataAsPak());}
  2344. if(Sync(android_expansion_time , src.android_expansion_time )){ch=true; androidExpansion(src.androidExpansion());}
  2345. //if(Sync(windows_code_sign_time , src.windows_code_sign_time )){ch=true; windowsCodeSign (src.windowsCodeSign ());}
  2346. }
  2347. ch|=Sync(supported_orientations_time, src.supported_orientations_time, supported_orientations, src.supported_orientations);
  2348. ch|=Sync( icon_time, src. icon_time, icon , src.icon );
  2349. ch|=Undo( notification_icon_time, src. notification_icon_time, notification_icon , src.notification_icon );
  2350. ch|=Sync( image_portrait_time, src. image_portrait_time, image_portrait , src.image_portrait );
  2351. ch|=Sync( image_landscape_time, src. image_landscape_time, image_landscape , src.image_landscape );
  2352. ch|=Sync( gui_skin_time, src. gui_skin_time, gui_skin , src.gui_skin );
  2353. changed|=ch*CHANGE_NORMAL;
  2354. if(equal(src))ver=src.ver;else if(changed)newVer();
  2355. return changed;
  2356. }
  2357. bool ElmApp::save(File &f)C
  2358. {
  2359. ::ElmData::save(f);
  2360. f.cmpUIntV(16);
  2361. f<<dirs_windows<<dirs_nonwindows;
  2362. f<<headers_windows<<headers_mac<<headers_linux<<headers_android<<headers_ios;
  2363. f<<libs_windows<<libs_mac<<libs_linux<<libs_android<<libs_ios;
  2364. f<<package<<android_license_key<<location_usage_reason<<build<<storage<<supported_orientations<<flag;
  2365. f<<fb_app_id;
  2366. f<<cb_app_id_ios<<cb_app_signature_ios<<cb_app_id_google<<cb_app_signature_google;
  2367. f<<icon<<notification_icon<<image_portrait<<image_landscape<<gui_skin;
  2368. f<<dirs_windows_time<<dirs_nonwindows_time;
  2369. f<<headers_windows_time<<headers_mac_time<<headers_linux_time<<headers_android_time<<headers_ios_time;
  2370. f<<libs_windows_time<<libs_mac_time<<libs_linux_time<<libs_android_time<<libs_ios_time;
  2371. f<<package_time<<android_license_key_time<<location_usage_reason_time<<build_time<<storage_time<<supported_orientations_time;
  2372. f<<fb_app_id_time;
  2373. f<<cb_app_id_ios_time<<cb_app_signature_ios_time<<cb_app_id_google_time<<cb_app_signature_google_time;
  2374. f<<embed_engine_data_time<<publish_proj_data_time<<publish_physx_dll_time<<publish_steam_dll_time<<publish_open_vr_dll_time<<publish_data_as_pak_time<<android_expansion_time;
  2375. f<<icon_time<<notification_icon_time<<image_portrait_time<<image_landscape_time<<gui_skin_time;
  2376. return f.ok();
  2377. }
  2378. bool ElmApp::load(File &f)
  2379. {
  2380. Str headers_nonwindows;
  2381. TimeStamp headers_nonwindows_time;
  2382. T=ElmApp(); // reset to default, in case this is needed (for example when loading data from reused objects for code synchronization)
  2383. if(::ElmData::load(f))switch(f.decUIntV())
  2384. {
  2385. case 16:
  2386. {
  2387. f>>dirs_windows>>dirs_nonwindows;
  2388. f>>headers_windows>>headers_mac>>headers_linux>>headers_android>>headers_ios;
  2389. f>>libs_windows>>libs_mac>>libs_linux>>libs_android>>libs_ios;
  2390. f>>package>>android_license_key>>location_usage_reason>>build>>storage>>supported_orientations>>flag;
  2391. f>>fb_app_id;
  2392. f>>cb_app_id_ios>>cb_app_signature_ios>>cb_app_id_google>>cb_app_signature_google;
  2393. f>>icon>>notification_icon>>image_portrait>>image_landscape>>gui_skin;
  2394. f>>dirs_windows_time>>dirs_nonwindows_time;
  2395. f>>headers_windows_time>>headers_mac_time>>headers_linux_time>>headers_android_time>>headers_ios_time;
  2396. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2397. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2398. f>>fb_app_id_time;
  2399. f>>cb_app_id_ios_time>>cb_app_signature_ios_time>>cb_app_id_google_time>>cb_app_signature_google_time;
  2400. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_open_vr_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2401. f>>icon_time>>notification_icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2402. if(f.ok())return true;
  2403. }break;
  2404. case 15:
  2405. {
  2406. f>>dirs_windows>>dirs_nonwindows>>headers_windows>>headers_nonwindows>>libs_windows>>libs_mac>>libs_linux>>libs_android>>libs_ios;
  2407. f>>package>>android_license_key>>location_usage_reason>>build>>storage>>supported_orientations>>flag;
  2408. f>>fb_app_id;
  2409. f>>cb_app_id_ios>>cb_app_signature_ios>>cb_app_id_google>>cb_app_signature_google;
  2410. f>>icon>>notification_icon>>image_portrait>>image_landscape>>gui_skin;
  2411. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2412. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2413. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2414. f>>fb_app_id_time;
  2415. f>>cb_app_id_ios_time>>cb_app_signature_ios_time>>cb_app_id_google_time>>cb_app_signature_google_time;
  2416. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_open_vr_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2417. f>>icon_time>>notification_icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2418. if(f.ok())return true;
  2419. }break;
  2420. case 14:
  2421. {
  2422. f>>dirs_windows>>dirs_nonwindows>>headers_windows>>headers_nonwindows>>libs_windows>>libs_mac>>libs_linux>>libs_android>>libs_ios;
  2423. f>>package>>android_license_key>>location_usage_reason>>build>>storage>>supported_orientations>>flag;
  2424. f>>fb_app_id;
  2425. f>>cb_app_id_ios>>cb_app_signature_ios>>cb_app_id_google>>cb_app_signature_google;
  2426. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2427. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2428. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2429. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2430. f>>fb_app_id_time;
  2431. f>>cb_app_id_ios_time>>cb_app_signature_ios_time>>cb_app_id_google_time>>cb_app_signature_google_time;
  2432. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_open_vr_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2433. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2434. if(f.ok())return true;
  2435. }break;
  2436. case 13:
  2437. {
  2438. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2439. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2440. f>>fb_app_id;
  2441. GetStr2(f, cb_app_id_ios); GetStr2(f, cb_app_signature_ios); GetStr2(f, cb_app_id_google); GetStr2(f, cb_app_signature_google);
  2442. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2443. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2444. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2445. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2446. f>>fb_app_id_time;
  2447. f>>cb_app_id_ios_time>>cb_app_signature_ios_time>>cb_app_id_google_time>>cb_app_signature_google_time;
  2448. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_open_vr_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2449. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2450. if(f.ok())return true;
  2451. }break;
  2452. case 12:
  2453. {
  2454. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2455. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2456. f>>fb_app_id;
  2457. GetStr2(f, cb_app_id_ios); GetStr2(f, cb_app_signature_ios); GetStr2(f, cb_app_id_google); GetStr2(f, cb_app_signature_google);
  2458. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2459. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2460. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2461. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2462. f>>fb_app_id_time;
  2463. f>>cb_app_id_ios_time>>cb_app_signature_ios_time>>cb_app_id_google_time>>cb_app_signature_google_time;
  2464. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2465. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2466. if(f.ok())return true;
  2467. }break;
  2468. case 11:
  2469. {
  2470. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2471. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2472. f>>fb_app_id; GetStr2(f, cb_app_id_ios); GetStr2(f, cb_app_signature_ios);
  2473. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2474. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2475. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2476. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2477. f>>fb_app_id_time>>cb_app_id_ios_time>>cb_app_signature_ios_time;
  2478. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2479. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2480. if(f.ok())return true;
  2481. }break;
  2482. case 10:
  2483. {
  2484. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2485. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2486. f>>fb_app_id;
  2487. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2488. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2489. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2490. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2491. f>>fb_app_id_time;
  2492. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_steam_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2493. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2494. if(f.ok())return true;
  2495. }break;
  2496. case 9:
  2497. {
  2498. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2499. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2500. f>>fb_app_id;
  2501. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2502. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2503. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2504. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2505. f>>fb_app_id_time;
  2506. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time>>android_expansion_time;
  2507. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2508. if(f.ok())return true;
  2509. }break;
  2510. case 8:
  2511. {
  2512. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2513. GetStr2(f, package); GetStr2(f, android_license_key); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2514. f>>fb_app_id;
  2515. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2516. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2517. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2518. f>>package_time>>android_license_key_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2519. f>>fb_app_id_time;
  2520. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time;
  2521. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2522. if(f.ok())return true;
  2523. }break;
  2524. case 7:
  2525. {
  2526. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2527. GetStr2(f, package); GetStr2(f, location_usage_reason); f>>build>>storage>>supported_orientations>>flag;
  2528. f>>fb_app_id;
  2529. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2530. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2531. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2532. f>>package_time>>location_usage_reason_time>>build_time>>storage_time>>supported_orientations_time;
  2533. f>>fb_app_id_time;
  2534. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time;
  2535. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2536. if(f.ok())return true;
  2537. }break;
  2538. case 6:
  2539. {
  2540. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2541. GetStr2(f, package); f>>build>>storage>>supported_orientations>>flag;
  2542. f>>fb_app_id;
  2543. f>>icon>>image_portrait>>image_landscape>>gui_skin;
  2544. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2545. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2546. f>>package_time>>build_time>>storage_time>>supported_orientations_time;
  2547. f>>fb_app_id_time;
  2548. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time;
  2549. f>>icon_time>>image_portrait_time>>image_landscape_time>>gui_skin_time;
  2550. if(f.ok())return true;
  2551. }break;
  2552. case 5:
  2553. {
  2554. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios);
  2555. GetStr2(f, package); f>>build>>storage>>supported_orientations>>flag;
  2556. f>>fb_app_id; GetStr2(f);
  2557. f>>icon>>image_portrait>>image_landscape;
  2558. f>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2559. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2560. f>>package_time>>build_time>>storage_time>>supported_orientations_time;
  2561. f>>fb_app_id_time; TimeStamp ts; f>>ts;
  2562. f>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time;
  2563. f>>icon_time>>image_portrait_time>>image_landscape_time;
  2564. if(f.ok())return true;
  2565. }break;
  2566. case 4:
  2567. {
  2568. GetStr2(f, dirs_windows); GetStr2(f, dirs_nonwindows); GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios); GetStr2(f, package);
  2569. f>>build>>storage>>supported_orientations>>flag>>icon>>image_portrait>>image_landscape>>dirs_windows_time>>dirs_nonwindows_time>>headers_windows_time>>headers_nonwindows_time;
  2570. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2571. f>>package_time>>build_time>>storage_time>>supported_orientations_time>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time>>icon_time>>image_portrait_time>>image_landscape_time;
  2572. if(f.ok())return true;
  2573. }break;
  2574. case 3:
  2575. {
  2576. GetStr2(f, headers_windows); GetStr2(f, headers_nonwindows); GetStr2(f, libs_windows); GetStr2(f, libs_mac); GetStr2(f, libs_linux); GetStr2(f, libs_android); GetStr2(f, libs_ios); GetStr2(f, package);
  2577. f>>build>>storage>>supported_orientations>>flag>>icon>>image_portrait>>image_landscape>>headers_windows_time>>headers_nonwindows_time;
  2578. f>>libs_windows_time>>libs_mac_time>>libs_linux_time>>libs_android_time>>libs_ios_time;
  2579. f>>package_time>>build_time>>storage_time>>supported_orientations_time>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time>>icon_time>>image_portrait_time>>image_landscape_time;
  2580. if(f.ok())return true;
  2581. }break;
  2582. case 2:
  2583. {
  2584. GetStr(f, headers_windows); GetStr(f, libs_windows); GetStr(f, package); f>>build>>storage>>supported_orientations>>flag>>icon>>image_portrait>>image_landscape>>headers_windows_time>>libs_windows_time>>package_time>>build_time>>storage_time>>supported_orientations_time>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time>>icon_time>>image_portrait_time>>image_landscape_time;
  2585. if(f.ok())return true;
  2586. }break;
  2587. case 1:
  2588. {
  2589. GetStr(f, headers_windows); GetStr(f, libs_windows); GetStr(f, package); f>>build>>storage>>supported_orientations>>flag>>icon>>image_portrait>>headers_windows_time>>libs_windows_time>>package_time>>build_time>>storage_time>>supported_orientations_time>>embed_engine_data_time>>publish_proj_data_time>>publish_physx_dll_time>>publish_data_as_pak_time>>icon_time>>image_portrait_time;
  2590. if(f.ok())return true;
  2591. }break;
  2592. case 0:
  2593. {
  2594. bool embed_engine_data;
  2595. GetStr(f, headers_windows); GetStr(f, libs_windows); GetStr(f, package); f>>build>>storage>>supported_orientations>>embed_engine_data>>icon>>image_portrait>>headers_windows_time>>libs_windows_time>>package_time>>build_time>>storage_time>>supported_orientations_time>>embed_engine_data_time>>icon_time>>image_portrait_time;
  2596. embedEngineData(embed_engine_data).publishProjData(true).publishPhysxDll(true).publishDataAsPak(true).androidExpansion(false); // set non-saved options
  2597. if(f.ok())return true;
  2598. }break;
  2599. }
  2600. return false;
  2601. }
  2602. void ElmApp::save(MemPtr<TextNode> nodes)C
  2603. {
  2604. ::ElmData::save(nodes);
  2605. nodes.New().set("Build" , build);
  2606. if(package.is())nodes.New().set("Package", package);
  2607. if(icon .valid())nodes.New().setFN("Icon" , icon);
  2608. if(notification_icon.valid())nodes.New().setFN("NotificationIcon", notification_icon);
  2609. if(image_portrait .valid())nodes.New().setFN("SplashPortrait" , image_portrait);
  2610. if(image_landscape .valid())nodes.New().setFN("SplashLandscape" , image_landscape);
  2611. if(gui_skin .valid())nodes.New().setFN("GuiSkin" , gui_skin);
  2612. if( embedEngineData ())nodes.New().set("EmbedEngineData" , embedEngineData ());
  2613. if(!publishProjData ())nodes.New().set("PublishProjectData", publishProjData ());
  2614. if(!publishDataAsPak())nodes.New().set("PublishDataAsPAK" , publishDataAsPak());
  2615. nodes.New().set("PublishPhysXDLL" , publishPhysxDll ());
  2616. if( publishSteamDll ())nodes.New().set("PublishSteamDLL" );
  2617. if( publishOpenVRDll())nodes.New().set("PublishOpenVRDLL");
  2618. if( dirs_windows .is())nodes.New().set("IncludePathsWindows" , dirs_windows);
  2619. if( dirs_nonwindows.is())nodes.New().set("IncludePathsNonWindows" , dirs_nonwindows);
  2620. if(headers_windows .is())nodes.New().set("IncludeHeadersWindows" , headers_windows);
  2621. if(headers_mac .is())nodes.New().set("IncludeHeadersMac" , headers_mac);
  2622. if(headers_linux .is())nodes.New().set("IncludeHeadersLinux" , headers_linux);
  2623. if(headers_android .is())nodes.New().set("IncludeHeadersAndroid" , headers_android);
  2624. if(headers_ios .is())nodes.New().set("IncludeHeadersiOS" , headers_ios);
  2625. if( libs_windows .is())nodes.New().set("IncludeLibrariesWindows" , libs_windows);
  2626. if( libs_mac .is())nodes.New().set("IncludeLibrariesMac" , libs_mac);
  2627. if( libs_linux .is())nodes.New().set("IncludeLibrariesLinux" , libs_linux);
  2628. if( libs_android .is())nodes.New().set("IncludeLibrariesAndroid" , libs_android);
  2629. if( libs_ios .is())nodes.New().set("IncludeLibrariesiOS" , libs_ios);
  2630. REPA(StorageModes)if(storage==StorageModes[i].mode){nodes.New().set("Storage", StorageModes[i].name); break;}
  2631. nodes.New().set("SupportedOrientations", supported_orientations);
  2632. if(location_usage_reason.is())nodes.New().set("LocationUsageReason" , location_usage_reason);
  2633. if(androidExpansion ())nodes.New().set("AndroidExpansion" );
  2634. if(android_license_key .is())nodes.New().set("AndroidLicenseKey" , android_license_key);
  2635. if(fb_app_id)nodes.New().set("FacebookAppID", fb_app_id);
  2636. {
  2637. TextNode &cb=nodes.New().setName("Chartboost");
  2638. if(cb_app_id_ios .is())cb.nodes.New().set("AppIDiOS" , cb_app_id_ios);
  2639. if(cb_app_signature_ios .is())cb.nodes.New().set("AppSignatureiOS" , cb_app_signature_ios);
  2640. if(cb_app_id_google .is())cb.nodes.New().set("AppIDGoogle" , cb_app_id_google);
  2641. if(cb_app_signature_google.is())cb.nodes.New().set("AppSignatureGoogle", cb_app_signature_google);
  2642. cb.nodes.New().set("AppIDiOSTime" , cb_app_id_ios_time.text());
  2643. cb.nodes.New().set("AppSignatureiOSTime" , cb_app_signature_ios_time.text());
  2644. cb.nodes.New().set("AppIDGoogleTime" , cb_app_id_google_time.text());
  2645. cb.nodes.New().set("AppSignatureGoogleTime", cb_app_signature_google_time.text());
  2646. }
  2647. nodes.New().set("BuildTime" , build_time.text());
  2648. nodes.New().set("PackageTime", package_time.text());
  2649. nodes.New().set("IconTime" , icon_time.text());
  2650. nodes.New().set("NotificationIconTime", notification_icon_time.text());
  2651. nodes.New().set("SplashPortraitTime" , image_portrait_time.text());
  2652. nodes.New().set("SplashLandscapeTime" , image_landscape_time.text());
  2653. nodes.New().set("GuiSkinTime" , gui_skin_time.text());
  2654. nodes.New().set("EmbedEngineDataTime" , embed_engine_data_time .text());
  2655. nodes.New().set("PublishProjectDataTime", publish_proj_data_time .text());
  2656. nodes.New().set("PublishDataAsPAKTime" , publish_data_as_pak_time.text());
  2657. nodes.New().set("PublishPhysXDLLTime" , publish_physx_dll_time .text());
  2658. nodes.New().set("PublishSteamDLLTime" , publish_steam_dll_time .text());
  2659. nodes.New().set("PublishOpenVRDLLTime" , publish_open_vr_dll_time.text());
  2660. nodes.New().set("IncludePathsWindowsTime" , dirs_windows_time.text());
  2661. nodes.New().set("IncludePathsNonWindowsTime" , dirs_nonwindows_time.text());
  2662. nodes.New().set("IncludeHeadersWindowsTime" , headers_windows_time.text());
  2663. nodes.New().set("IncludeHeadersMacTime" , headers_mac_time.text());
  2664. nodes.New().set("IncludeHeadersLinuxTime" , headers_linux_time.text());
  2665. nodes.New().set("IncludeHeadersAndroidTime" , headers_android_time.text());
  2666. nodes.New().set("IncludeHeadersiOSTime" , headers_ios_time.text());
  2667. nodes.New().set("IncludeLibrariesWindowsTime" , libs_windows_time.text());
  2668. nodes.New().set("IncludeLibrariesMacTime" , libs_mac_time.text());
  2669. nodes.New().set("IncludeLibrariesLinuxTime" , libs_linux_time.text());
  2670. nodes.New().set("IncludeLibrariesAndroidTime" , libs_android_time.text());
  2671. nodes.New().set("IncludeLibrariesiOSTime" , libs_ios_time.text());
  2672. nodes.New().set("StorageTime" , storage_time.text());
  2673. nodes.New().set("SupportedOrientationsTime", supported_orientations_time.text());
  2674. nodes.New().set("LocationUsageReasonTime" , location_usage_reason_time.text());
  2675. nodes.New().set("AndroidExpansionTime" , android_expansion_time.text());
  2676. nodes.New().set("AndroidLicenseKeyTime" , android_license_key_time.text());
  2677. nodes.New().set("FacebookAppIDTime", fb_app_id_time.text());
  2678. }
  2679. void ElmApp::load(C MemPtr<TextNode> &nodes)
  2680. {
  2681. ::ElmData::load(nodes);
  2682. REPA(nodes)
  2683. {
  2684. C TextNode &n=nodes[i];
  2685. if(n.name=="Build" )n.getValue(build );else
  2686. if(n.name=="Package" )n.getValue(package);else
  2687. if(n.name=="Icon" )n.getValue(icon );else
  2688. if(n.name=="NotificationIcon" )n.getValue(notification_icon);else
  2689. if(n.name=="SplashPortrait" )n.getValue(image_portrait );else
  2690. if(n.name=="SplashLandscape" )n.getValue(image_landscape );else
  2691. if(n.name=="GuiSkin" )n.getValue(gui_skin );else
  2692. if(n.name=="EmbedEngineData" )embedEngineData (n.value.is() ? n.asInt() : true);else
  2693. if(n.name=="PublishProjectData" )publishProjData (n.asBool1());else
  2694. if(n.name=="PublishDataAsPAK" )publishDataAsPak(n.asBool1());else
  2695. if(n.name=="PublishPhysXDLL" )publishPhysxDll (n.asBool1());else
  2696. if(n.name=="PublishSteamDLL" )publishSteamDll (n.asBool1());else
  2697. if(n.name=="PublishOpenVRDLL" )publishOpenVRDll(n.asBool1());else
  2698. if(n.name=="IncludePathsWindows" )n.getValue( dirs_windows );else
  2699. if(n.name=="IncludePathsNonWindows" )n.getValue( dirs_nonwindows);else
  2700. if(n.name=="IncludeHeadersWindows" )n.getValue(headers_windows );else
  2701. if(n.name=="IncludeHeadersMac" )n.getValue(headers_mac );else
  2702. if(n.name=="IncludeHeadersLinux" )n.getValue(headers_linux );else
  2703. if(n.name=="IncludeHeadersAndroid" )n.getValue(headers_android );else
  2704. if(n.name=="IncludeHeadersiOS" )n.getValue(headers_ios );else
  2705. if(n.name=="IncludeLibrariesWindows" )n.getValue( libs_windows );else
  2706. if(n.name=="IncludeLibrariesMac" )n.getValue( libs_mac );else
  2707. if(n.name=="IncludeLibrariesLinux" )n.getValue( libs_linux );else
  2708. if(n.name=="IncludeLibrariesAndroid" )n.getValue( libs_android );else
  2709. if(n.name=="IncludeLibrariesiOS" )n.getValue( libs_ios );else
  2710. if(n.name=="Storage" ){REPA(StorageModes)if(n.value==StorageModes[i].name){storage=StorageModes[i].mode; break;}}else
  2711. if(n.name=="SupportedOrientations" )supported_orientations=n.asInt();else
  2712. if(n.name=="LocationUsageReason" )n.getValue(location_usage_reason);else
  2713. if(n.name=="AndroidExpansion" )androidExpansion(n.asBool1());else
  2714. if(n.name=="AndroidLicenseKey" )n.getValue(android_license_key);else
  2715. if(n.name=="FacebookAppID" )n.getValue(fb_app_id);else
  2716. if(n.name=="Chartboost" )
  2717. {
  2718. REPA(n.nodes)
  2719. {
  2720. C TextNode &cb=n.nodes[i];
  2721. if(cb.name=="AppIDiOS" )cb.getValue(cb_app_id_ios );else
  2722. if(cb.name=="AppSignatureiOS" )cb.getValue(cb_app_signature_ios );else
  2723. if(cb.name=="AppIDGoogle" )cb.getValue(cb_app_id_google );else
  2724. if(cb.name=="AppSignatureGoogle" )cb.getValue(cb_app_signature_google);else
  2725. if(cb.name=="AppIDiOSTime" )cb_app_id_ios_time =cb.asText();else
  2726. if(cb.name=="AppSignatureiOSTime" )cb_app_signature_ios_time =cb.asText();else
  2727. if(cb.name=="AppIDGoogleTime" )cb_app_id_google_time =cb.asText();else
  2728. if(cb.name=="AppSignatureGoogleTime")cb_app_signature_google_time=cb.asText();
  2729. }
  2730. }else
  2731. if(n.name=="BuildTime" )build_time=n.asText();else
  2732. if(n.name=="PackageTime")package_time=n.asText();else
  2733. if(n.name=="IconTime" )icon_time=n.asText();else
  2734. if(n.name=="NotificationIconTime")notification_icon_time=n.asText();else
  2735. if(n.name=="SplashPortraitTime" )image_portrait_time=n.asText();else
  2736. if(n.name=="SplashLandscapeTime" )image_landscape_time=n.asText();else
  2737. if(n.name=="GuiSkinTime" )gui_skin_time=n.asText();else
  2738. if(n.name=="EmbedEngineDataTime" )embed_engine_data_time =n.asText();else
  2739. if(n.name=="PublishProjectDataTime")publish_proj_data_time =n.asText();else
  2740. if(n.name=="PublishDataAsPAKTime" )publish_data_as_pak_time=n.asText();else
  2741. if(n.name=="PublishPhysXDLLTime" )publish_physx_dll_time =n.asText();else
  2742. if(n.name=="PublishSteamDLLTime" )publish_steam_dll_time =n.asText();else
  2743. if(n.name=="PublishOpenVRDLLTime" )publish_open_vr_dll_time=n.asText();else
  2744. if(n.name=="IncludePathsWindowsTime" )dirs_windows_time=n.asText();else
  2745. if(n.name=="IncludePathsNonWindowsTime" )dirs_nonwindows_time=n.asText();else
  2746. if(n.name=="IncludeHeadersWindowsTime" )headers_windows_time=n.asText();else
  2747. if(n.name=="IncludeHeadersMacTime" )headers_mac_time=n.asText();else
  2748. if(n.name=="IncludeHeadersLinuxTime" )headers_linux_time=n.asText();else
  2749. if(n.name=="IncludeHeadersAndroidTime" )headers_android_time=n.asText();else
  2750. if(n.name=="IncludeHeadersiOSTime" )headers_ios_time=n.asText();else
  2751. if(n.name=="IncludeLibrariesWindowsTime" )libs_windows_time=n.asText();else
  2752. if(n.name=="IncludeLibrariesMacTime" )libs_mac_time=n.asText();else
  2753. if(n.name=="IncludeLibrariesLinuxTime" )libs_linux_time=n.asText();else
  2754. if(n.name=="IncludeLibrariesAndroidTime" )libs_android_time=n.asText();else
  2755. if(n.name=="IncludeLibrariesiOSTime" )libs_ios_time=n.asText();else
  2756. if(n.name=="StorageTime" )storage_time=n.asText();else
  2757. if(n.name=="SupportedOrientationsTime")supported_orientations_time=n.asText();else
  2758. if(n.name=="LocationUsageReasonTime" )location_usage_reason_time=n.asText();else
  2759. if(n.name=="AndroidExpansionTime" )android_expansion_time=n.asText();else
  2760. if(n.name=="AndroidLicenseKeyTime" )android_license_key_time=n.asText();else
  2761. if(n.name=="FacebookAppIDTime")fb_app_id_time=n.asText();
  2762. }
  2763. }
  2764. bool ElmMiniMap::equal(C ElmMiniMap &src)C {return ::ElmData::equal(src) && areas_per_image_time==src.areas_per_image_time && image_size_time==src.image_size_time && world_time==src.world_time && env_time==src.env_time;}
  2765. bool ElmMiniMap::newer(C ElmMiniMap &src)C {return ::ElmData::newer(src) || areas_per_image_time> src.areas_per_image_time || image_size_time> src.image_size_time || world_time> src.world_time || env_time> src.env_time;}
  2766. bool ElmMiniMap::mayContain(C UID &id)C {return id==world_id || id==env_id;}
  2767. void ElmMiniMap::newData(){::ElmData::newData(); areas_per_image_time++; image_size_time++; world_time++; env_time++;}
  2768. uint ElmMiniMap::undo(C ElmMiniMap &src)
  2769. {
  2770. uint changed=::ElmData::undo(src);
  2771. changed|=Undo(areas_per_image_time, src.areas_per_image_time, areas_per_image, src.areas_per_image)*CHANGE_AFFECT_FILE;
  2772. changed|=Undo( image_size_time, src. image_size_time, image_size, src. image_size)*CHANGE_AFFECT_FILE;
  2773. changed|=Undo( world_time, src. world_time, world_id, src. world_id)*CHANGE_AFFECT_FILE;
  2774. changed|=Undo( env_time, src. env_time, env_id, src. env_id)*CHANGE_AFFECT_FILE;
  2775. if(changed)newVer();
  2776. return changed;
  2777. }
  2778. uint ElmMiniMap::sync(C ElmMiniMap &src)
  2779. {
  2780. uint changed=::ElmData::sync(src);
  2781. changed|=Sync(areas_per_image_time, src.areas_per_image_time, areas_per_image, src.areas_per_image)*CHANGE_AFFECT_FILE;
  2782. changed|=Sync( image_size_time, src. image_size_time, image_size, src. image_size)*CHANGE_AFFECT_FILE;
  2783. changed|=Sync( world_time, src. world_time, world_id, src. world_id)*CHANGE_AFFECT_FILE;
  2784. changed|=Sync( env_time, src. env_time, env_id, src. env_id)*CHANGE_AFFECT_FILE;
  2785. if(equal(src))ver=src.ver;else if(changed)newVer();
  2786. return changed;
  2787. }
  2788. void ElmMiniMap::copyTo(Game::MiniMap::Settings &settings)C
  2789. {
  2790. settings.image_size =image_size;
  2791. settings.areas_per_image=areas_per_image;
  2792. }
  2793. bool ElmMiniMap::save(File &f)C
  2794. {
  2795. ::ElmData::save(f);
  2796. f.cmpUIntV(0);
  2797. f<<areas_per_image<<image_size<<world_id<<env_id<<areas_per_image_time<<image_size_time<<world_time<<env_time;
  2798. return f.ok();
  2799. }
  2800. bool ElmMiniMap::load(File &f)
  2801. {
  2802. if(::ElmData::load(f))switch(f.decUIntV())
  2803. {
  2804. case 0:
  2805. {
  2806. f>>areas_per_image>>image_size>>world_id>>env_id>>areas_per_image_time>>image_size_time>>world_time>>env_time;
  2807. if(f.ok())return true;
  2808. }break;
  2809. }
  2810. return false;
  2811. }
  2812. void ElmMiniMap::save(MemPtr<TextNode> nodes)C
  2813. {
  2814. ::ElmData::save(nodes);
  2815. nodes.New().set ("AreasPerImage" , areas_per_image);
  2816. nodes.New().set ("ImageSize" , image_size);
  2817. if(world_id.valid())nodes.New().setFN("World" , world_id);
  2818. if( env_id.valid())nodes.New().setFN("Environment" , env_id);
  2819. nodes.New().set ("AreasPerImageTime", areas_per_image_time.text());
  2820. nodes.New().set ("ImageSizeTime" , image_size_time.text());
  2821. nodes.New().set ("WorldTime" , world_time.text());
  2822. nodes.New().set ("EnvironmentTime" , env_time.text());
  2823. }
  2824. void ElmMiniMap::load(C MemPtr<TextNode> &nodes)
  2825. {
  2826. ::ElmData::load(nodes);
  2827. REPA(nodes)
  2828. {
  2829. C TextNode &n=nodes[i];
  2830. if(n.name=="AreasPerImage" )n.getValue(areas_per_image);else
  2831. if(n.name=="ImageSize" )n.getValue(image_size);else
  2832. if(n.name=="World" )n.getValue(world_id);else
  2833. if(n.name=="Environment" )n.getValue( env_id);else
  2834. if(n.name=="AreasPerImageTime")areas_per_image_time=n.asText();else
  2835. if(n.name=="ImageSizeTime" ) image_size_time=n.asText();else
  2836. if(n.name=="WorldTime" ) world_time=n.asText();else
  2837. if(n.name=="EnvironmentTime" ) env_time=n.asText();
  2838. }
  2839. }
  2840. Elm::~Elm() {Delete(data);}
  2841. Elm& Elm::copyParams(C Elm &src, bool set_parent) // copy parameters from 'src', 'type' must be already specified, doesn't copy ID
  2842. {
  2843. if(this!=&src && type==src.type)
  2844. {
  2845. Delete(data);
  2846. flag=src.flag;
  2847. name=src.name;
  2848. name_time=src. name_time;
  2849. removed_time=src. removed_time;
  2850. no_publish_time=src.no_publish_time;
  2851. if(set_parent)
  2852. {
  2853. parent_id =src.parent_id;
  2854. parent_time=src.parent_time;
  2855. }
  2856. // copy data
  2857. if(!src.data)Delete(data);else // if source has no data then delete it
  2858. if(ElmData *data=Data()) // if created data then copy it
  2859. {
  2860. switch(type)
  2861. {
  2862. case ELM_OBJ_CLASS : * objClassData()=*src. objClassData(); break;
  2863. case ELM_OBJ : * objData()=*src. objData(); break;
  2864. case ELM_MESH : * meshData()=*src. meshData(); break;
  2865. case ELM_MTRL : * mtrlData()=*src. mtrlData(); break;
  2866. case ELM_WATER_MTRL : * waterMtrlData()=*src. waterMtrlData(); break;
  2867. case ELM_PHYS_MTRL : * physMtrlData()=*src. physMtrlData(); break;
  2868. case ELM_SKEL : * skelData()=*src. skelData(); break;
  2869. case ELM_PHYS : * physData()=*src. physData(); break;
  2870. case ELM_ANIM : * animData()=*src. animData(); break;
  2871. case ELM_PANEL_IMAGE: *panelImageData()=*src.panelImageData(); break;
  2872. case ELM_ENV : * envData()=*src. envData(); break;
  2873. case ELM_WORLD : * worldData()=*src. worldData(); break;
  2874. case ELM_MINI_MAP : * miniMapData()=*src. miniMapData(); break;
  2875. case ELM_ENUM : * enumData()=*src. enumData(); break;
  2876. case ELM_IMAGE : * imageData()=*src. imageData(); break;
  2877. case ELM_IMAGE_ATLAS: *imageAtlasData()=*src.imageAtlasData(); break;
  2878. case ELM_ICON_SETTS : * iconSettsData()=*src. iconSettsData(); break;
  2879. case ELM_ICON : * iconData()=*src. iconData(); break;
  2880. case ELM_FONT : * fontData()=*src. fontData(); break;
  2881. case ELM_TEXT_STYLE : * textStyleData()=*src. textStyleData(); break;
  2882. case ELM_PANEL : * panelData()=*src. panelData(); break;
  2883. case ELM_GUI_SKIN : * guiSkinData()=*src. guiSkinData(); break;
  2884. case ELM_GUI : * guiData()=*src. guiData(); break;
  2885. case ELM_SOUND : * soundData()=*src. soundData(); break;
  2886. case ELM_VIDEO : * videoData()=*src. videoData(); break;
  2887. case ELM_FILE : * fileData()=*src. fileData(); break;
  2888. case ELM_CODE : * codeData()=*src. codeData(); break;
  2889. case ELM_APP : * appData()=*src. appData(); break;
  2890. }
  2891. if(id!=src.id)data->clearLinked(); // if we're copying as a different object (duplicating) then we need to clear linked
  2892. }
  2893. }
  2894. return T;
  2895. }
  2896. void Elm::operator=(C Elm &src)
  2897. {
  2898. // set values before calling 'copyParams'
  2899. id =src.id;
  2900. type=src.type;
  2901. copyParams(src);
  2902. }
  2903. Elm::Elm(C Elm &src) : type(ELM_NONE), flag(0), file_size(-1), id(UID().randomizeValid()), parent_id(UIDZero), data(null) {T=src;}
  2904. bool Elm::importing()C {return FlagTest(flag, IMPORTING );}
  2905. Elm& Elm::importing(bool on) {FlagSet(flag, IMPORTING , on); return T;}
  2906. bool Elm::opened()C {return FlagTest(flag, OPENED );}
  2907. Elm& Elm::opened(bool on) {FlagSet(flag, OPENED , on); return T;}
  2908. bool Elm::removed()C {return FlagTest(flag, REMOVED );}
  2909. Elm& Elm::removed(bool on) {FlagSet(flag, REMOVED , on); return T;}
  2910. bool Elm::publish()C {return !FlagTest(flag, NO_PUBLISH );}
  2911. Elm& Elm::publish(bool on) {FlagSet(flag, NO_PUBLISH , !on); return T;}
  2912. bool Elm::noPublish()C {return FlagTest(flag, NO_PUBLISH );}
  2913. Elm& Elm::noPublish(bool on) {FlagSet(flag, NO_PUBLISH , on); return T;}
  2914. bool Elm::finalRemoved()C {return FlagTest(flag, FINAL_REMOVED );}
  2915. Elm& Elm::finalRemoved(bool on) {FlagSet(flag, FINAL_REMOVED , on); return T;}
  2916. bool Elm::finalExists()C {return !FlagTest(flag, FINAL_REMOVED );}
  2917. Elm& Elm::finalExists(bool on) {FlagSet(flag, FINAL_REMOVED , !on); return T;}
  2918. bool Elm::finalPublish()C {return !FlagTest(flag, FINAL_NO_PUBLISH);}
  2919. Elm& Elm::finalPublish(bool on) {FlagSet(flag, FINAL_NO_PUBLISH, !on); return T;}
  2920. bool Elm::finalNoPublish()C {return FlagTest(flag, FINAL_NO_PUBLISH);}
  2921. Elm& Elm::finalNoPublish(bool on) {FlagSet(flag, FINAL_NO_PUBLISH, on); return T;}
  2922. C Str& Elm::srcFile()C {return data ? data->src_file : S;}
  2923. bool Elm::initialized()C {return data && data->ver;}
  2924. void Elm::resetFinal() {FlagEnable(flag, FINAL_REMOVED|FINAL_NO_PUBLISH);}
  2925. Elm& Elm::setRemoved( bool removed , C TimeStamp &time) {T.removed (removed ); T. removed_time=time; return T;}
  2926. Elm& Elm::setNoPublish( bool no_publish, C TimeStamp &time) {T.noPublish(no_publish); T.no_publish_time=time; return T;}
  2927. Elm& Elm::setName(C Str &name , C TimeStamp &time) {T.name =name ; T. name_time=time; return T;}
  2928. Elm& Elm::setParent(C UID &parent_id , C TimeStamp &time) {T.parent_id=parent_id ; T. parent_time=time; return T;}
  2929. Elm& Elm::setParent(C Elm *parent , C TimeStamp &time) {return setParent(parent ? parent->id : UIDZero, time);}
  2930. Elm& Elm::setSrcFile(C Str &src_file , C TimeStamp &time) {if(ElmData *data=Data()){data->setSrcFile(src_file, time); data->newVer();} return T;}
  2931. ElmObjClass * Elm::objClassData() {if(type==ELM_OBJ_CLASS ){if(!data)data=new ElmObjClass ; return CAST(ElmObjClass , data);} return null;}
  2932. C ElmObjClass * Elm::objClassData()C {return (type==ELM_OBJ_CLASS ) ? CAST(ElmObjClass , data) : null;}
  2933. ElmObj * Elm::objData() {if(type==ELM_OBJ ){if(!data)data=new ElmObj ; return CAST(ElmObj , data);} return null;}
  2934. C ElmObj * Elm::objData()C {return (type==ELM_OBJ ) ? CAST(ElmObj , data) : null;}
  2935. ElmMesh * Elm::meshData() {if(type==ELM_MESH ){if(!data)data=new ElmMesh ; return CAST(ElmMesh , data);} return null;}
  2936. C ElmMesh * Elm::meshData()C {return (type==ELM_MESH ) ? CAST(ElmMesh , data) : null;}
  2937. ElmMaterial * Elm::mtrlData() {if(type==ELM_MTRL ){if(!data)data=new ElmMaterial ; return CAST(ElmMaterial , data);} return null;}
  2938. C ElmMaterial * Elm::mtrlData()C {return (type==ELM_MTRL ) ? CAST(ElmMaterial , data) : null;}
  2939. ElmWaterMtrl * Elm::waterMtrlData() {if(type==ELM_WATER_MTRL ){if(!data)data=new ElmWaterMtrl ; return CAST(ElmWaterMtrl , data);} return null;}
  2940. C ElmWaterMtrl * Elm::waterMtrlData()C {return (type==ELM_WATER_MTRL ) ? CAST(ElmWaterMtrl , data) : null;}
  2941. ElmPhysMtrl * Elm::physMtrlData() {if(type==ELM_PHYS_MTRL ){if(!data)data=new ElmPhysMtrl ; return CAST(ElmPhysMtrl , data);} return null;}
  2942. C ElmPhysMtrl * Elm::physMtrlData()C {return (type==ELM_PHYS_MTRL ) ? CAST(ElmPhysMtrl , data) : null;}
  2943. ElmSkel * Elm::skelData() {if(type==ELM_SKEL ){if(!data)data=new ElmSkel ; return CAST(ElmSkel , data);} return null;}
  2944. C ElmSkel * Elm::skelData()C {return (type==ELM_SKEL ) ? CAST(ElmSkel , data) : null;}
  2945. ElmPhys * Elm::physData() {if(type==ELM_PHYS ){if(!data)data=new ElmPhys ; return CAST(ElmPhys , data);} return null;}
  2946. C ElmPhys * Elm::physData()C {return (type==ELM_PHYS ) ? CAST(ElmPhys , data) : null;}
  2947. ElmAnim * Elm::animData() {if(type==ELM_ANIM ){if(!data)data=new ElmAnim ; return CAST(ElmAnim , data);} return null;}
  2948. C ElmAnim * Elm::animData()C {return (type==ELM_ANIM ) ? CAST(ElmAnim , data) : null;}
  2949. ElmPanelImage* Elm::panelImageData() {if(type==ELM_PANEL_IMAGE){if(!data)data=new ElmPanelImage; return CAST(ElmPanelImage, data);} return null;}
  2950. C ElmPanelImage* Elm::panelImageData()C {return (type==ELM_PANEL_IMAGE) ? CAST(ElmPanelImage, data) : null;}
  2951. ElmEnv * Elm::envData() {if(type==ELM_ENV ){if(!data)data=new ElmEnv ; return CAST(ElmEnv , data);} return null;}
  2952. C ElmEnv * Elm::envData()C {return (type==ELM_ENV ) ? CAST(ElmEnv , data) : null;}
  2953. ElmWorld * Elm::worldData() {if(type==ELM_WORLD ){if(!data)data=new ElmWorld ; return CAST(ElmWorld , data);} return null;}
  2954. C ElmWorld * Elm::worldData()C {return (type==ELM_WORLD ) ? CAST(ElmWorld , data) : null;}
  2955. ElmMiniMap * Elm::miniMapData() {if(type==ELM_MINI_MAP ){if(!data)data=new ElmMiniMap ; return CAST(ElmMiniMap , data);} return null;}
  2956. C ElmMiniMap * Elm::miniMapData()C {return (type==ELM_MINI_MAP ) ? CAST(ElmMiniMap , data) : null;}
  2957. ElmEnum * Elm::enumData() {if(type==ELM_ENUM ){if(!data)data=new ElmEnum ; return CAST(ElmEnum , data);} return null;}
  2958. C ElmEnum * Elm::enumData()C {return (type==ELM_ENUM ) ? CAST(ElmEnum , data) : null;}
  2959. ElmImage * Elm::imageData() {if(type==ELM_IMAGE ){if(!data)data=new ElmImage ; return CAST(ElmImage , data);} return null;}
  2960. C ElmImage * Elm::imageData()C {return (type==ELM_IMAGE ) ? CAST(ElmImage , data) : null;}
  2961. ElmImageAtlas* Elm::imageAtlasData() {if(type==ELM_IMAGE_ATLAS){if(!data)data=new ElmImageAtlas; return CAST(ElmImageAtlas, data);} return null;}
  2962. C ElmImageAtlas* Elm::imageAtlasData()C {return (type==ELM_IMAGE_ATLAS) ? CAST(ElmImageAtlas, data) : null;}
  2963. ElmIconSetts * Elm::iconSettsData() {if(type==ELM_ICON_SETTS ){if(!data)data=new ElmIconSetts ; return CAST(ElmIconSetts , data);} return null;}
  2964. C ElmIconSetts * Elm::iconSettsData()C {return (type==ELM_ICON_SETTS ) ? CAST(ElmIconSetts , data) : null;}
  2965. ElmIcon * Elm::iconData() {if(type==ELM_ICON ){if(!data)data=new ElmIcon ; return CAST(ElmIcon , data);} return null;}
  2966. C ElmIcon * Elm::iconData()C {return (type==ELM_ICON ) ? CAST(ElmIcon , data) : null;}
  2967. ElmFont * Elm::fontData() {if(type==ELM_FONT ){if(!data)data=new ElmFont ; return CAST(ElmFont , data);} return null;}
  2968. C ElmFont * Elm::fontData()C {return (type==ELM_FONT ) ? CAST(ElmFont , data) : null;}
  2969. ElmTextStyle * Elm::textStyleData() {if(type==ELM_TEXT_STYLE ){if(!data)data=new ElmTextStyle ; return CAST(ElmTextStyle , data);} return null;}
  2970. C ElmTextStyle * Elm::textStyleData()C {return (type==ELM_TEXT_STYLE ) ? CAST(ElmTextStyle , data) : null;}
  2971. ElmPanel * Elm::panelData() {if(type==ELM_PANEL ){if(!data)data=new ElmPanel ; return CAST(ElmPanel , data);} return null;}
  2972. C ElmPanel * Elm::panelData()C {return (type==ELM_PANEL ) ? CAST(ElmPanel , data) : null;}
  2973. ElmGuiSkin * Elm::guiSkinData() {if(type==ELM_GUI_SKIN ){if(!data)data=new ElmGuiSkin ; return CAST(ElmGuiSkin , data);} return null;}
  2974. C ElmGuiSkin * Elm::guiSkinData()C {return (type==ELM_GUI_SKIN ) ? CAST(ElmGuiSkin , data) : null;}
  2975. ElmGui * Elm::guiData() {if(type==ELM_GUI ){if(!data)data=new ElmGui ; return CAST(ElmGui , data);} return null;}
  2976. C ElmGui * Elm::guiData()C {return (type==ELM_GUI ) ? CAST(ElmGui , data) : null;}
  2977. ElmSound * Elm::soundData() {if(type==ELM_SOUND ){if(!data)data=new ElmSound ; return CAST(ElmSound , data);} return null;}
  2978. C ElmSound * Elm::soundData()C {return (type==ELM_SOUND ) ? CAST(ElmSound , data) : null;}
  2979. ElmVideo * Elm::videoData() {if(type==ELM_VIDEO ){if(!data)data=new ElmVideo ; return CAST(ElmVideo , data);} return null;}
  2980. C ElmVideo * Elm::videoData()C {return (type==ELM_VIDEO ) ? CAST(ElmVideo , data) : null;}
  2981. ElmFile * Elm::fileData() {if(type==ELM_FILE ){if(!data)data=new ElmFile ; return CAST(ElmFile , data);} return null;}
  2982. C ElmFile * Elm::fileData()C {return (type==ELM_FILE ) ? CAST(ElmFile , data) : null;}
  2983. ElmCode * Elm::codeData() {if(type==ELM_CODE ){if(!data)data=new ElmCode ; return CAST(ElmCode , data);} return null;}
  2984. C ElmCode * Elm::codeData()C {return (type==ELM_CODE ) ? CAST(ElmCode , data) : null;}
  2985. ElmApp * Elm::appData() {if(type==ELM_APP ){if(!data)data=new ElmApp ; return CAST(ElmApp , data);} return null;}
  2986. C ElmApp * Elm::appData()C {return (type==ELM_APP ) ? CAST(ElmApp , data) : null;}
  2987. ElmData * Elm::Data()
  2988. {
  2989. if(!data)switch(type)
  2990. {
  2991. case ELM_OBJ_CLASS : data=new ElmObjClass ; break;
  2992. case ELM_OBJ : data=new ElmObj ; break;
  2993. case ELM_MESH : data=new ElmMesh ; break;
  2994. case ELM_MTRL : data=new ElmMaterial ; break;
  2995. case ELM_WATER_MTRL : data=new ElmWaterMtrl ; break;
  2996. case ELM_PHYS_MTRL : data=new ElmPhysMtrl ; break;
  2997. case ELM_SKEL : data=new ElmSkel ; break;
  2998. case ELM_PHYS : data=new ElmPhys ; break;
  2999. case ELM_ANIM : data=new ElmAnim ; break;
  3000. case ELM_PANEL_IMAGE: data=new ElmPanelImage; break;
  3001. case ELM_ENV : data=new ElmEnv ; break;
  3002. case ELM_WORLD : data=new ElmWorld ; break;
  3003. case ELM_MINI_MAP : data=new ElmMiniMap ; break;
  3004. case ELM_ENUM : data=new ElmEnum ; break;
  3005. case ELM_IMAGE : data=new ElmImage ; break;
  3006. case ELM_IMAGE_ATLAS: data=new ElmImageAtlas; break;
  3007. case ELM_ICON_SETTS : data=new ElmIconSetts ; break;
  3008. case ELM_ICON : data=new ElmIcon ; break;
  3009. case ELM_FONT : data=new ElmFont ; break;
  3010. case ELM_TEXT_STYLE : data=new ElmTextStyle ; break;
  3011. case ELM_PANEL : data=new ElmPanel ; break;
  3012. case ELM_GUI_SKIN : data=new ElmGuiSkin ; break;
  3013. case ELM_GUI : data=new ElmGui ; break;
  3014. case ELM_SOUND : data=new ElmSound ; break;
  3015. case ELM_VIDEO : data=new ElmVideo ; break;
  3016. case ELM_FILE : data=new ElmFile ; break;
  3017. case ELM_CODE : data=new ElmCode ; break;
  3018. case ELM_APP : data=new ElmApp ; break;
  3019. }
  3020. return data;
  3021. }
  3022. bool Elm::newerFile(C Elm &src)C // if 'this' has newer file than 'src'
  3023. {
  3024. if(type==src.type)switch(type)
  3025. {
  3026. case ELM_MESH : return meshData()->file_time>src. meshData()->file_time;
  3027. case ELM_SKEL : return skelData()->file_time>src. skelData()->file_time;
  3028. case ELM_PHYS : return physData()->file_time>src. physData()->file_time;
  3029. case ELM_ANIM : return animData()->file_time>src. animData()->file_time;
  3030. case ELM_GUI : return guiData()->file_time>src. guiData()->file_time;
  3031. case ELM_IMAGE : return imageData()->file_time>src. imageData()->file_time;
  3032. case ELM_IMAGE_ATLAS: return imageAtlasData()->file_time>src.imageAtlasData()->file_time;
  3033. case ELM_SOUND : return soundData()->file_time>src. soundData()->file_time;
  3034. case ELM_VIDEO : return videoData()->file_time>src. videoData()->file_time;
  3035. case ELM_FILE : return fileData()->file_time>src. fileData()->file_time;
  3036. case ELM_ICON : return iconData()->file_time>src. iconData()->file_time;
  3037. }
  3038. return false;
  3039. }
  3040. bool Elm::newerData(C Elm &src)C // if 'this' has any data newer than 'src'
  3041. {
  3042. if(type==src.type)switch(type)
  3043. {
  3044. case ELM_ENUM : return enumData()->newer(*src. enumData());
  3045. case ELM_IMAGE : return imageData()->newer(*src. imageData());
  3046. case ELM_IMAGE_ATLAS: return imageAtlasData()->newer(*src.imageAtlasData());
  3047. case ELM_FONT : return fontData()->newer(*src. fontData());
  3048. case ELM_TEXT_STYLE : return textStyleData()->newer(*src. textStyleData());
  3049. case ELM_PANEL : return panelData()->newer(*src. panelData());
  3050. case ELM_GUI : return guiData()->newer(*src. guiData());
  3051. case ELM_MTRL : return mtrlData()->newer(*src. mtrlData());
  3052. case ELM_WATER_MTRL : return waterMtrlData()->newer(*src. waterMtrlData());
  3053. case ELM_PHYS_MTRL : return physMtrlData()->newer(*src. physMtrlData());
  3054. case ELM_OBJ_CLASS : return objClassData()->newer(*src. objClassData());
  3055. case ELM_OBJ : return objData()->newer(*src. objData());
  3056. case ELM_MESH : return meshData()->newer(*src. meshData());
  3057. case ELM_SKEL : return skelData()->newer(*src. skelData());
  3058. case ELM_PHYS : return physData()->newer(*src. physData());
  3059. case ELM_ANIM : return animData()->newer(*src. animData());
  3060. case ELM_PANEL_IMAGE: return panelImageData()->newer(*src.panelImageData());
  3061. case ELM_ICON : return iconData()->newer(*src. iconData());
  3062. case ELM_ENV : return envData()->newer(*src. envData());
  3063. case ELM_WORLD : return worldData()->newer(*src. worldData());
  3064. case ELM_SOUND : return soundData()->newer(*src. soundData());
  3065. case ELM_VIDEO : return videoData()->newer(*src. videoData());
  3066. case ELM_FILE : return fileData()->newer(*src. fileData());
  3067. case ELM_CODE : return codeData()->newer(*src. codeData());
  3068. case ELM_APP : return appData()->newer(*src. appData());
  3069. case ELM_ICON_SETTS : return iconSettsData()->newer(*src. iconSettsData());
  3070. case ELM_MINI_MAP : return miniMapData()->newer(*src. miniMapData());
  3071. case ELM_GUI_SKIN : return guiSkinData()->newer(*src. guiSkinData());
  3072. }
  3073. return false;
  3074. }
  3075. uint Elm::syncData(C Elm &src)
  3076. {
  3077. if(type==src.type)switch(type)
  3078. {
  3079. case ELM_ENUM : return enumData()->sync(*src. enumData());
  3080. case ELM_IMAGE : return imageData()->sync(*src. imageData());
  3081. case ELM_IMAGE_ATLAS: return imageAtlasData()->sync(*src.imageAtlasData());
  3082. case ELM_FONT : return fontData()->sync(*src. fontData());
  3083. case ELM_TEXT_STYLE : return textStyleData()->sync(*src. textStyleData());
  3084. case ELM_PANEL : return panelData()->sync(*src. panelData());
  3085. case ELM_GUI : return guiData()->sync(*src. guiData());
  3086. case ELM_MTRL : return mtrlData()->sync(*src. mtrlData());
  3087. case ELM_WATER_MTRL : return waterMtrlData()->sync(*src. waterMtrlData());
  3088. case ELM_PHYS_MTRL : return physMtrlData()->sync(*src. physMtrlData());
  3089. case ELM_OBJ_CLASS : return objClassData()->sync(*src. objClassData());
  3090. case ELM_OBJ : return objData()->sync(*src. objData());
  3091. case ELM_MESH : return meshData()->sync(*src. meshData());
  3092. case ELM_SKEL : return skelData()->sync(*src. skelData());
  3093. case ELM_PHYS : return physData()->sync(*src. physData());
  3094. case ELM_ANIM : return animData()->sync(*src. animData());
  3095. case ELM_PANEL_IMAGE: return panelImageData()->sync(*src.panelImageData());
  3096. case ELM_ICON : return iconData()->sync(*src. iconData());
  3097. case ELM_ENV : return envData()->sync(*src. envData());
  3098. case ELM_WORLD : return worldData()->sync(*src. worldData());
  3099. case ELM_SOUND : return soundData()->sync(*src. soundData());
  3100. case ELM_VIDEO : return videoData()->sync(*src. videoData());
  3101. case ELM_FILE : return fileData()->sync(*src. fileData());
  3102. case ELM_CODE : return codeData()->sync(*src. codeData());
  3103. case ELM_APP : return appData()->sync(*src. appData(), false);
  3104. case ELM_ICON_SETTS : return iconSettsData()->sync(*src. iconSettsData());
  3105. case ELM_MINI_MAP : return miniMapData()->sync(*src. miniMapData());
  3106. case ELM_GUI_SKIN : return guiSkinData()->sync(*src. guiSkinData());
  3107. }
  3108. return 0;
  3109. }
  3110. bool Elm::save(File &f, bool network, bool skip_name_data)C
  3111. {
  3112. byte flag=T.flag;
  3113. if(data )flag|=DATA;
  3114. if(network)FlagDisable(flag, IMPORTING); // don't transmit IMPORTING status over network, to make reload requests local only, so one reload doesn't trigger reload on all connected computers
  3115. f.cmpUIntV(3);
  3116. f<<id<<parent_id<<type<<flag;
  3117. f<<name_time<<parent_time<<removed_time<<no_publish_time;
  3118. if(!skip_name_data)f<<name;
  3119. // data
  3120. if(data)if(skip_name_data)f<<data->ver;
  3121. else data->save(f);
  3122. return f.ok();
  3123. }
  3124. bool Elm::load(File &f, bool network, bool skip_name_data)
  3125. {
  3126. switch(f.decUIntV())
  3127. {
  3128. case 3:
  3129. {
  3130. f>>id>>parent_id>>type>>flag; if(type>=ELM_NUM)return false;
  3131. f>>name_time>>parent_time>>removed_time>>no_publish_time;
  3132. if(!skip_name_data)f>>name;
  3133. // data
  3134. Delete(data); if(flag&DATA) // if has data
  3135. {
  3136. FlagDisable(flag, DATA);
  3137. ElmData *data=Data(); if(!data)return false;
  3138. if(skip_name_data)f>>data->ver;
  3139. else if(!data->load(f))return false;
  3140. }
  3141. if(f.ok())return true;
  3142. }break;
  3143. case 2:
  3144. {
  3145. f>>id>>parent_id>>type>>flag; if(type>=ELM_NUM)return false;
  3146. f>>name_time>>parent_time>>removed_time>>no_publish_time;
  3147. if(!skip_name_data)GetStr2(f, name);
  3148. // data
  3149. Delete(data); if(flag&DATA) // if has data
  3150. {
  3151. FlagDisable(flag, DATA);
  3152. ElmData *data=Data(); if(!data)return false;
  3153. if(skip_name_data)f>>data->ver;
  3154. else if(!data->load(f))return false;
  3155. }
  3156. if(f.ok())return true;
  3157. }break;
  3158. case 1:
  3159. {
  3160. f>>id>>parent_id>>type>>flag; if(type>=ELM_NUM)return false;
  3161. f>>name_time>>parent_time>>removed_time>>no_publish_time;
  3162. if(!skip_name_data)GetStr(f, name);
  3163. // data
  3164. Delete(data); if(flag&DATA) // if has data
  3165. {
  3166. FlagDisable(flag, DATA);
  3167. ElmData *data=Data(); if(!data)return false;
  3168. if(skip_name_data)f>>data->ver;
  3169. else if(!data->load(f))return false;
  3170. }
  3171. if(f.ok())return true;
  3172. }break;
  3173. case 0:
  3174. {
  3175. f>>id>>parent_id>>type>>flag; if(type>=ELM_NUM)return false;
  3176. f>>name_time>>parent_time>>removed_time; no_publish_time.zero();
  3177. if(!skip_name_data)GetStr(f, name);
  3178. // data
  3179. Delete(data); if(flag&DATA) // if has data
  3180. {
  3181. FlagDisable(flag, DATA);
  3182. ElmData *data=Data(); if(!data)return false;
  3183. if(skip_name_data)f>>data->ver;
  3184. else if(!data->load(f))return false;
  3185. }
  3186. if(f.ok())return true;
  3187. }break;
  3188. }
  3189. return false;
  3190. }
  3191. void Elm::save(TextNode &node)C
  3192. {
  3193. node.set(id.asFileName());
  3194. node.nodes.New().set ("Type" , ElmTypeNameNoSpaceDummy.names[type]);
  3195. node.nodes.New().set ("Name" , name);
  3196. if(parent_id.valid())node.nodes.New().setFN("Parent" , parent_id);
  3197. if(removed ())node.nodes.New().set ("Removed");
  3198. if(noPublish ())node.nodes.New().set ("Publish", publish());
  3199. node.nodes.New().set("NameTime" , name_time.text());
  3200. node.nodes.New().set("ParentTime" , parent_time.text());
  3201. if( removed_time.is())node.nodes.New().set("RemovedTime", removed_time.text());
  3202. if(no_publish_time.is())node.nodes.New().set("PublishTime", no_publish_time.text());
  3203. // IMPORTING OPENED flags are not saved, because this text format is used for SVN synchronization, and we don't want to send these flags to other computers
  3204. // FINAL_REMOVED FINAL_NO_PUBLISH flags are not saved because they are calculated based on other flags and parents
  3205. if(data)data->save(node.nodes.New().setName("Data").nodes);
  3206. }
  3207. bool Elm::load(C TextNode &node, Str &error) // assumes that 'error' doesn't need to be cleared at start, and 'T.id' was already set
  3208. {
  3209. C TextNode *data_node=null;
  3210. REPA(node.nodes)
  3211. {
  3212. C TextNode &n=node.nodes[i];
  3213. if(n.name=="Type" ){REP(ELM_NUM)if(n.value==ElmTypeNameNoSpaceDummy.names[i]){type=ELM_TYPE(i); break;}}else
  3214. if(n.name=="Name" )n.getValue(name );else
  3215. if(n.name=="Parent" )n.getValue(parent_id);else
  3216. if(n.name=="Removed" )removed (n.asBool1());else
  3217. if(n.name=="Publish" )publish (n.asBool1());else
  3218. if(n.name=="NameTime" )name_time =n.asText () ;else
  3219. if(n.name=="ParentTime" )parent_time =n.asText () ;else
  3220. if(n.name=="RemovedTime")removed_time =n.asText () ;else
  3221. if(n.name=="PublishTime")no_publish_time=n.asText () ;else
  3222. if(n.name=="Data" )data_node=&n; // remember for later, because to load data, first we must know the type
  3223. }
  3224. if(!type){error=S+"Element \""+node.name+"\" has no type"; return false;}
  3225. if(data_node)if(ElmData *data=Data())data->load(ConstCast(data_node->nodes));/*else return false; we can silently ignore this*/
  3226. return true;
  3227. }
  3228. void Elm::compressNew(File &f)C
  3229. {
  3230. f<<id<<parent_id<<type<<name; //<<create_time;
  3231. }
  3232. void Elm::decompressNew(File &f)
  3233. {
  3234. f>>id>>parent_id>>type>>name; //>>create_time;
  3235. name_time=parent_time=NewElmTime; // new elements always have those times set, so instead of sending we can assume their value here
  3236. }
  3237. void Elm::compressData(File &f)C
  3238. {
  3239. f<<id<<type;
  3240. f.putBool(data!=null); if(data)data->save(f);
  3241. }
  3242. bool Elm::decompressData(File &f)
  3243. {
  3244. f>>id>>type;
  3245. Delete(data); if(f.getBool())
  3246. {
  3247. ElmData *data=Data(); if(!data)return false;
  3248. return data->load(f);
  3249. }
  3250. return false;
  3251. }
  3252. bool TextureInfo::knownFileSize()C {return file_size>=0;}
  3253. bool TextureInfo::knownSharpness()C {return sharpness< 2;}
  3254. ElmObjClass::ElmObjClass() : flag(0) {}
  3255. ElmObj::ElmObj() : mesh_id(UIDZero), base_id(UIDZero) {}
  3256. ElmMesh::ElmMesh() : obj_id(UIDZero), skel_id(UIDZero), phys_id(UIDZero), body_id(UIDZero), draw_group_id(UIDZero), box(Vec(0), Vec(-1)) {}
  3257. ElmMaterial::ElmMaterial() : base_0_tex(UIDZero), base_1_tex(UIDZero), detail_tex(UIDZero), macro_tex(UIDZero), reflection_tex(UIDZero), light_tex(UIDZero), downsize_tex_mobile(0), flag(0) {}
  3258. ElmWaterMtrl::ElmWaterMtrl() : base_0_tex(UIDZero), base_1_tex(UIDZero), reflection_tex(UIDZero), flag(0) {}
  3259. ElmSkel::ElmSkel() : mesh_id(UIDZero) {}
  3260. ElmPhys::ElmPhys() : mesh_id(UIDZero), mtrl_id(UIDZero), density(1), box(Vec(0), Vec(-1)) {}
  3261. ElmAnim::ElmAnim() : skel_id(UIDZero), root_move(VecZero), root_rot(VecZero), flag(LOOP) {}
  3262. ElmWorld::ElmWorld() : area_size(0), hm_res(0), ctrl_r(0.33f), ctrl_h(2.0f), max_climb(0.7f), max_slope(PI_4), cell_size(1.0f/3), cell_h(0.1f), env_id(UIDZero) {}
  3263. ElmEnum::ElmEnum() : type(EditEnums::DEFAULT) {}
  3264. ElmImage::ElmImage() : flag(MIP_MAPS), type(COMPRESSED), mode(IMAGE_2D), size(0) {}
  3265. ElmImageAtlas::ElmImageAtlas() : mip_maps(true) {}
  3266. ElmImageAtlas::Img::Img() : removed(false), id(UIDZero) {}
  3267. ElmIconSetts::ElmIconSetts() : type(ElmImage::COMPRESSED) {}
  3268. ElmIcon::ElmIcon() : flag(0), icon_settings_id(UIDZero), obj_id(UIDZero), anim_id(UIDZero), variation_id(InheritVariation), anim_pos(0) {}
  3269. ElmTextStyle::ElmTextStyle() : font_id(UIDZero) {}
  3270. ElmPanelImage::ElmPanelImage() : compressed(false) {}
  3271. ElmApp::ElmApp() : build(1), fb_app_id(0), storage(Edit::STORAGE_INTERNAL), supported_orientations(DIRF_X|DIRF_Y), flag(PUBLISH_PROJ_DATA|PUBLISH_PHYSX_DLL|PUBLISH_DATA_AS_PAK), icon(UIDZero), notification_icon(UIDZero), image_portrait(UIDZero), image_landscape(UIDZero), gui_skin(UIDZero) {}
  3272. ElmMiniMap::ElmMiniMap() : areas_per_image(4), image_size(256), world_id(UIDZero), env_id(UIDZero) {}
  3273. Elm::Elm() : type(ELM_NONE), flag(0), file_size(-1), id(UID().randomizeValid()), parent_id(UIDZero), data(null) {}
  3274. TextureInfo::TextureInfo() : file_size(-1), sharpness( 3) {}
  3275. /******************************************************************************/