Ticket #1122: atlas_eyedropper-01182012.patch
File atlas_eyedropper-01182012.patch, 21.6 KB (added by , 12 years ago) |
---|
-
source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 368 368 wxSystemOptions::SetOption(_T("osx.openfiledialog.always-show-types"), 1); // has global effect 369 369 370 370 // wxLog::SetTraceMask(wxTraceMessages); 371 372 g_SelectedTexture = _T("grass1_spring"); 373 g_SelectedTexture.NotifyObservers(); 371 374 372 375 SetOpenFilename(_T("")); 373 376 -
source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 45 45 TextureNotebook* m_Textures; 46 46 }; 47 47 48 49 48 enum 50 49 { 51 50 ID_Passability = 1, … … 60 59 return window; 61 60 } 62 61 62 // Add spaces into the displayed name so there are more wrapping opportunities 63 static wxString FormatTextureName(wxString name) 64 { 65 if (name.Len()) 66 name[0] = wxToupper(name[0]); 67 name.Replace(_T("_"), _T(" ")); 68 69 return name; 70 } 71 72 ////////////////////////////////////////////////////////////////////////// 73 74 class TexturePreviewPanel : public wxPanel 75 { 76 private: 77 static const int imageWidth = 120; 78 static const int imageHeight = 40; 79 80 public: 81 TexturePreviewPanel(wxWindow* parent) 82 : wxPanel(parent, wxID_ANY), m_Timer(this) 83 { 84 m_Conn = g_SelectedTexture.RegisterObserver(0, &TexturePreviewPanel::OnTerrainChange, this); 85 m_Sizer = new wxStaticBoxSizer(wxVERTICAL, this, _T("Texture")); 86 SetSizer(m_Sizer); 87 88 // Use placeholder bitmap for now 89 m_Sizer->Add(new wxStaticBitmap(this, wxID_ANY, wxNullBitmap), wxSizerFlags(1).Expand()); 90 } 91 92 void LoadPreview() 93 { 94 if (m_TextureName.IsEmpty()) 95 { 96 // If we haven't got a texture yet, copy the global 97 m_TextureName = g_SelectedTexture; 98 } 99 100 Freeze(); 101 102 m_Sizer->Clear(true); 103 104 AtlasMessage::qGetTerrainTexturePreview qry(m_TextureName.wc_str(), imageWidth, imageHeight); 105 qry.Post(); 106 107 AtlasMessage::sTerrainTexturePreview preview = qry.preview; 108 109 // Check for invalid/missing texture - shouldn't happen 110 if (wxString(qry.preview->name.c_str()).IsEmpty()) 111 return; 112 113 // Construct the wrapped-text label 114 wxStaticText* label = new wxStaticText(this, wxID_ANY, FormatTextureName(*qry.preview->name), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); 115 label->Wrap(m_Sizer->GetSize().GetX()); 116 117 unsigned char* buf = (unsigned char*)(malloc(preview.imageData.GetSize())); 118 // imagedata.GetBuffer() gives a Shareable<unsigned char>*, which 119 // is stored the same as a unsigned char*, so we can just copy it. 120 memcpy(buf, preview.imageData.GetBuffer(), preview.imageData.GetSize()); 121 wxImage img(qry.preview->imageWidth, qry.preview->imageHeight, buf); 122 123 wxStaticBitmap* bitmap = new wxStaticBitmap(this, wxID_ANY, wxBitmap(img), wxDefaultPosition, wxSize(qry.preview->imageWidth, qry.preview->imageHeight), wxBORDER_SIMPLE); 124 m_Sizer->Add(bitmap, wxSizerFlags(1).Align(wxALIGN_CENTRE)); 125 m_Sizer->Add(label, wxSizerFlags().Expand()); 126 127 // We have to force the sidebar to layout manually 128 GetParent()->Layout(); 129 130 Layout(); 131 Thaw(); 132 133 if (preview.loaded && m_Timer.IsRunning()) 134 { 135 m_Timer.Stop(); 136 } 137 else if (!preview.loaded && !m_Timer.IsRunning()) 138 { 139 m_Timer.Start(2000); 140 } 141 } 142 143 void OnTerrainChange(const wxString& texture) 144 { 145 // Check if texture really changed, to avoid doing this too often 146 if (texture != m_TextureName) 147 { 148 // Load new texture preview 149 m_TextureName = texture; 150 LoadPreview(); 151 } 152 } 153 154 void OnTimer(wxTimerEvent& WXUNUSED(evt)) 155 { 156 LoadPreview(); 157 } 158 159 private: 160 ObservableScopedConnection m_Conn; 161 wxSizer* m_Sizer; 162 wxTimer m_Timer; 163 wxString m_TextureName; 164 165 DECLARE_EVENT_TABLE(); 166 }; 167 168 BEGIN_EVENT_TABLE(TexturePreviewPanel, wxPanel) 169 EVT_TIMER(wxID_ANY, TexturePreviewPanel::OnTimer) 170 END_EVENT_TABLE(); 171 172 ////////////////////////////////////////////////////////////////////////// 173 63 174 TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) : 64 175 Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer) 65 176 { … … 82 193 ///////////////////////////////////////////////////////////////////////// 83 194 // Terrain texture 84 195 wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Texture tools")); 196 // Top row 85 197 wxSizer* gridSizer = new wxGridSizer(3); 86 198 gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain")), 87 199 _("Brush with left mouse button to paint texture dominantly,\nright mouse button to paint submissively")), wxSizerFlags().Expand()); … … 90 202 gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Fill"), _T("FillTerrain")), 91 203 _T("Bucket fill a patch of terrain texture with a new one")), wxSizerFlags().Expand()); 92 204 sizer->Add(gridSizer, wxSizerFlags().Expand()); 205 // Second row 206 gridSizer = new wxGridSizer(3); 207 gridSizer->Add(Tooltipped(new ToolButton(scenarioEditor.GetToolManager(), this, _("Eyedrop"), _T("EyeDropper")), 208 _("Click terrain to get the texture at that position")), wxSizerFlags().Expand()); 209 sizer->Add(gridSizer, wxSizerFlags().Expand()); 93 210 m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 10)); 94 211 } 95 212 … … 97 214 ///////////////////////////////////////////////////////////////////////// 98 215 // Brush settings 99 216 wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Brush")); 217 218 m_TexturePreview = new TexturePreviewPanel(this); 219 sizer->Add(m_TexturePreview, wxSizerFlags(1).Expand()); 220 100 221 g_Brush_Elevation.CreateUI(this, sizer); 101 222 m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 10)); 102 223 } … … 145 266 m_PassabilityChoice->Append(passClasses[i].c_str()); 146 267 147 268 static_cast<TerrainBottomBar*>(m_BottomBar)->LoadTerrain(); 269 m_TexturePreview->LoadPreview(); 148 270 } 149 271 150 272 void TerrainSidebar::OnPassabilityChoice(wxCommandEvent& evt) … … 245 367 AtlasMessage::qGetTerrainGroupPreviews qry((std::wstring)m_Name.wc_str(), imageWidth, imageHeight); 246 368 qry.Post(); 247 369 248 std::vector<AtlasMessage::sTerrain GroupPreview> previews = *qry.previews;370 std::vector<AtlasMessage::sTerrainTexturePreview> previews = *qry.previews; 249 371 250 372 bool allLoaded = true; 251 373 … … 254 376 if (!previews[i].loaded) 255 377 allLoaded = false; 256 378 257 // Construct the wrapped-text label258 379 wxString name = previews[i].name.c_str(); 259 380 260 // Add spaces into the displayed name so there are more wrapping opportunities 261 wxString labelText = name; 262 if (labelText.Len()) 263 labelText[0] = wxToupper(labelText[0]); 264 labelText.Replace(_T("_"), _T(" ")); 265 wxStaticText* label = new wxStaticText(m_ScrolledPanel, wxID_ANY, labelText, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); 381 // Construct the wrapped-text label 382 wxStaticText* label = new wxStaticText(m_ScrolledPanel, wxID_ANY, FormatTextureName(name), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); 266 383 label->Wrap(imageWidth); 267 384 268 385 unsigned char* buf = (unsigned char*)(malloc(previews[i].imageData.GetSize())); … … 303 420 wxButton* button = wxDynamicCast(evt.GetEventObject(), wxButton); 304 421 wxString name = static_cast<wxStringClientData*>(button->GetClientObject())->GetData(); 305 422 g_SelectedTexture = name; 423 g_SelectedTexture.NotifyObservers(); 306 424 307 425 if (m_LastTerrainSelection) 308 426 m_LastTerrainSelection->SetBackgroundColour(wxNullColour); -
source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 17 17 18 18 #include "../Common/Sidebar.h" 19 19 20 class TexturePreviewPanel; 21 20 22 class TerrainSidebar : public Sidebar 21 23 { 22 24 public: … … 31 33 void OnResizeMap(wxCommandEvent& evt); 32 34 33 35 wxChoice* m_PassabilityChoice; 36 TexturePreviewPanel* m_TexturePreview; 34 37 35 38 DECLARE_EVENT_TABLE(); 36 39 }; 40 -
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/MiscState.cpp
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 19 19 20 20 #include "MiscState.h" 21 21 22 wxString g_SelectedTexture = _T("grass1_spring");22 Observable<wxString> g_SelectedTexture; 23 23 24 24 Observable<std::vector<AtlasMessage::ObjectID> > g_SelectedObjects; -
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/MiscState.h
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 25 25 typedef size_t ObjectID; 26 26 } 27 27 28 extern wxStringg_SelectedTexture;28 extern Observable<wxString> g_SelectedTexture; 29 29 30 30 extern Observable<std::vector<AtlasMessage::ObjectID> > g_SelectedObjects; 31 31 -
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/EyeDropper.cpp
1 /* Copyright (C) 2012 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * 0 A.D. is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "precompiled.h" 19 20 #include "ScenarioEditor/ScenarioEditor.h" 21 #include "Common/Tools.h" 22 #include "Common/Brushes.h" 23 #include "Common/MiscState.h" 24 #include "GameInterface/Messages.h" 25 26 using AtlasMessage::Position; 27 28 class EyeDropper : public StateDrivenTool<EyeDropper> 29 { 30 DECLARE_DYNAMIC_CLASS(EyeDropper); 31 32 Position m_Pos; 33 Brush m_Brush; 34 35 public: 36 EyeDropper() 37 { 38 m_Brush.SetSquare(2); 39 SetState(&Waiting); 40 } 41 42 void OnEnable() 43 { 44 m_Brush.MakeActive(); 45 } 46 47 void OnDisable() 48 { 49 POST_MESSAGE(BrushPreview, (false, Position())); 50 } 51 52 struct sWaiting : public State 53 { 54 bool OnMouse(EyeDropper* WXUNUSED(obj), wxMouseEvent& evt) 55 { 56 if (evt.LeftDown()) 57 { 58 Position pos(evt.GetPosition()); 59 POST_MESSAGE(BrushPreview, (true, pos)); 60 61 AtlasMessage::qGetTerrainTexture qry(pos); 62 qry.Post(); 63 64 g_SelectedTexture = wxString(qry.texture.c_str()); 65 g_SelectedTexture.NotifyObservers(); 66 67 return true; 68 } 69 else if (evt.Moving()) 70 { 71 POST_MESSAGE(BrushPreview, (true, Position(evt.GetPosition()))); 72 return true; 73 } 74 else 75 { 76 return false; 77 } 78 } 79 } 80 Waiting; 81 }; 82 83 IMPLEMENT_DYNAMIC_CLASS(EyeDropper, StateDrivenTool<EyeDropper>); 84 -
source/tools/atlas/AtlasUI/ScenarioEditor/Tools/EyeDropper.cpp
-
source/tools/atlas/GameInterface/Handlers/TerrainHandlers.cpp
Property changes on: source/tools/atlas/AtlasUI/ScenarioEditor/Tools/EyeDropper.cpp ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 51 51 msg->groupNames = groupNames; 52 52 } 53 53 54 static bool CompareTerrain(const sTerrain GroupPreview& a, const sTerrainGroupPreview& b)54 static bool CompareTerrain(const sTerrainTexturePreview& a, const sTerrainTexturePreview& b) 55 55 { 56 56 return (wcscmp(a.name.c_str(), b.name.c_str()) < 0); 57 57 } 58 58 59 QUERYHANDLER(GetTerrainGroupPreviews)59 static sTerrainTexturePreview GetPreview(CTerrainTextureEntry* tex, int width, int height) 60 60 { 61 std::vector<sTerrainGroupPreview> previews; 61 sTerrainTexturePreview preview; 62 preview.name = tex->GetTag().FromUTF8(); 62 63 63 CTerrainGroup* group = g_TexMan.FindGroup(CStrW(*msg->groupName).ToUTF8()); 64 for (std::vector<CTerrainTextureEntry*>::const_iterator it = group->GetTerrains().begin(); it != group->GetTerrains().end(); ++it) 65 { 66 previews.push_back(sTerrainGroupPreview()); 67 previews.back().name = (*it)->GetTag().FromUTF8(); 64 std::vector<unsigned char> buf (width*height*3); 68 65 69 std::vector<unsigned char> buf (msg->imageWidth*msg->imageHeight*3); 66 // It's not good to shrink the entire texture to fit the small preview 67 // window, since it's the fine details in the texture that are 68 // interesting; so just go down one mipmap level, then crop a chunk 69 // out of the middle. 70 70 71 // It's not good to shrink the entire texture to fit the small preview 72 // window, since it's the fine details in the texture that are 73 // interesting; so just go down one mipmap level, then crop a chunk 74 // out of the middle. 71 // Read the size of the texture. (Usually loads the texture from 72 // disk, which is slow.) 73 GLint w, h; 74 ssize_t level = 1; // level 0 is the original size 75 tex->GetTexture()->Bind(); 76 glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &w); 77 glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &h); 75 78 76 // Read the size of the texture. (Usually loads the texture from 77 // disk, which is slow.) 78 GLint w, h; 79 ssize_t level = 1; // level 0 is the original size 80 (*it)->GetTexture()->Bind(); 81 glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &w); 82 glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &h); 79 if (w < width || h < height) 80 { 81 // Oops, too small to preview - just use a flat colour 82 u32 c = tex->GetBaseColor(); 83 for (ssize_t i = 0; i < width*height; ++i) 84 { 85 buf[i*3+0] = (c>>16) & 0xff; 86 buf[i*3+1] = (c>>8) & 0xff; 87 buf[i*3+2] = (c>>0) & 0xff; 88 } 89 } 90 else 91 { 92 // Read the whole texture into a new buffer 93 unsigned char* texdata = new unsigned char[w*h*3]; 94 glGetTexImage(GL_TEXTURE_2D, level, GL_RGB, GL_UNSIGNED_BYTE, texdata); 83 95 84 if (w < msg->imageWidth || h < msg->imageHeight) 96 // Extract the middle section (as a representative preview), 97 // and copy into buf 98 unsigned char* texdata_ptr = texdata + (w*(h - height)/2 + (w - width)/2) * 3; 99 unsigned char* buf_ptr = &buf[0]; 100 for (ssize_t y = 0; y < height; ++y) 85 101 { 86 // Oops, too small to preview - just use a flat colour 87 u32 c = (*it)->GetBaseColor(); 88 for (ssize_t i = 0; i < msg->imageWidth*msg->imageHeight; ++i) 89 { 90 buf[i*3+0] = (c>>16) & 0xff; 91 buf[i*3+1] = (c>>8) & 0xff; 92 buf[i*3+2] = (c>>0) & 0xff; 93 } 102 memcpy(buf_ptr, texdata_ptr, width*3); 103 buf_ptr += width*3; 104 texdata_ptr += w*3; 94 105 } 95 else96 {97 // Read the whole texture into a new buffer98 unsigned char* texdata = new unsigned char[w*h*3];99 glGetTexImage(GL_TEXTURE_2D, level, GL_RGB, GL_UNSIGNED_BYTE, texdata);100 106 101 // Extract the middle section (as a representative preview), 102 // and copy into buf 103 unsigned char* texdata_ptr = texdata + (w*(h - msg->imageHeight)/2 + (w - msg->imageWidth)/2) * 3; 104 unsigned char* buf_ptr = &buf[0]; 105 for (ssize_t y = 0; y < msg->imageHeight; ++y) 106 { 107 memcpy(buf_ptr, texdata_ptr, msg->imageWidth*3); 108 buf_ptr += msg->imageWidth*3; 109 texdata_ptr += w*3; 110 } 107 delete[] texdata; 108 } 111 109 112 delete[] texdata; 113 } 110 preview.loaded = tex->GetTexture()->IsLoaded(); 111 preview.imageWidth = width; 112 preview.imageHeight = height; 113 preview.imageData = buf; 114 114 115 previews.back().loaded = (*it)->GetTexture()->IsLoaded(); 116 previews.back().imageWidth = msg->imageWidth; 117 previews.back().imageHeight = msg->imageHeight; 118 previews.back().imageData = buf; 115 return preview; 116 } 117 118 QUERYHANDLER(GetTerrainGroupPreviews) 119 { 120 std::vector<sTerrainTexturePreview> previews; 121 122 CTerrainGroup* group = g_TexMan.FindGroup(CStrW(*msg->groupName).ToUTF8()); 123 for (std::vector<CTerrainTextureEntry*>::const_iterator it = group->GetTerrains().begin(); it != group->GetTerrains().end(); ++it) 124 { 125 previews.push_back(GetPreview(*it, msg->imageWidth, msg->imageHeight)); 119 126 } 120 127 121 128 // Sort the list alphabetically by name … … 137 144 } 138 145 } 139 146 147 QUERYHANDLER(GetTerrainTexture) 148 { 149 ssize_t x, y; 150 g_CurrentBrush.m_Centre = msg->pos->GetWorldSpace(); 151 g_CurrentBrush.GetCentre(x, y); 152 153 CTerrain* terrain = g_Game->GetWorld()->GetTerrain(); 154 CMiniPatch* tile = terrain->GetTile(x, y); 155 if (tile) 156 { 157 CTerrainTextureEntry* tex = tile->GetTextureEntry(); 158 msg->texture = tex->GetTag().FromUTF8(); 159 } 160 else 161 { 162 msg->texture = std::wstring(); 163 } 164 } 165 166 QUERYHANDLER(GetTerrainTexturePreview) 167 { 168 CTerrainTextureEntry* tex = g_TexMan.FindTexture(CStrW(*msg->name).ToUTF8()); 169 if (tex) 170 { 171 msg->preview = GetPreview(tex, msg->imageWidth, msg->imageHeight); 172 } 173 else 174 { 175 sTerrainTexturePreview noPreview; 176 noPreview.name = std::wstring(); 177 noPreview.imageHeight = 0; 178 noPreview.imageWidth = 0; 179 msg->preview = noPreview; 180 } 181 } 182 140 183 ////////////////////////////////////////////////////////////////////////// 141 184 142 185 namespace { -
source/tools/atlas/GameInterface/Messages.h
1 /* Copyright (C) 201 1Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 259 259 ); 260 260 261 261 #ifndef MESSAGES_SKIP_STRUCTS 262 struct sTerrain GroupPreview262 struct sTerrainTexturePreview 263 263 { 264 264 Shareable<std::wstring> name; 265 265 Shareable<bool> loaded; … … 267 267 Shareable<int> imageHeight; 268 268 Shareable<std::vector<unsigned char> > imageData; // RGB*width*height 269 269 }; 270 SHAREABLE_STRUCT(sTerrain GroupPreview);270 SHAREABLE_STRUCT(sTerrainTexturePreview); 271 271 #endif 272 272 273 273 QUERY(GetTerrainGroupPreviews, … … 275 275 ((int, imageWidth)) 276 276 ((int, imageHeight)) 277 277 , 278 ((std::vector<sTerrain GroupPreview>, previews))278 ((std::vector<sTerrainTexturePreview>, previews)) 279 279 ); 280 280 281 281 QUERY(GetTerrainPassabilityClasses, … … 283 283 ((std::vector<std::wstring>, classNames)) 284 284 ); 285 285 286 QUERY(GetTerrainTexturePreview, 287 ((std::wstring, name)) 288 ((int, imageWidth)) 289 ((int, imageHeight)) 290 , 291 ((sTerrainTexturePreview, preview)) 292 ); 293 286 294 ////////////////////////////////////////////////////////////////////////// 287 295 288 296 #ifndef MESSAGES_SKIP_STRUCTS … … 481 489 ((std::wstring, texture)) 482 490 ); 483 491 492 QUERY(GetTerrainTexture, 493 ((Position, pos)) 494 , 495 ((std::wstring, texture)) 496 ); 497 484 498 ////////////////////////////////////////////////////////////////////////// 485 499 486 500 QUERY(PickObject, -
source/tools/atlas/GameInterface/Shareable.h
1 /* Copyright (C) 20 09Wildfire Games.1 /* Copyright (C) 2012 Wildfire Games. 2 2 * This file is part of 0 A.D. 3 3 * 4 4 * 0 A.D. is free software: you can redistribute it and/or modify … … 118 118 // Shareable containers must have shareable contents - but it's easy to forget 119 119 // to declare them, so make sure the errors are almost readable, like: 120 120 // "use of undefined type 'REQUIRE_TYPE_TO_BE_SHAREABLE_FAILURE<T,__formal> 121 // with [ T=AtlasMessage::sTerrain GroupPreview, __formal=false ]"121 // with [ T=AtlasMessage::sTerrainTexturePreview, __formal=false ]" 122 122 // 123 123 // (Implementation based on boost/static_assert) 124 124 template <typename T, bool> struct REQUIRE_TYPE_TO_BE_SHAREABLE_FAILURE;