Implement error-handling (file names and locations) via std::source_location and added CRT debugging memory leak detection.

pull/28/head
sigonasr2 1 year ago
parent 75159a21be
commit 67a5288984
  1. 20
      Crawler/CharacterInfoWindow.cpp
  2. 3
      Crawler/ClassInfo.h
  3. 16
      Crawler/ClassSelectionWindow.cpp
  4. 44
      Crawler/Crawler.cpp
  5. 1
      Crawler/Crawler.vcxproj
  6. 3
      Crawler/Crawler.vcxproj.filters
  7. 37
      Crawler/Error.h
  8. 6
      Crawler/GameState.cpp
  9. 5
      Crawler/GameState.h
  10. 11
      Crawler/InventoryScrollableWindowComponent.h
  11. 6
      Crawler/InventoryWindow.cpp
  12. 6
      Crawler/Item.cpp
  13. 36
      Crawler/Menu.cpp
  14. 2
      Crawler/Menu.h
  15. 2
      Crawler/MenuItemButton.h
  16. 2
      Crawler/MonsterData.cpp
  17. 2
      Crawler/Pathfinding.cpp
  18. 4
      Crawler/ScrollableWindowComponent.h
  19. 4
      Crawler/State_GameRun.cpp
  20. 15
      Crawler/State_OverworldMap.cpp
  21. 6
      Crawler/TSXParser.h
  22. 8
      Crawler/TestMenu.cpp
  23. 8
      Crawler/TestSubMenu.cpp
  24. 3
      Crawler/Toggleable.h
  25. 2
      Crawler/Version.h
  26. 17
      Crawler/olcPixelGameEngine.h
  27. 13
      Crawler/olcUTIL_DataFile.h
  28. BIN
      Crawler/pge.data
  29. 2
      Crawler/pge.js
  30. BIN
      Crawler/pge.wasm
  31. 13
      Crawler/safemap.h
  32. BIN
      x64/Release/Crawler.exe

@ -17,21 +17,21 @@ void Menu::InitializeClassInfoWindow(){
Menu*classSelectionWindow=Menu::menus[CLASS_SELECTION];
ClassInfo data=classutils::GetClassInfo(classSelectionWindow->S(A::CLASS_SELECTION));
MenuLabel*label=new MenuLabel(CLASS_INFO,{{0,0},{classInfoWindow->size.x-1,24}},data.className,2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
MenuLabel*label=NEW MenuLabel(CLASS_INFO,{{0,0},{classInfoWindow->size.x-1,24}},data.className,2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
classInfoWindow->AddComponent("Class Name",label);
CharacterRotatingDisplay*classDisplay=new CharacterRotatingDisplay(CLASS_INFO,{{0,0},{72,120}},GFX[data.classFullImgName].Decal());
CharacterRotatingDisplay*classDisplay=NEW CharacterRotatingDisplay(CLASS_INFO,{{0,0},{72,120}},GFX[data.classFullImgName].Decal());
classInfoWindow->AddComponent("Rotating Character Display",classDisplay);
vf2d healthDisplayLabelPos={classInfoWindow->size.x/3,label->GetPos().y+24};
vf2d labelSize={2*classInfoWindow->size.x/3-1,16};
MenuLabel*baseStatsLabel=new MenuLabel(CLASS_INFO,{{0,label->GetPos().y+24},{classInfoWindow->size.x/3,labelSize.y}},"Base Stats",1,ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
MenuLabel*baseStatsLabel=NEW MenuLabel(CLASS_INFO,{{0,label->GetPos().y+24},{classInfoWindow->size.x/3,labelSize.y}},"Base Stats",1,ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
MenuLabel*healthDisplayLabel=new MenuLabel(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,16*0},labelSize},"Health: "+std::to_string(data.baseHealth)+" + "+std::to_string(data.healthGrowthRate).substr(0,3)+" per level",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
MenuLabel*atkDisplayLabel=new MenuLabel(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,16*1},labelSize},"Attack: "+std::to_string(data.baseAtk)+" + "+std::to_string(data.atkGrowthRate).substr(0,3)+" per level",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
MenuLabel*healthDisplayLabel=NEW MenuLabel(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,16*0},labelSize},"Health: "+std::to_string(data.baseHealth)+" + "+std::to_string(data.healthGrowthRate).substr(0,3)+" per level",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
MenuLabel*atkDisplayLabel=NEW MenuLabel(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,16*1},labelSize},"Attack: "+std::to_string(data.baseAtk)+" + "+std::to_string(data.atkGrowthRate).substr(0,3)+" per level",1,ComponentAttr::LEFT_ALIGN|ComponentAttr::SHADOW|ComponentAttr::OUTLINE);
classInfoWindow->AddComponent("Base Stats Text",baseStatsLabel);
classInfoWindow->AddComponent("Health Display Text",healthDisplayLabel);
@ -39,17 +39,17 @@ void Menu::InitializeClassInfoWindow(){
vf2d abilityIconOffsets = {0,32};
CharacterAbilityPreviewComponent*ability1=new CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*0}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability1);
CharacterAbilityPreviewComponent*ability2=new CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*1}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability2);
CharacterAbilityPreviewComponent*ability3=new CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*2}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability3);
CharacterAbilityPreviewComponent*rightClickAbility=new CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*3}+abilityIconOffsets,labelSize*vf2d{1,2}},data.rightClickAbility);
CharacterAbilityPreviewComponent*ability1=NEW CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*0}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability1);
CharacterAbilityPreviewComponent*ability2=NEW CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*1}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability2);
CharacterAbilityPreviewComponent*ability3=NEW CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*2}+abilityIconOffsets,labelSize*vf2d{1,2}},data.ability3);
CharacterAbilityPreviewComponent*rightClickAbility=NEW CharacterAbilityPreviewComponent(CLASS_INFO,{healthDisplayLabelPos+vf2d{0,32*3}+abilityIconOffsets,labelSize*vf2d{1,2}},data.rightClickAbility);
classInfoWindow->AddComponent("Ability 1 Display",ability1);
classInfoWindow->AddComponent("Ability 2 Display",ability2);
classInfoWindow->AddComponent("Ability 3 Display",ability3);
classInfoWindow->AddComponent("Right Click Ability Display",rightClickAbility);
MenuComponent*backButton=new MenuComponent(CLASS_INFO,{{classInfoWindow->center().x/2,healthDisplayLabelPos.y+32*4+abilityIconOffsets.y+12},{classInfoWindow->size.x/2,16}},"Back",[](MenuFuncData data){Menu::CloseMenu();});
MenuComponent*backButton=NEW MenuComponent(CLASS_INFO,{{classInfoWindow->center().x/2,healthDisplayLabelPos.y+32*4+abilityIconOffsets.y+12},{classInfoWindow->size.x/2,16}},"Back",[](MenuFuncData data){Menu::CloseMenu();});
classInfoWindow->AddComponent("Back Button",backButton);
}

