partial signals in ruby, gradual adaptation to dynamic resolution

This commit is contained in:
Issac332 2026-07-14 01:41:55 +03:00
parent 0da721aa08
commit 1ddacce66e
20 changed files with 317 additions and 29 deletions

View file

@ -81,6 +81,7 @@ set(MAIN_HEADERS
src/define.h src/define.h
src/signals/signal.h src/signals/signal.h
src/signals/signalconnection.h src/signals/signalconnection.h
src/signals/rubyDispatcher.h
) )
set(MAIN_SOURCE set(MAIN_SOURCE
@ -127,6 +128,7 @@ set(MAIN_SOURCE
src/modloader.cpp src/modloader.cpp
src/sunshine.cpp src/sunshine.cpp
src/lightmap.cpp src/lightmap.cpp
src/signals/rubyDispatcher.cpp
) )
if(WIN32) if(WIN32)
@ -265,6 +267,7 @@ set(BINDING_HEADERS
binding-mri/viewportelement-binding.h binding-mri/viewportelement-binding.h
binding-mri/flashable-binding.h binding-mri/flashable-binding.h
binding-mri/keybindings-binding.h binding-mri/keybindings-binding.h
binding-mri/signalconnection-binding.h
) )
set(BINDING_SOURCE set(BINDING_SOURCE
binding-mri/binding-mri.cpp binding-mri/binding-mri.cpp
@ -294,6 +297,7 @@ set(BINDING_SOURCE
binding-mri/modloader-binding.cpp binding-mri/modloader-binding.cpp
binding-mri/keybindings-binding.cpp binding-mri/keybindings-binding.cpp
binding-mri/lightmap-binding.cpp binding-mri/lightmap-binding.cpp
binding-mri/signalconnection-binding.cpp
) )
source_group("Binding Source" FILES ${BINDING_SOURCE} ${BINDING_HEADERS}) source_group("Binding Source" FILES ${BINDING_SOURCE} ${BINDING_HEADERS})

View file

@ -121,6 +121,7 @@ void tilemapBindingInit();
void windowVXBindingInit(); void windowVXBindingInit();
void tilemapVXBindingInit(); void tilemapVXBindingInit();
void TimeBindingInit(); void TimeBindingInit();
void SignalConnectionBindingInit();
void inputBindingInit(); void inputBindingInit();
void audioBindingInit(); void audioBindingInit();
@ -165,6 +166,7 @@ static void mriBindingInit(){
windowBindingInit(); windowBindingInit();
tilemapBindingInit(); tilemapBindingInit();
TimeBindingInit(); TimeBindingInit();
SignalConnectionBindingInit();
inputBindingInit(); inputBindingInit();
audioBindingInit(); audioBindingInit();
graphicsBindingInit(); graphicsBindingInit();

View file

@ -26,6 +26,12 @@
#include "binding-types.h" #include "binding-types.h"
#include "exception.h" #include "exception.h"
#include "config.h" #include "config.h"
#include "debugwriter.h"
#include "signals/rubydispatcher.h"
#include "signalconnection-binding.h"
#include <vector>
RB_METHOD(graphicsUpdate){ RB_METHOD(graphicsUpdate){
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
@ -208,19 +214,35 @@ DEF_GRA_PROP_B(Frameskip)
_rb_define_module_function(module, prop_name_s "=", graphics##Set##PropName); \ _rb_define_module_function(module, prop_name_s "=", graphics##Set##PropName); \
} }
static VALUE graphicsWindowMoved(VALUE self){
RUBY_CONNECTION
conn->connection = shState->windowSignals.moved.Connect([conn](int x, int y){
shState->rubyDispatcher().invoke([conn, x, y]{
rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(x), INT2NUM(y));
});
});
return TypedData_Wrap_Struct(rb_cRubyConnection, &rubyConnection_type, conn);
}
static VALUE graphicsWindowResized(VALUE self){
RUBY_CONNECTION
conn->connection = shState->windowSignals.resized.Connect([conn](int w, int h){
shState->rubyDispatcher().invoke([conn, w, h]{
rb_funcall(conn->proc, rb_intern("call"), 2, INT2NUM(w), INT2NUM(h));
});
});
return TypedData_Wrap_Struct(rb_cRubyConnection, &rubyConnection_type, conn);
}
void graphicsBindingInit(){ void graphicsBindingInit(){
VALUE module = rb_define_module("Graphics"); VALUE module = rb_define_module("Graphics");
_rb_define_module_function(module, "update", graphicsUpdate); // Signals
_rb_define_module_function(module, "freeze", graphicsFreeze);
_rb_define_module_function(module, "transition", graphicsTransition);
_rb_define_module_function(module, "frame_reset", graphicsFrameReset);
_rb_define_module_function(module, "__reset__", graphicsReset); rb_define_module_function(module, "window_moved", RUBY_METHOD_FUNC(graphicsWindowMoved), 0);
rb_define_module_function(module, "window_resized", RUBY_METHOD_FUNC(graphicsWindowResized), 0);
INIT_GRA_PROP_BIND( FrameRate, "frame_rate" );
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
// Functions
_rb_define_module_function(module, "x", graphicsPosX); _rb_define_module_function(module, "x", graphicsPosX);
_rb_define_module_function(module, "y", graphicsPosY); _rb_define_module_function(module, "y", graphicsPosY);
_rb_define_module_function(module, "width", graphicsWidth); _rb_define_module_function(module, "width", graphicsWidth);
@ -231,7 +253,16 @@ void graphicsBindingInit(){
_rb_define_module_function(module, "snap_to_bitmap", graphicsSnapToBitmap); _rb_define_module_function(module, "snap_to_bitmap", graphicsSnapToBitmap);
_rb_define_module_function(module, "resize_screen", graphicsResizeScreen); _rb_define_module_function(module, "resize_screen", graphicsResizeScreen);
_rb_define_module_function(module, "move_screen", graphicsMoveScreen); _rb_define_module_function(module, "move_screen", graphicsMoveScreen);
_rb_define_module_function(module, "update", graphicsUpdate);
_rb_define_module_function(module, "freeze", graphicsFreeze);
_rb_define_module_function(module, "transition", graphicsTransition);
_rb_define_module_function(module, "frame_reset", graphicsFrameReset);
_rb_define_module_function(module, "__reset__", graphicsReset);
// Variables
INIT_GRA_PROP_BIND( FrameRate, "frame_rate" );
INIT_GRA_PROP_BIND( FrameCount, "frame_count" );
INIT_GRA_PROP_BIND( Brightness, "brightness" ); INIT_GRA_PROP_BIND( Brightness, "brightness" );
INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" ); INIT_GRA_PROP_BIND( Fullscreen, "fullscreen" );
INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" ); INIT_GRA_PROP_BIND( ShowCursor, "show_cursor" );

View file

@ -0,0 +1,59 @@
#include "etc.h"
#include "binding-util.h"
#include "binding-types.h"
#include "debugwriter.h"
#include "sharedstate.h"
#include "signalconnection-binding.h"
void RubyConnection::Disconnect(){
RubyConnection::connection.Disconnect();
}
bool RubyConnection::Connected(){
return RubyConnection::connection.Connected();
}
VALUE rb_cRubyConnection = Qnil;
void rubyConnection_free(void* ptr)
{
RubyConnection* conn = static_cast<RubyConnection*>(ptr);
conn->Disconnect();
delete conn;
}
void rubyConnection_mark(void *ptr)
{
RubyConnection *conn = static_cast<RubyConnection*>(ptr);
if (!NIL_P(conn->proc))
rb_gc_mark(conn->proc);
}
const rb_data_type_t rubyConnection_type = { "RubyConnection", {rubyConnection_mark, rubyConnection_free, 0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY };
static VALUE rubyConnection_alloc(VALUE klass)
{
RubyConnection* ptr = ALLOC(RubyConnection);
return TypedData_Wrap_Struct(klass, &rubyConnection_type, ptr);
}
static VALUE rubyConnectionDisconnect(VALUE self){
RubyConnection* conn;
TypedData_Get_Struct(self, RubyConnection, &rubyConnection_type, conn);
conn->Disconnect();
return Qnil;
}
static VALUE rubyConnectionConnected(VALUE self){
RubyConnection* conn;
TypedData_Get_Struct(self, RubyConnection, &rubyConnection_type, conn);
return rb_bool_new(conn->Connected());
}
void SignalConnectionBindingInit(){
rb_cRubyConnection = rb_define_class("RubyConnection", rb_cObject);
rb_define_alloc_func(rb_cRubyConnection, rubyConnection_alloc);
rb_define_method(rb_cRubyConnection, "disconnect", RUBY_METHOD_FUNC(rubyConnectionDisconnect), 0);
rb_define_method(rb_cRubyConnection, "connected", RUBY_METHOD_FUNC(rubyConnectionConnected), 0);
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "signals/signalconnection.h"
#include <ruby.h>
extern void rubyConnection_free(void* ptr);
extern void rubyConnection_mark(void* ptr);
extern const rb_data_type_t rubyConnection_type;
extern VALUE rb_cRubyConnection;
struct RubyConnection
{
VALUE proc;
SignalConnection connection;
void Disconnect();
bool Connected();
};
#define RUBY_CONNECTION \
if (!rb_block_given_p()) \
rb_raise(rb_eArgError, "unable to connect signal, block required"); \
VALUE proc = rb_block_proc(); \
RubyConnection* conn = new RubyConnection(); \
conn->proc = proc;

View file

@ -2,7 +2,6 @@ class DynamicLight
def initialize(viewport) def initialize(viewport)
@debug_sprite = Sprite.new(viewport) @debug_sprite = Sprite.new(viewport)
@debug_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height) @debug_sprite.bitmap = Bitmap.new(Graphics.width, Graphics.height)
@debug_sprite.bitmap.fill_rect(0, 0, Graphics.width, Graphics.height, Color.new(255, 255, 255))
@debug_sprite.visible = false @debug_sprite.visible = false
@light_sprite = LightMap.new(viewport) @light_sprite = LightMap.new(viewport)
#@light_sprite.wallmap = Bitmap.new($game_map.width, $game_map.height) #@light_sprite.wallmap = Bitmap.new($game_map.width, $game_map.height)
@ -17,6 +16,13 @@ class DynamicLight
# end # end
#end #end
@update_connection = Graphics.window_resized do |w, h|
@debug_sprite.bitmap.rect.width = w;
@debug_sprite.bitmap.rect.height = h;
#@debug_sprite.bitmap.dispose
#@debug_sprite.bitmap = Bitmap.new(w, h)
end
if $light == nil if $light == nil
return return
end end
@ -34,6 +40,7 @@ class DynamicLight
end end
def dispose def dispose
@update_connection.disconnect
@light_sprite.dispose @light_sprite.dispose
end end

View file

@ -19,6 +19,26 @@ class Spriteset_Map
@viewport_lights = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport_lights = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport_flash = Viewport.new(0, 0, Graphics.width, Graphics.height) @viewport_flash = Viewport.new(0, 0, Graphics.width, Graphics.height)
@update_connection = Graphics.window_resized do |w, h|
@viewport.rect.width = w
@viewport.rect.height = h
@viewport_bg.rect.width = w
@viewport_bg.rect.height = h
@viewport_pics.rect.width = w
@viewport_pics.rect.height = h
@viewport_particles.rect.width = w
@viewport_particles.rect.height = h
@viewport_lights.rect.width = w
@viewport_lights.rect.height = h
@viewport_flash.rect.width = w
@viewport_flash.rect.height = h
end
@viewport_bg.z = -500 @viewport_bg.z = -500
@viewport_lights.z = 200 @viewport_lights.z = 200
@viewport_pics.z = 500 @viewport_pics.z = 500
@ -89,6 +109,7 @@ class Spriteset_Map
# * Dispose # * Dispose
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def dispose def dispose
@update_connection.disconnect
# Dispose of tilemap # Dispose of tilemap
@tilemap.tileset.dispose if @tilemap.tileset @tilemap.tileset.dispose if @tilemap.tileset
for i in 0..6 for i in 0..6

View file

@ -18,6 +18,18 @@ class Window_Message < Window_Selectable
self.z = 9999 self.z = 9999
self.back_opacity = 210 self.back_opacity = 210
@update_connection = Graphics.window_resized do |w, h|
self.x = Graphics.width / 2 - 304
case $game_system.message_position
when 0 # up
self.y = 16
when 1 # middle
self.y = Graphics.height / 2 - height / 2
when 2 # down
self.y = Graphics.height - height - 16
end
end
# Animation flags # Animation flags
@fade_in = false @fade_in = false
@fade_out = false @fade_out = false

View file

@ -212,9 +212,11 @@ void EventThread::process(RGSSThreadData &rtData){
//SDL_GL_GetDrawableSize(win, &winW, &winH); //SDL_GL_GetDrawableSize(win, &winW, &winH);
windowSizeMsg.post(Vec2i(winW, winH)); windowSizeMsg.post(Vec2i(winW, winH));
if (shState != nullptr)
shState->windowSignals.resized.Emit(event.window.data1, event.window.data2);
resetInputStates(); resetInputStates();
break; break;
// random meow
case SDL_EVENT_WINDOW_MOUSE_ENTER : case SDL_EVENT_WINDOW_MOUSE_ENTER :
cursorInWindow = true; cursorInWindow = true;
mouseState.inWindow = true; mouseState.inWindow = true;

View file

@ -39,6 +39,7 @@
#include "debugwriter.h" #include "debugwriter.h"
#include "oneshot.h" #include "oneshot.h"
#include "define.h" #include "define.h"
#include "signals/rubydispatcher.h"
#include <SDL3/SDL_video.h> #include <SDL3/SDL_video.h>
#include <SDL3/SDL_timer.h> #include <SDL3/SDL_timer.h>
#include <SDL3_image/SDL_image.h> #include <SDL3_image/SDL_image.h>
@ -616,6 +617,9 @@ Graphics::~Graphics(){
} }
void Graphics::update(bool limitFps){ void Graphics::update(bool limitFps){
// TODO: move this to ruby thread update, idk where it is
shState->rubyDispatcher().process();
p->checkShutDownReset(); p->checkShutDownReset();
p->checkSyncLock(); p->checkSyncLock();
@ -902,6 +906,7 @@ void Graphics::resizeScreen(int width, int height){
FloatRect screenRect(0, 0, width, height); FloatRect screenRect(0, 0, width, height);
p->screenQuad.setTexPosRect(screenRect, screenRect); p->screenQuad.setTexPosRect(screenRect, screenRect);
glState.scissorBox.set(IntRect(0, 0, width, height));
shState->eThread().requestWindowResize(width, height); shState->eThread().requestWindowResize(width, height);
} }

View file

@ -9,7 +9,6 @@
#include "gl-util.h" #include "gl-util.h"
#include "quad.h" #include "quad.h"
#include "transform.h"
#include "shader.h" #include "shader.h"
#include "glstate.h" #include "glstate.h"
#include "quadarray.h" #include "quadarray.h"
@ -33,8 +32,9 @@ struct LightMapPrivate{
std::vector<LightSource> dynamicLightSources; std::vector<LightSource> dynamicLightSources;
std::vector<LightSource> gpuBuffer; std::vector<LightSource> gpuBuffer;
SignalConnection bitmapUpdateConnection;
Quad quad; Quad quad;
Transform trans;
Rect *srcRect; Rect *srcRect;
SignalConnection srcRectCon; SignalConnection srcRectCon;
@ -67,6 +67,15 @@ struct LightMapPrivate{
updateSrcRectCon(); updateSrcRectCon();
prepareCon = shState->graphicsSignals.prepareDraw.Connect(*this, &LightMapPrivate::prepare); prepareCon = shState->graphicsSignals.prepareDraw.Connect(*this, &LightMapPrivate::prepare);
bitmapUpdateConnection = shState->windowSignals.resized.Connect([&](int w, int h){
shState->rubyDispatcher().invoke([&, w, h]{
bitmap = new Bitmap(w, h);
bitmap->ensureNonMega();
*srcRect = bitmap->rect();
onSrcRectChange();
quad.setPosRect(srcRect->toFloatRect());
});
});
bitmap->ensureNonMega(); bitmap->ensureNonMega();
//bitmap->fillRect(0, 0, shState->graphics().width(), shState->graphics().height(), Vec4(0, 0, 0, 1)); //bitmap->fillRect(0, 0, shState->graphics().width(), shState->graphics().height(), Vec4(0, 0, 0, 1));
@ -79,6 +88,7 @@ struct LightMapPrivate{
~LightMapPrivate(){ ~LightMapPrivate(){
srcRectCon.Disconnect(); srcRectCon.Disconnect();
prepareCon.Disconnect(); prepareCon.Disconnect();
bitmapUpdateConnection.Disconnect();
} }
void onSrcRectChange(){ void onSrcRectChange(){
@ -112,17 +122,8 @@ struct LightMapPrivate{
return; return;
/* Compare sprite bounding box against the scene */ /* Compare sprite bounding box against the scene */
/* If sprite is zoomed/rotated, just opt out for now
* for simplicity's sake */
const Vec2 &scale = trans.getScale();
if (scale.x != 1 || scale.y != 1 || trans.getRotation() != 0){
isVisible = true;
return;
}
IntRect self; IntRect self;
self.setPos(trans.getPositionI() - (trans.getOriginI() + sceneOrig)); self.setPos(Vec2i(0, 0));
self.w = bitmap->width(); self.w = bitmap->width();
self.h = bitmap->height(); self.h = bitmap->height();
@ -249,10 +250,6 @@ void LightMap::draw(){
} }
void LightMap::onGeometryChange(const Scene::Geometry &geo){ void LightMap::onGeometryChange(const Scene::Geometry &geo){
/* Offset at which the sprite will be drawn
* relative to screen origin */
p->trans.setGlobalOffset(geo.offset());
p->sceneRect.setSize(geo.rect.size()); p->sceneRect.setSize(geo.rect.size());
p->sceneOrig = geo.orig; p->sceneOrig = geo.orig;
} }

View file

@ -69,6 +69,8 @@ protected:
IntruList<SceneElement> elements; IntruList<SceneElement> elements;
Geometry geometry; Geometry geometry;
SignalConnection resizeConnection;
friend class SceneElement; friend class SceneElement;
friend class Window; friend class Window;
friend class WindowVX; friend class WindowVX;

View file

@ -56,6 +56,9 @@ struct SharedStatePrivate{
SDL_Window *sdlWindow; SDL_Window *sdlWindow;
Scene *screen; Scene *screen;
RubyDispatcher rubyDispatcher;
RenderDispatcher renderDispatcher;
FileSystem fileSystem; FileSystem fileSystem;
EventThread &eThread; EventThread &eThread;
@ -96,6 +99,8 @@ struct SharedStatePrivate{
SharedStatePrivate(RGSSThreadData *threadData) SharedStatePrivate(RGSSThreadData *threadData)
: bindingData(0), : bindingData(0),
sdlWindow(threadData->window), sdlWindow(threadData->window),
rubyDispatcher(),
renderDispatcher(),
fileSystem(threadData->config.allowSymlinks), fileSystem(threadData->config.allowSymlinks),
eThread(*threadData->ethread), eThread(*threadData->ethread),
rtData(*threadData), rtData(*threadData),
@ -194,6 +199,8 @@ void SharedState::setScreen(Scene &screen){
GSATT(void*, bindingData) GSATT(void*, bindingData)
GSATT(SDL_Window*, sdlWindow) GSATT(SDL_Window*, sdlWindow)
GSATT(Scene*, screen) GSATT(Scene*, screen)
GSATT(RubyDispatcher&, rubyDispatcher)
GSATT(RenderDispatcher&, renderDispatcher)
GSATT(FileSystem&, fileSystem) GSATT(FileSystem&, fileSystem)
GSATT(EventThread&, eThread) GSATT(EventThread&, eThread)
GSATT(RGSSThreadData&, rtData) GSATT(RGSSThreadData&, rtData)

View file

@ -23,6 +23,8 @@
#define SHAREDSTATE_H #define SHAREDSTATE_H
#include "signals/signal.h" #include "signals/signal.h"
#include "signals/rubydispatcher.h"
#include "signals/renderdispatcher.h"
#define shState SharedState::instance #define shState SharedState::instance
#define glState shState->_glState() #define glState shState->_glState()
@ -69,6 +71,10 @@ struct SharedState{
WindowSignals windowSignals; WindowSignals windowSignals;
GraphicsSignals graphicsSignals; GraphicsSignals graphicsSignals;
// dispatchers, they redirect signals from another thread to their own
RubyDispatcher &rubyDispatcher() const;
RenderDispatcher &renderDispatcher() const;
// other shit idk // other shit idk
void *bindingData() const; void *bindingData() const;
void setBindingData(void *data); void setBindingData(void *data);

View file

@ -0,0 +1,21 @@
#include "renderdispatcher.h"
void RenderDispatcher::invoke(std::function<void()> fn){
std::lock_guard lock(mutex);
queue.push(std::move(fn));
}
void RenderDispatcher::process(){
std::queue<std::function<void()>> local;
{
std::lock_guard lock(mutex);
std::swap(local, queue);
}
while (!local.empty())
{
local.front()();
local.pop();
}
}

View file

@ -0,0 +1,17 @@
#pragma once
#include <functional>
#include <mutex>
#include <queue>
class RenderDispatcher{
public:
RenderDispatcher() {};
void invoke(std::function<void()> fn);
void process();
private:
std::mutex mutex;
std::queue<std::function<void()>> queue;
};

View file

@ -0,0 +1,21 @@
#include "rubydispatcher.h"
void RubyDispatcher::invoke(std::function<void()> fn){
std::lock_guard lock(mutex);
queue.push(std::move(fn));
}
void RubyDispatcher::process(){
std::queue<std::function<void()>> local;
{
std::lock_guard lock(mutex);
std::swap(local, queue);
}
while (!local.empty())
{
local.front()();
local.pop();
}
}

View file

@ -0,0 +1,17 @@
#pragma once
#include <functional>
#include <mutex>
#include <queue>
class RubyDispatcher{
public:
RubyDispatcher() {};
void invoke(std::function<void()> fn);
void process();
private:
std::mutex mutex;
std::queue<std::function<void()>> queue;
};

View file

@ -40,6 +40,7 @@
#include "tileatlas.h" #include "tileatlas.h"
#include "tilemap-common.h" #include "tilemap-common.h"
#include "sunshine.h" #include "sunshine.h"
#include "signals/rubydispatcher.h"
#include <boost/chrono.hpp> #include <boost/chrono.hpp>
@ -48,6 +49,7 @@
#include <vector> #include <vector>
#include <SDL3/SDL_surface.h> #include <SDL3/SDL_surface.h>
#include <SDL3/SDL_thread.h>
extern const StaticRect autotileRects[]; extern const StaticRect autotileRects[];
@ -250,6 +252,7 @@ struct TilemapPrivate {
} atlas; } atlas;
int viewpW, viewpH; int viewpW, viewpH;
SignalConnection viewpUpdateConnection;
size_t zlayersMax; size_t zlayersMax;
/* Map viewport position */ /* Map viewport position */
@ -328,8 +331,8 @@ struct TilemapPrivate {
mapViewportDirty(false), mapViewportDirty(false),
zOrderDirty(false), zOrderDirty(false),
tilemapReady(false), tilemapReady(false),
viewpW(shState->graphics().width() / 32 + 1), viewpW(shState->graphics().width() / 31 + 2),
viewpH(shState->graphics().height() / 32 + 2), viewpH(shState->graphics().height() / 31 + 2),
zlayersMax(viewpH + 5) zlayersMax(viewpH + 5)
{ {
zlayerVert.resize(zlayersMax); zlayerVert.resize(zlayersMax);
@ -360,6 +363,34 @@ struct TilemapPrivate {
elem.zlayers[i] = new ZLayer(this, viewport); elem.zlayers[i] = new ZLayer(this, viewport);
prepareCon = shState->graphicsSignals.prepareDraw.Connect(*this, &TilemapPrivate::prepare); prepareCon = shState->graphicsSignals.prepareDraw.Connect(*this, &TilemapPrivate::prepare);
viewpUpdateConnection = shState->windowSignals.resized.Connect([&](int w, int h){
shState->rubyDispatcher().invoke([&, w, h]{
if (this->viewport->isDisposed()){
Debug() << "Warning: resize updating of disposed tilemap, disconnecting";
this->viewpUpdateConnection.Disconnect();
return;
}
int oldZLayersCount = zlayersMax;
viewpW = w / 31 + 2;
viewpH = h / 31 + 2;
zlayersMax = viewpH + 5;
zlayerVert.resize(zlayersMax);
zlayerBases.resize(zlayersMax + 1);
if (zlayersMax > oldZLayersCount){
elem.zlayers.resize(zlayersMax);
for (size_t i = oldZLayersCount; i < zlayersMax; ++i)
if (elem.zlayers[i] == nullptr)
elem.zlayers[i] = new ZLayer(this, this->viewport);
}
else{
for (size_t i = zlayersMax; i < oldZLayersCount; ++i)
if (elem.zlayers[i] != nullptr)
delete elem.zlayers[i];
elem.zlayers.resize(zlayersMax);
}
});
});
updateFlashMapViewport(); updateFlashMapViewport();
} }
@ -377,6 +408,7 @@ struct TilemapPrivate {
VBO::del(tiles.vbo); VBO::del(tiles.vbo);
/* Disconnect signal handlers */ /* Disconnect signal handlers */
viewpUpdateConnection.Disconnect();
tilesetCon.Disconnect(); tilesetCon.Disconnect();
for (int i = 0; i < autotileCount; ++i){ for (int i = 0; i < autotileCount; ++i){
autotilesCon[i].Disconnect(); autotilesCon[i].Disconnect();

View file

@ -53,7 +53,6 @@ private:
void composite(); void composite();
void draw(); void draw();
void onGeometryChange(const Geometry &); void onGeometryChange(const Geometry &);
bool isEffectiveViewport(Rect *&, Color *&, Tone *&) const;
void releaseResources(); void releaseResources();
const char *klassName() const { return "viewport"; } const char *klassName() const { return "viewport"; }