diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-01-01 12:03:58 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-01-01 12:03:58 +0100 |
commit | 8906ff2e2755f6f8a2e52f5252afbcbea248c947 (patch) | |
tree | e684823e99b9182badcb49dd6c2e35409fe40d02 | |
parent | a871e68ebd153d9ab4f9f9e36d7b099689e05c38 (diff) |
instance_destroy that actually works; no more shared_ptr
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | global.h | 5 | ||||
-rw-r--r-- | library.cpp | 8 | ||||
-rw-r--r-- | library.h | 8 | ||||
-rw-r--r-- | main.cpp | 58 | ||||
-rw-r--r-- | src/objects/obj_control.cpp | 10 |
7 files changed, 80 insertions, 20 deletions
@@ -1,5 +1,5 @@ CXX := g++ -CXXFLAGS := -Wall -Wextra -std=c++11 -O2 -fwrapv -I. -I/usr/local/lib +CXXFLAGS := -Wall -Wextra -std=c++11 -g -fwrapv -I. -I/usr/local/lib LIBS := -L/usr/local/lib -lsfml-{system,window,graphics} BIN := game @@ -25,8 +25,9 @@ font_skipped := $(filter-out %.ttf %/LICENSE,$(font_allfiles)) font_obj := $(patsubst src/fonts/%.ttf,build/fonts/%.o,$(font_fnames)) font_externs := $(shell echo $$(for f in $(font_obj); do basename $$f | sed 's/\.[^.]*$$//' | sed 's/.*/extern Font *&;/'; done)) -base_src := $(wildcard *_base.cpp) -base_src += library.cpp sprite.cpp font.cpp main.cpp +special_cpp := object_header_extractor.cpp object_header_maker.cpp object_wrapper.cpp + +base_src := $(filter-out $(special_cpp),$(wildcard *.cpp)) base_obj := $(patsubst %.cpp,build/%.o,$(base_src)) categories := object sprite font @@ -89,7 +90,7 @@ build/objects/%.h: src/objects/%.cpp $(CXX) -E object_header_maker.cpp "-D__OBJECT_NAME__=$(basename $(notdir $<))" "-DEVENT_XLIST=$$($(CXX) -E object_header_extractor.cpp "-D__OBJECT_FNAME__=\"$<\"" | sed 's/__________EVENT_NEWLINE__________/\n/g' | grep -oe '__________EVENT_COUNTER_TAG_[^_]*__________' | sed 's/[^G]*G_\(.*\)__________.*/X(\1)/g' | xargs)" | sed 's/^# [0-9]\+ ".*//' >"$@" build/objects.h: $(object_head) - echo Collecting header files + echo Writing collected objects header echo $(object_head) | xargs -n 1 basename | sed 's,.*,#include "objects/&",' >"$@" @@ -1,2 +1,4 @@ - Group textures together: http://www.sfml-dev.org/tutorials/2.4/graphics-sprite.php#the-importance-of-using-as-few-textures-as-possible +- Throw some kind of exception when calling instance_destroy(this), so the event function + cannot continue executing @@ -1,7 +1,7 @@ #pragma once +#include <set> #include <vector> -#include <memory> #include "object_base.h" @@ -10,5 +10,6 @@ using namespace std; class Global{ public: - vector<shared_ptr<Object>> objects; + set<Object*> objects; + vector<Object*> objects_todelete; }; diff --git a/library.cpp b/library.cpp index 38bbf48..2386c0b 100644 --- a/library.cpp +++ b/library.cpp @@ -20,6 +20,14 @@ public: } } init_object; + +void instance_destroy(Object *obj){ + assert(global.objects.find(obj)!=global.objects.end()); + obj->destroy(); + global.objects_todelete.push_back(obj); +} + + static void draw_text(int x,int y,const char *s,size_t len){ if(currentFont!=nullptr){ sharedSfText.setFont(currentFont->sf_font); @@ -13,13 +13,15 @@ extern sf::RenderWindow window; template <typename ObjT> -shared_ptr<Object> instance_create(int x,int y){ - shared_ptr<Object> ptr(new ObjT(x,y)); - global.objects.push_back(ptr); +Object* instance_create(int x,int y){ + Object *ptr=new ObjT(x,y); + global.objects.insert(ptr); ptr->create(); return ptr; } +void instance_destroy(Object *obj); + void draw_text(int x,int y,const char *s); void draw_textf(int x,int y,const char *format,...) __attribute__((format (printf, 3, 4))); @@ -13,9 +13,10 @@ using namespace std; -static shared_ptr<Object> makeobjectbyname(int x,int y,const char *name){ +__attribute__((unused)) +static Object* makeobjectbyname(int x,int y,const char *name){ -#define X(objname) if(strcmp(name,#objname)==0)return make_shared<objname>(x,y); +#define X(objname) if(strcmp(name,#objname)==0)return new objname(x,y); OBJECT_CLASSES_XLIST #undef X @@ -28,6 +29,37 @@ Global global; sf::RenderWindow window; +void applyObjectChanges(){ + set<Object*> seen; + for(Object *obj : global.objects_todelete){ + if(seen.insert(obj).second){ + delete obj; + global.objects.erase(obj); + } + } + global.objects_todelete.clear(); +} + +void applyObjectChanges(set<Object*>::iterator &it){ + bool incremented=false; + set<Object*> seen; + for(Object *obj : global.objects_todelete){ + if(seen.insert(obj).second){ + delete obj; + if(it!=global.objects.end()&&*it==obj){ + ++it; + incremented=true; + } + global.objects.erase(obj); + } + } + global.objects_todelete.clear(); + if(!incremented){ + ++it; + } +} + + void eventCycle(){ sf::Event event; while(window.pollEvent(event)){ @@ -42,14 +74,18 @@ void eventCycle(){ } } - for(int i=0;i<(int)global.objects.size();i++){ - global.objects[i]->step(); + for(set<Object*>::iterator it=global.objects.begin(); + it!=global.objects.end(); + applyObjectChanges(it)){ + (*it)->step(); } window.clear(sf::Color::White); - for(int i=0;i<(int)global.objects.size();i++){ - global.objects[i]->draw(); + for(set<Object*>::iterator it=global.objects.begin(); + it!=global.objects.end(); + applyObjectChanges(it)){ + (*it)->draw(); } window.display(); @@ -63,15 +99,17 @@ int main(void){ window.create(sf::VideoMode(640,480),GAME_NAME); window.setVerticalSyncEnabled(true); - global.objects.push_back(makeobjectbyname(0,0,"obj_control")); - global.objects[0]->create(); + instance_create<obj_control>(0,0); + applyObjectChanges(); while(window.isOpen()){ eventCycle(); } - for(shared_ptr<Object> p : global.objects){ - p->destroy(); + for(set<Object*>::iterator it=global.objects.begin(); + it!=global.objects.end(); + applyObjectChanges(it)){ + instance_destroy(*it); } } diff --git a/src/objects/obj_control.cpp b/src/objects/obj_control.cpp index 66b481c..87c685d 100644 --- a/src/objects/obj_control.cpp +++ b/src/objects/obj_control.cpp @@ -1,12 +1,13 @@ OUT #include <cstdlib> static double yd=0; +static Object *hoiobj; EVENT(create){ draw_set_font(fnt_liber); x=10; y=240; - instance_create<obj_hoi>(20,20); + hoiobj=instance_create<obj_hoi>(20,20); } EVENT(step){ @@ -14,6 +15,13 @@ EVENT(step){ y+=yd; yd+=(double)rand()/RAND_MAX*2-y/240; yd*=0.99; + + if(x==100){ + instance_destroy(hoiobj); + } else if(x==200){ + instance_destroy(this); + return; + } } EVENT(draw){ |