@ -71,8 +71,7 @@ public:
data.ability2=&Thief::ability2;
data.ability3=&Thief::ability3;
}else{
std::cout<<"WARNING! Could not get class info for non-existent class "+className+"!";
throw;
ERR("WARNING! Could not get class info for non-existent class "+className+"!")
}
return data;

@ -17,18 +17,18 @@ void Menu::InitializeClassSelectionWindow(){
vf2d outlineSize=classSelectionWindow->size-vf2d{13,13};
MenuLabel*classSelectionLabel=new MenuLabel(CLASS_SELECTION,{{4,20},{outlineSize.x,32}},"Choose a Character Class",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
MenuLabel*classSelectionLabel=NEW MenuLabel(CLASS_SELECTION,{{4,20},{outlineSize.x,32}},"Choose a Character Class",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
classSelectionWindow->AddComponent("Class Selection Title Label",classSelectionLabel);
MenuLabel*outline=new MenuLabel(CLASS_SELECTION,{{4,4},outlineSize},"",1,ComponentAttr::OUTLINE);
MenuLabel*outline=NEW MenuLabel(CLASS_SELECTION,{{4,4},outlineSize},"",1,ComponentAttr::OUTLINE);
classSelectionWindow->AddComponent("Outline Border",outline);
vf2d navigationButtonSize={24*2.5f,16};
MenuComponent*backButton=new MenuComponent(CLASS_SELECTION,{{4+2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Back",[](MenuFuncData data){Menu::CloseMenu();});
MenuComponent*backButton=NEW MenuComponent(CLASS_SELECTION,{{4+2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Back",[](MenuFuncData data){Menu::CloseMenu();});
classSelectionWindow->AddComponent("Back Button",backButton);
MenuComponent*confirmButton=new MenuComponent(CLASS_SELECTION,{{outlineSize.x+4-navigationButtonSize.x-2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Confirm",[](MenuFuncData data){
MenuComponent*confirmButton=NEW MenuComponent(CLASS_SELECTION,{{outlineSize.x+4-navigationButtonSize.x-2,outlineSize.y+4-navigationButtonSize.y-2},navigationButtonSize},"Confirm",[](MenuFuncData data){
std::string selectedClass=data.component->S(A::CLASS_SELECTION);
data.game->ChangePlayerClass(classutils::StringToClass(selectedClass));
GameState::ChangeState(States::OVERWORLD_MAP);
@ -74,14 +74,14 @@ void Menu::InitializeClassSelectionWindow(){
buttonStartPos.y+(buttonSize.y+buttonPadding.y+2*outlineSize.y/9)*float(i/3),
};
vf2d backgroundSize={floor(outlineSize.y/3-buttonPadding.y*3),outlineSize.y/3-buttonPadding.y*3}; //The floor is for fixing a small pixel rounding bug.
MenuLabel*backgroundOutline=new MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,backgroundSize},"",1,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
MenuLabel*classLabel=new MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,buttonSize},className,1,ComponentAttr::SHADOW);
MenuAnimatedIconToggleButton*classSprite=new MenuAnimatedIconToggleButton(CLASS_SELECTION,{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){
MenuLabel*backgroundOutline=NEW MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,backgroundSize},"",1,ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND);
MenuLabel*classLabel=NEW MenuLabel(CLASS_SELECTION,{backgroundOffsetPos,buttonSize},className,1,ComponentAttr::SHADOW);
MenuAnimatedIconToggleButton*classSprite=NEW MenuAnimatedIconToggleButton(CLASS_SELECTION,{backgroundOffsetPos+vf2d{0,12},backgroundSize+vf2d{0,-buttonSize.y-12}},classAnimationName,[](MenuFuncData data){
data.menu.components["Confirm"]->Enable(true);
data.menu.components["Confirm"]->S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION);
});
toggleGroup.push_back(classSprite);
MenuComponent*classButton=new MenuComponent(CLASS_SELECTION,{offsetPos,buttonSize},"Info",CLASS_INFO,
MenuComponent*classButton=NEW MenuComponent(CLASS_SELECTION,{offsetPos,buttonSize},"Info",CLASS_INFO,
[](MenuFuncData data){
data.menu.S(A::CLASS_SELECTION)=data.component->S(A::CLASS_SELECTION);
delete Menu::menus[CLASS_INFO];

@ -1162,7 +1162,7 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
std::string baseSourceDir=tag.data["source"].substr(slashMarkerSourceDir+1);
if(MAP_TILESETS.find("assets/maps/"+baseSourceDir)==MAP_TILESETS.end()){
TSXParser tileset(baseDir+tag.data["source"]);
Renderable*r=new Renderable();
Renderable*r=NEW Renderable();
MAP_TILESETS["assets/maps/"+baseSourceDir].tilewidth=tileset.GetData().tilewidth;
MAP_TILESETS["assets/maps/"+baseSourceDir].tileheight=tileset.GetData().tileheight;
MAP_TILESETS["assets/maps/"+baseSourceDir].tileset=r;
@ -1179,7 +1179,7 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
if(MAP_DATA[map].MapData.optimized){
std::cout<<"Generating optimized map for Map "<<map<<std::endl;
MAP_DATA[map].optimizedTile=new Renderable();
MAP_DATA[map].optimizedTile=NEW Renderable();
MAP_DATA[map].optimizedTile->Create(MAP_DATA[map].MapData.width*MAP_DATA[map].MapData.tilewidth,MAP_DATA[map].MapData.height*MAP_DATA[map].MapData.tileheight);
SetDrawTarget(MAP_DATA[map].optimizedTile->Sprite());
Pixel::Mode prevMode=GetPixelMode();
@ -1470,22 +1470,22 @@ std::map<std::string,std::vector<geom2d::rect<int>>>&Crawler::GetZoneData(MapNam
void Crawler::ChangePlayerClass(Class cl){
switch(cl){
case WARRIOR:{
player.reset(new Warrior(player.get()));
player.reset(NEW Warrior(player.get()));
}break;
case THIEF:{
player.reset(new Thief(player.get()));
player.reset(NEW Thief(player.get()));
}break;
case TRAPPER:{
player.reset(new Trapper(player.get()));
player.reset(NEW Trapper(player.get()));
}break;
case RANGER:{
player.reset(new Ranger(player.get()));
player.reset(NEW Ranger(player.get()));
}break;
case WIZARD:{
player.reset(new Wizard(player.get()));
player.reset(NEW Wizard(player.get()));
}break;
case WITCH:{
player.reset(new Witch(player.get()));
player.reset(NEW Witch(player.get()));
}break;
}
player->hp=player->maxhp=DATA.GetProperty(player->GetClassName()+".BaseHealth").GetInt();
@ -1545,9 +1545,13 @@ datafiledoubledata Crawler::GetDoubleList(std::string key){
int main()
{
Crawler demo;
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4))
demo.Start();
{
Crawler demo;
if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4))
demo.Start();
}
_CrtDumpMemoryLeaks();
return 0;
}
@ -1627,6 +1631,9 @@ bool Crawler::OnUserDestroy(){
delete MAP_DATA[data.first].optimizedTile;
}
}
for(auto&data:GameState::states){
delete data.second;
}
return true;
}
@ -1726,8 +1733,7 @@ void Crawler::BossDamageDealt(int damage){
void Crawler::ReduceBossEncounterMobCount(){
totalBossEncounterMobs--;
if(totalBossEncounterMobs<0){
std::cout<<"WARNING! Boss Encounter mob count is less than zero, THIS SHOULD NOT BE HAPPENING!"<<std::endl;
throw;
ERR("WARNING! Boss Encounter mob count is less than zero, THIS SHOULD NOT BE HAPPENING!");
}
}
@ -1763,8 +1769,7 @@ void Crawler::InitializeGraphics(){
clamping=bool(DATA["Images"][key].GetInt(2));
}
if(!GFX.count(imgFile)&&GFX[imgFile].Load("GFX_Prefix"_S+imgFile,nullptr,filtering,clamping)!=rcode::OK){
std::cout<<" WARNING! Failed to load "+imgFile+"!";
throw;
ERR(" WARNING! Failed to load "+imgFile+"!")
}
}
@ -1828,16 +1833,13 @@ void Crawler::ValidateGameStatus(){
for(IToggleable*item:IToggleable::uninitializedToggleGroupItems){
std::cout<<"\tUninitialized Toggle Item Ptr: 0x"<<std::hex<<item<<std::endl;
}
std::cout<<"Error TOGGLE!!! Please turn on debug_toggleable_items in configuration.txt and re-run the program to see which toggleable item did not properly get a toggleable group set."<<std::endl;
throw;
ERR("Error TOGGLE!!! Please turn on debug_toggleable_items in configuration.txt and re-run the program to see which toggleable item did not properly get a toggleable group set.");
}
if(Unlock::unlocks.size()==0){
std::cout<<"WARNING! There are no unlocks set! This was probably not intentional! It means no areasa on the overworld are accessible!"<<std::endl;
throw;
ERR("WARNING! There are no unlocks set! This was probably not intentional! It means no areasa on the overworld are accessible!");
}
if(!Unlock::IsUnlocked(State_OverworldMap::GetCurrentConnectionPoint())){
std::cout<<"WARNING! The current connection point is not unlocked! This is not supposed to be happening."<<std::endl;
throw;
ERR("WARNING! The current connection point is not unlocked! This is not supposed to be happening.")
}
}

@ -275,6 +275,7 @@
<ClInclude Include="DEFINES.h" />
<ClInclude Include="Effect.h" />
<ClInclude Include="Emitter.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="GameState.h" />
<ClInclude Include="Item.h" />
<ClInclude Include="MenuAnimatedIconToggleButton.h" />

@ -228,6 +228,9 @@
<ClInclude Include="Unlock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Error.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Player.cpp">

@ -0,0 +1,37 @@
#pragma once
#include <ostream>
#ifndef __EMSCRIPTEN__
#include <source_location>
#endif
#ifdef _DEBUG
#define NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
// Replace _NORMAL_BLOCK with _CLIENT_BLOCK if you want the
// allocations to be of _CLIENT_BLOCK type
#else
#define NEW new
#endif
#undef ERR //Stupid Windows
#ifndef __EMSCRIPTEN__
#define ERR(err) { \
std::stringstream errStream; \
errStream<<err; \
Error::log(errStream,std::source_location::current());}
class Error{
public:
inline static void log(std::stringstream&str,std::source_location loc){
std::cout<<loc.file_name()<<"("<<loc.line()<<":"<<loc.column()<<") "<<loc.function_name()<<": "<<str.str()<<std::endl;
throw;
}
};
#else
#define ERR(err) { \
std::stringstream errStream; \
errStream<<err; \
std::cout<<errStream.str(); }
#define _CrtDumpMemoryLeaks() ((int)0)
#endif

@ -3,7 +3,7 @@
#include "State_OverworldMap.h"
#include "State_MainMenu.h"
#define NEW_STATE(state,class) GameState::states[state]=new class();
#define NEW_STATE(state,class) GameState::states[state]=NEW class();
void GameState::Initialize(){
NEW_STATE(States::GAME_RUN,State_GameRun);
@ -11,4 +11,6 @@ void GameState::Initialize(){
NEW_STATE(States::MAIN_MENU,State_MainMenu);
GameState::ChangeState(States::MAIN_MENU);
}
}
GameState::~GameState(){}

@ -2,6 +2,7 @@
#include <map>
#include <iostream>
#include "Crawler.h"
#include "Error.h"
INCLUDE_game
@ -17,6 +18,7 @@ class GameState{
public:
inline static GameState*STATE=nullptr;
inline static std::map<States::State,GameState*>states;
virtual ~GameState();
static void Initialize();
virtual void OnStateChange(GameState*prevState)=0;
virtual void OnUserUpdate(Crawler*game)=0;
@ -24,8 +26,7 @@ public:
static inline void ChangeState(States::State newState){
GameState*prevState=STATE;
if(!states.count(newState)){
std::cout<<"WARNING! State not defined for state "<<newState<<"!"<<std::endl;
throw;
ERR("WARNING! State not defined for state "<<newState<<"!")
}
STATE=states.at(newState);
game->camera.SetTarget(game->GetPlayer()->GetPos());

@ -21,18 +21,17 @@ protected:
removedCount+=std::erase(keyboardButtonList,button);
if(removedCount!=2){
std::cout<<"WARNING! Attempted to remove buttons from button listing, but not found!";
throw;
;
}
if(buttonList.size()==0){
if(!Menu::menus[button->parentMenu]->buttons.erase(button->GetPos().y)){
std::cout<<"WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!";
throw;
ERR("WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!")
}
}
if(keyboardButtonList.size()==0){
if(!Menu::menus[button->parentMenu]->keyboardButtons.erase(button->GetPos().y)){
std::cout<<"WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!";
throw;
ERR("WARNING! Attempted to erase key "<<button->GetPos().y<<" from button map, but the list still exists!")
}
}
}
@ -76,7 +75,7 @@ protected:
button->UseItem();
};
MenuItemButton*button=new MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
MenuItemButton*button=NEW MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
AddComponent(Menu::menus[parentMenu],"item"+std::to_string(itemIndex),button);
}else
if(components.size()>inv.size()){ //There are empty spots, so let's clean up.

@ -21,7 +21,7 @@ void Menu::InitializeInventoryWindow(){
Menu*inventoryWindow=CreateMenu(INVENTORY,CENTERED,windowSize);
InventoryScrollableWindowComponent*inventory=new InventoryScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){});
InventoryScrollableWindowComponent*inventory=NEW InventoryScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){});
inventoryWindow->AddComponent("inventory",inventory);
Menu::AddInventoryListener(inventory,"Consumables");
Menu::AddInventoryListener(inventory,"Equipment");
@ -30,8 +30,8 @@ void Menu::InitializeInventoryWindow(){
//We don't have to actually populate the inventory list because now when an item gets added, it will automatically add the correct component in for us.
MenuLabel*itemNameLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing+itemSpacing-16)},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW};
MenuLabel*itemNameLabel=NEW MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing+itemSpacing-16)},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW};
inventoryWindow->AddComponent("itemName",itemNameLabel);
MenuLabel*itemDescriptionLabel=new MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing+itemSpacing)},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW};
MenuLabel*itemDescriptionLabel=NEW MenuLabel{INVENTORY,geom2d::rect<float>(vf2d{2,float(initialInvHeight*totalSpacing+itemSpacing)},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW};
inventoryWindow->AddComponent("itemDescription",itemDescriptionLabel);
}

@ -50,8 +50,7 @@ void ItemInfo::InitializeItems(){
if(scriptName!=""){
if(!ITEM_SCRIPTS.count(scriptName)){
std::cout<<"Could not load script "<<scriptName<<" for Item "<<key.first<<"!"<<std::endl;
throw;
ERR("Could not load script "<<scriptName<<" for Item "<<key.first<<"!")
}
}
@ -60,8 +59,7 @@ void ItemInfo::InitializeItems(){
it.description=description;
it.category=category;
if(!ITEM_CATEGORIES.count(it.category)){
std::cout<<"WARNING! Tried to add item "<<it.name<<" to category "<<it.category<<" which does not exist!"<<std::endl;
throw;
ERR("WARNING! Tried to add item "<<it.name<<" to category "<<it.category<<" which does not exist!")
}
ITEM_CATEGORIES.at(it.category).insert(it.name);
it.img=img.Decal();

@ -57,8 +57,7 @@ void Menu::InitializeMenus(){
for(MenuType type=TEST;type<MenuType::ENUM_END;type=MenuType(int(type+1))){
if(menus.count(type)==0){
std::cout<<"WARNING! Menu Type "<<type<<" does not exist!"<<std::endl;
throw;
ERR("WARNING! Menu Type "<<type<<" does not exist!")
}
//Lock up everything once it's done.
menus[type]->buttons.SetInitialized();
@ -79,12 +78,12 @@ void Menu::InitializeMenus(){
std::cout<<"\t\tCreated Inside of Menu: "<<component->memoryLeakInfo.first<<" // Last Component: "<<component->memoryLeakInfo.second<<std::endl;
count++;
}
throw;
ERR("")
}
}
Menu*Menu::CreateMenu(MenuType type,vf2d pos,vf2d size){
menus[type]=new Menu(pos,size);
menus[type]=NEW Menu(pos,size);
lastMenuTypeCreated=type;
return menus.at(type);
}
@ -123,8 +122,7 @@ void Menu::AddComponent(std::string key,MenuComponent*button){
displayComponents.push_back(button);
}
if(components.count(key)){
std::cout<<"WARNING! Key "<<key<<" for this sub-menu already exists! Key names must be unique!"<<std::endl;
throw;
ERR("WARNING! Key "<<key<<" for this sub-menu already exists! Key names must be unique!")
}
button->name=key;
components.Unlock(); //It's possible we can add a component later on, so we will make sure we remove the lock first.
@ -161,8 +159,7 @@ void Menu::MenuSelect(Crawler*game){
if(stack.size()<32){
stack.push_back(menus[buttons[selection.y][selection.x]->menuDest]);//Navigate to the next menu.
}else{
std::cout<<"WARNING! Exceeded menu stack size limit!"<<std::endl;
throw;
ERR("WARNING! Exceeded menu stack size limit!")
}
}
}
@ -614,13 +611,11 @@ void Menu::AddInventoryListener(MenuComponent*component,ITCategory category){
if(inventoryListeners.count(category)){
std::vector<MenuComponent*>&listenerList=inventoryListeners.at(category);
if(std::find(listenerList.begin(),listenerList.end(),component)!=listenerList.end()){
std::cout<<"WARNING! Component "<<component->name<<" has already been added to the "<<category<<" listener list! There should not be any duplicates!!"<<std::endl;
throw;
ERR("WARNING! Component "<<component->name<<" has already been added to the "<<category<<" listener list! There should not be any duplicates!!")
}
listenerList.push_back(component);
}else{
std::cout<<"WARNING! Inventory category "<<category<<" does not exist!"<<std::endl;
throw;
ERR("WARNING! Inventory category "<<category<<" does not exist!")
}
}
@ -632,8 +627,7 @@ void Menu::CloseMenu(){
if(stack.size()>0){
stack.pop_back();
}else{
std::cout<<"WARNING! Trying to close out no menu?? Why are we doing this?"<<std::endl;
throw;
ERR("WARNING! Trying to close out no menu?? Why are we doing this?")
}
}
@ -642,5 +636,17 @@ std::pair<MenuType,std::string>Menu::GetMemoryLeakReportInfo(){
}
void Menu::CloseAllMenus(){
stack.clear();
if(stack.size()>0){
stack.clear();
}else{
ERR("WARNING! Trying to close out no menu?? Why are we doing this?")
}
}
bool Menu::IsMenuOpen(){
return stack.size()>0;
}
void Menu::CleanupAllMenus(){
}

@ -44,11 +44,13 @@ public:
static void OpenMenu(MenuType menu);
static void CloseMenu();
static void CloseAllMenus();
static void CleanupAllMenus();
static std::vector<Menu*>stack;
static std::string themeSelection;
static safeunorderedmap<std::string,Theme>themes;
static std::vector<MenuComponent*>unhandledComponents; //This list contains MenuComponents that are created and haven't been assigned via AddComponent. If we get to the end of menu initialization and there are any components in this vector, we have leaked memory and will report this.
static const vf2d CENTERED;
static bool IsMenuOpen();
safemap<std::string,MenuComponent*>components; //A friendly way to interrogate any component we are interested in.
std::vector<MenuComponent*>displayComponents; //Components that are only for displaying purposes.
static std::map<MenuType,Menu*>menus;

@ -72,7 +72,7 @@ protected:
}
virtual inline MenuComponent*PickUpDraggableItem()override{
if(valid){
MenuItemButton*pickUp=new MenuItemButton(parentMenu,rect,invRef,inventoryIndex,onClick);
MenuItemButton*pickUp=NEW MenuItemButton(parentMenu,rect,invRef,inventoryIndex,onClick);
valid=false;
return pickUp;
}else{

@ -28,7 +28,7 @@ void MonsterData::InitializeMonsterData(){
MonsterName+"_DIE",
};
MonsterData::imgs[id]=new Renderable();
MonsterData::imgs[id]=NEW Renderable();
MonsterData::imgs[id]->Load("assets/monsters/"+MonsterName+".png");
for(int i=0;i<animations.size();i++){

@ -8,7 +8,7 @@ void Pathfinding::Initialize(){
if(nodes!=nullptr){
delete[] nodes;
}
nodes = new sNode[game->GetCurrentMap().width * game->GetCurrentMap().height];
nodes = NEW sNode[game->GetCurrentMap().width * game->GetCurrentMap().height];
for (int x = 0; x < game->GetCurrentMap().width; x++)
for (int y = 0; y < game->GetCurrentMap().height; y++)
{

@ -35,8 +35,8 @@ public:
}
protected:
virtual inline void AfterCreate()override{
upButton=new MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
downButton=new MenuComponent(parentMenu,{rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
upButton=NEW MenuComponent(parentMenu,{vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y+="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
downButton=NEW MenuComponent(parentMenu,{rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){V(A::SCROLL_OFFSET).y-="ThemeGlobal.MenuButtonScrollSpeed"_I;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD);
//Let's use the internal name of this component to add unique names for sub-components.
Menu::menus[parentMenu]->AddComponent(name+upButton->rect.pos.str()+"_"+upButton->rect.size.str(),upButton);
Menu::menus[parentMenu]->AddComponent(name+downButton->rect.pos.str()+"_"+downButton->rect.size.str(),downButton);

@ -7,7 +7,9 @@ INCLUDE_MONSTER_LIST
INCLUDE_game
void State_GameRun::OnStateChange(GameState*prevState){
Menu::CloseAllMenus();
if(Menu::IsMenuOpen()){
Menu::CloseAllMenus();
}
game->GetPlayer()->SetState(State::NORMAL);
};
void State_GameRun::OnUserUpdate(Crawler*game){

@ -16,7 +16,9 @@ State_OverworldMap::State_OverworldMap(){
SetStageMarker("Stage I-I"); //Eventually we will load the game from a file and this will not be necessary. We just set it to this for now.
}
void State_OverworldMap::OnStateChange(GameState*prevState){
Menu::CloseAllMenus();
if(Menu::IsMenuOpen()){
Menu::CloseAllMenus();
}
game->GetPlayer()->SetPos(currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16});
playerTargetPos=currentConnectionPoint->rect.pos+currentConnectionPoint->rect.size/2+vf2d{0,16};
game->GetPlayer()->UpdateWalkingAnimation(DOWN);
@ -78,28 +80,28 @@ void State_OverworldMap::Draw(Crawler*game){
vf2d pos=cp.rect.pos+vf2d{0,cp.rect.size.y-borderThickness}+vf2d{-pulsatingAmt.x,pulsatingAmt.y};
vf2d size={borderThickness+crosshairExtension.x,borderThickness};
game->view.FillRectDecal(pos,size,RED);
pos={pos.x,pos.y-crosshairExtension.y}+vf2d{-pulsatingAmt.x,pulsatingAmt.y};
pos=vf2d{pos.x,pos.y-crosshairExtension.y}+vf2d{-pulsatingAmt.x,pulsatingAmt.y};
size={borderThickness,crosshairExtension.y};
game->view.FillRectDecal(pos,size,RED);
//Lower-Right Corner
pos=cp.rect.pos+vf2d{cp.rect.size.x-borderThickness-crosshairExtension.x,cp.rect.size.y-borderThickness}+vf2d{pulsatingAmt.x,pulsatingAmt.y};
size={borderThickness+crosshairExtension.x,borderThickness};
game->view.FillRectDecal(pos,size,RED);
pos={pos.x+crosshairExtension.x,pos.y-crosshairExtension.y}+vf2d{pulsatingAmt.x,pulsatingAmt.y};
pos=vf2d{pos.x+crosshairExtension.x,pos.y-crosshairExtension.y}+vf2d{pulsatingAmt.x,pulsatingAmt.y};
size={borderThickness,crosshairExtension.y};
game->view.FillRectDecal(pos,size,RED);
//Upper-Left Corner
pos=cp.rect.pos+vf2d{0,0}+vf2d{-pulsatingAmt.x,-pulsatingAmt.y};
size={borderThickness+crosshairExtension.x,borderThickness};
game->view.FillRectDecal(pos,size,RED);
pos={pos.x,pos.y+borderThickness}+vf2d{-pulsatingAmt.x,-pulsatingAmt.y};
pos=vf2d{pos.x,pos.y+borderThickness}+vf2d{-pulsatingAmt.x,-pulsatingAmt.y};
size={borderThickness,crosshairExtension.y};
game->view.FillRectDecal(pos,size,RED);
//Upper-Right Corner
pos=cp.rect.pos+vf2d{cp.rect.size.x-borderThickness-crosshairExtension.x,0}+vf2d{pulsatingAmt.x,-pulsatingAmt.y};
size={borderThickness+crosshairExtension.x,borderThickness};
game->view.FillRectDecal(pos,size,RED);
pos={pos.x+crosshairExtension.x,pos.y+borderThickness}+vf2d{pulsatingAmt.x,-pulsatingAmt.y};
pos=vf2d{pos.x+crosshairExtension.x,pos.y+borderThickness}+vf2d{pulsatingAmt.x,-pulsatingAmt.y};
size={borderThickness,crosshairExtension.y};
game->view.FillRectDecal(pos,size,RED);
break;
@ -113,8 +115,7 @@ void State_OverworldMap::SetStageMarker(std::string connectionName){
return;
}
}
std::cout<<"WARNING! Could not find a connection point with name "<<connectionName<<"!"<<std::endl;
throw;
ERR("WARNING! Could not find a connection point with name "<<connectionName<<"!");
}
ConnectionPoint&State_OverworldMap::ConnectionPointFromIndex(int ind){

@ -5,6 +5,7 @@
#include "Map.h"
#include "olcUTIL_Geometry2D.h"
#include "olcUTIL_DataFile.h"
#include "Error.h"
using namespace olc;
@ -33,6 +34,8 @@ class TSXParser{
TSXParser(std::string file);
};
//#define TSX_PARSER_SETUP
#ifdef TSX_PARSER_SETUP
#undef TSX_PARSER_SETUP
extern bool _DEBUG_MAP_LOAD_INFO;
@ -135,8 +138,7 @@ class TSXParser{
TileCollisionData data;
data.collision=geom2d::rect<int>{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}};
if(parsedTilesetInfo.CollisionData.count(previousTagID)){
if(_DEBUG_MAP_LOAD_INFO)std::cout<<"WARNING! There was already collision data defined for tile "<<previousTagID<<"!"<<std::endl;
throw;
if(_DEBUG_MAP_LOAD_INFO)ERR("WARNING! There was already collision data defined for tile "<<previousTagID<<"!")
}
parsedTilesetInfo.CollisionData[previousTagID]=data;
}

@ -8,18 +8,18 @@ void Menu::InitializeTestMenu(){
data.menu.stack.clear();
};
testMenu->AddComponent("Close",new MenuComponent(TEST,{{24*1,24*1},{24*2,24*1}},"Close",quitWindow));
testMenu->AddComponent("Close",NEW MenuComponent(TEST,{{24*1,24*1},{24*2,24*1}},"Close",quitWindow));
MenuFunc doNothing=[](MenuFuncData data){};
testMenu->AddComponent("Test",new MenuComponent(TEST,{{24*4,24*1},{24*3,24*1}},"Test",doNothing));
testMenu->AddComponent("Test",NEW MenuComponent(TEST,{{24*4,24*1},{24*3,24*1}},"Test",doNothing));
MenuFunc HurtPlayer=[](MenuFuncData data){
data.game->GetPlayer()->Hurt(20,data.game->GetPlayer()->OnUpperLevel(),data.game->GetPlayer()->GetZ());
};
testMenu->AddComponent("Hurt Player",new MenuComponent(TEST,{{24*4,24*3},{24*3,24*1}},"Hurt Player",HurtPlayer));
testMenu->AddComponent("Hurt Player",NEW MenuComponent(TEST,{{24*4,24*3},{24*3,24*1}},"Hurt Player",HurtPlayer));
testMenu->AddComponent("Open SubMenu",new MenuComponent(TEST,{{24*2,24*4.5},{24*4,24*1}},"Open Another\n Menu",TEST_2,doNothing));
testMenu->AddComponent("Open SubMenu",NEW MenuComponent(TEST,{{24*2,24*4.5},{24*4,24*1}},"Open Another\n Menu",TEST_2,doNothing));
}

@ -15,7 +15,7 @@ void Menu::InitializeTestSubMenu(){
data.menu.stack.pop_back();
};
testSubMenu->AddComponent("BACK",new MenuComponent(TEST_2,{{24*1,24*1},{24*2,24*1}},"Go Back",goBack));
testSubMenu->AddComponent("BACK",NEW MenuComponent(TEST_2,{{24*1,24*1},{24*2,24*1}},"Go Back",goBack));
int index=0;
for(auto&theme:Menu::themes){
@ -43,9 +43,9 @@ void Menu::InitializeTestSubMenu(){
}
};
testSubMenu->AddComponent("PREV_THEME",new MenuComponent(TEST_2,{{24*-0.5,24*3},{24*1,24*1}},"<",themePrev));
testSubMenu->AddComponent("PREV_THEME",NEW MenuComponent(TEST_2,{{24*-0.5,24*3},{24*1,24*1}},"<",themePrev));
testSubMenu->AddComponent("THEME_DISPLAY",new MenuLabel(TEST_2,{{24*0.5,24*3},{24*3,24*1}},"Theme\n"+Menu::themes[themeSelection].GetThemeName()));
testSubMenu->AddComponent("THEME_DISPLAY",NEW MenuLabel(TEST_2,{{24*0.5,24*3},{24*3,24*1}},"Theme\n"+Menu::themes[themeSelection].GetThemeName()));
MenuFunc themeNext=[](MenuFuncData data){
data.menu.I(A::INDEXED_THEME)=(size_t(data.menu.I(A::INDEXED_THEME))+1)%themes.size();
@ -60,5 +60,5 @@ void Menu::InitializeTestSubMenu(){
}
};
testSubMenu->AddComponent("NEXT_THEME",new MenuComponent(TEST_2,{{24*3.5,24*3},{24*1,24*1}},">",themeNext));
testSubMenu->AddComponent("NEXT_THEME",NEW MenuComponent(TEST_2,{{24*3.5,24*3},{24*1,24*1}},">",themeNext));
}

@ -17,8 +17,7 @@ public:
}
inline void SetToggleGroup(){
if(toggleGroupInitialized){
std::cout<<"WARNING! Toggle group for this component was set twice for some reason! THIS SHOULD NOT BE HAPPENING!"<<std::endl;
throw;
ERR("WARNING! Toggle group for this component was set twice for some reason! THIS SHOULD NOT BE HAPPENING!")
}
toggleGroupInitialized=true;
std::erase_if(uninitializedToggleGroupItems,[&](IToggleable*item){return this==item;});

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 2559
#define VERSION_BUILD 2592
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -395,6 +395,7 @@ return 0;
#include <algorithm>
#include <array>
#include <cstring>
#include "Error.h"
#pragma endregion
#define PGE_VER 223
@ -1695,7 +1696,7 @@ namespace olc
olc::Sprite* Sprite::Duplicate()
{
olc::Sprite* spr = new olc::Sprite(width, height);
olc::Sprite* spr = NEW olc::Sprite(width, height);
std::memcpy(spr->GetData(), GetData(), width * height * sizeof(olc::Pixel));
spr->modeSample = modeSample;
return spr;
@ -1703,7 +1704,7 @@ namespace olc
olc::Sprite* Sprite::Duplicate(const olc::vi2d& vPos, const olc::vi2d& vSize)
{
olc::Sprite* spr = new olc::Sprite(vSize.x, vSize.y);
olc::Sprite* spr = NEW olc::Sprite(vSize.x, vSize.y);
for (int y = 0; y < vSize.y; y++)
for (int x = 0; x < vSize.x; x++)
spr->SetPixel(x, y, GetPixel(vPos.x + x, vPos.y + y));
@ -5272,12 +5273,12 @@ namespace olc
std::wstring ConvertS2W(std::string s)
{
#ifdef __MINGW32__
wchar_t* buffer = new wchar_t[s.length() + 1];
wchar_t* buffer = NEW wchar_t[s.length() + 1];
mbstowcs(buffer, s.c_str(), s.length());
buffer[s.length()] = L'\0';
#else
int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
wchar_t* buffer = new wchar_t[count];
wchar_t* buffer = NEW wchar_t[count];
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
#endif
std::wstring w(buffer);
@ -5493,12 +5494,12 @@ namespace olc
std::wstring ConvertS2W(std::string s)
{
#ifdef __MINGW32__
wchar_t* buffer = new wchar_t[s.length() + 1];
wchar_t* buffer = NEW wchar_t[s.length() + 1];
mbstowcs(buffer, s.c_str(), s.length());
buffer[s.length()] = L'\0';
#else
int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
wchar_t* buffer = new wchar_t[count];
wchar_t* buffer = NEW wchar_t[count];
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count);
#endif
std::wstring w(buffer);
@ -5711,12 +5712,12 @@ namespace olc
DragQueryFile(drop, i, dfbuffer, 256);
#ifdef UNICODE
#ifdef __MINGW32__
char* buffer = new char[len + 1];
char* buffer = NEW char[len + 1];
wcstombs(buffer, dfbuffer, len);
buffer[len] = '\0';
#else
int count = WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, NULL, 0, NULL, NULL);
char* buffer = new char[count];
char* buffer = NEW char[count];
WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, buffer, count, NULL, NULL);
#endif
vFiles.push_back(std::string(buffer));

@ -61,6 +61,7 @@ David Barr, aka javidx9, <EFBFBD>OneLoneCoder 2019, 2020, 2021, 2022
#include <fstream>
#include <stack>
#include <sstream>
#include "Error.h"
int operator ""_I(const char*key,std::size_t len);
@ -87,8 +88,7 @@ namespace olc::utils
inline const std::string GetString(const size_t nItem = 0) const
{
if (nItem >= m_vContent.size()){
std::cout<<"WARNING! Accesing out-of-bounds list item "<<nItem<<" of "<<lastAccessedProperty<<"!"<<std::endl;
throw;
ERR("WARNING! Accesing out-of-bounds list item "<<nItem<<" of "<<lastAccessedProperty<<"!");
return "";
}
else {
@ -168,8 +168,7 @@ namespace olc::utils
if (HasProperty(sProperty))
return operator[](sProperty).GetProperty(name.substr(x + 1, name.size()));
else {
std::cout<<"WARNING! Could not read Property "<<sProperty<<"! Potential bugs may occur."<<std::endl;
throw;
ERR("WARNING! Could not read Property " << sProperty << "! Potential bugs may occur.")
return operator[](sProperty);
}
}
@ -434,8 +433,7 @@ namespace olc::utils
}
// File not found, so fail
std::cout<<"WARNING! Could not open file "<<sFileName<<"!"<<std::endl;
throw;
ERR("WARNING! Could not open file "<<sFileName<<"!");
return false;
}
@ -446,8 +444,7 @@ namespace olc::utils
if (m_mapObjects.count(name) == 0)
{
if(INITIAL_SETUP_COMPLETE){
std::cout<<"WARNING! Key "<<name<<" does not exist in datafile!"<<std::endl; //We're not going to allow manual creation of nodes.
throw;
ERR("WARNING! Key "<<name<<" does not exist in datafile!") //We're not going to allow manual creation of nodes.
}
// ...it did not! So create this object in the map. First get a vector id
// and link it with the name in the unordered_map

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 MiB

After

Width:  |  Height:  |  Size: 6.7 MiB

File diff suppressed because one or more lines are too long

Binary file not shown.

@ -1,4 +1,5 @@
#pragma once
#include "Error.h"
//A class that has an initialization lock so that when the lock is activated, any further gets that are missing items in it will report themselves for easier debugging detection.
template<typename T,typename O>
@ -8,15 +9,13 @@ class safemap{
public:
O&operator[](T key){
if(initialized&&map.count(key)==0){
std::cout<<"WARNING! Trying to get non-existent key "<<key<<"!"<<std::endl;
throw;
ERR("WARNING! Trying to get non-existent key "<<key<<"!")
}
if(!initialized){
size_t originalSize=map.size();
O&val=map[key];
if(originalSize==map.size()){
std::cout<<"WARNING! A previously set value has been overwritten! Key: "<<key<<std::endl;
throw;
ERR("WARNING! A previously set value has been overwritten! Key: "<<key)
}
return val;
}else{
@ -65,15 +64,13 @@ class safeunorderedmap{
public:
O&operator[](T key){
if(initialized&&map.count(key)==0){
std::cout<<"WARNING! Trying to get non-existent key "<<key<<"!"<<std::endl;
throw;
ERR("WARNING! Trying to get non-existent key "<<key<<"!")
}
if(!initialized){
size_t originalSize=map.size();
map[key]=items.size();
if(originalSize==map.size()){
std::cout<<"WARNING! A previously set value has been overwritten! Key: "<<key<<std::endl;
throw;
ERR("WARNING! A previously set value has been overwritten! Key: "<<key)
}
items.push_back({});
return items[map[key]];

Binary file not shown.
Loading…
Cancel
Save