summaryrefslogtreecommitdiff
path: root/src/editor/editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/editor/editor.cpp')
-rw-r--r--src/editor/editor.cpp161
1 files changed, 120 insertions, 41 deletions
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp
index c96f908..72ca4d2 100644
--- a/src/editor/editor.cpp
+++ b/src/editor/editor.cpp
@@ -2,6 +2,7 @@
#include "../game.h"
#include "../game/object.h"
+#include "properties.h"
GAME_EDITOR* editor = 0;
@@ -31,7 +32,7 @@ void editor_clear_gui_state_refs( GAME_EDITOR* e ) {
e->gui.header_viewtype = 0;
}
-void editor_push_undo_action( GAME_EDITOR* e, const GAME_EDITOR::EDITOR_UNDO_ACTION& action ) {
+void editor_push_undo_action( GAME_EDITOR* e, const EDITOR_UNDO_ACTION& action ) {
if( !e )
return;
@@ -265,11 +266,11 @@ void editor_undo_record_create_walls( GAME_EDITOR* e, I32 start_idx, I32 count )
if( count <= 0 )
return;
- GAME_EDITOR::EDITOR_UNDO_ACTION action{};
+ EDITOR_UNDO_ACTION action{};
action.type = EDITOR_UNDO_CREATE_WALLS;
- action.start_idx = start_idx;
+ action.create.start_idx = start_idx;
for( I32 i = 0; i < count; ++i )
- action.walls.push( map->walls[start_idx + i] );
+ action.create.walls.push( map->walls[start_idx + i] );
editor_push_undo_action( e, action );
}
@@ -282,10 +283,11 @@ void editor_undo_record_create_poly( GAME_EDITOR* e, I32 start_idx ) {
if( start_idx < 0 || start_idx >= (I32)map->polygons.size )
return;
- GAME_EDITOR::EDITOR_UNDO_ACTION action{};
- action.type = EDITOR_UNDO_CREATE_POLY;
- action.start_idx = start_idx;
- action.polys.push( map->polygons[start_idx] );
+ EDITOR_UNDO_ACTION action{
+ .type = EDITOR_UNDO_CREATE_POLY,
+ .create = { .start_idx = start_idx }
+ };
+ action.create.polys.push( map->polygons[start_idx] );
editor_push_undo_action( e, action );
}
@@ -298,10 +300,12 @@ void editor_undo_record_create_sprite( GAME_EDITOR* e, I32 start_idx ) {
if( start_idx < 0 || start_idx >= (I32)map->sprites.size )
return;
- GAME_EDITOR::EDITOR_UNDO_ACTION action{};
- action.type = EDITOR_UNDO_CREATE_SPRITES;
- action.start_idx = start_idx;
- action.sprites.push( map->sprites[start_idx] );
+ EDITOR_UNDO_ACTION action = {
+ .type = EDITOR_UNDO_CREATE_SPRITES,
+ .create = { .start_idx = start_idx }
+ };
+
+ action.create.sprites.push( map->sprites[start_idx] );
editor_push_undo_action( e, action );
}
@@ -314,18 +318,36 @@ void editor_undo_record_create_entity( GAME_EDITOR* e, I32 start_idx ) {
if( start_idx < 0 || start_idx >= (I32)map->entities.size )
return;
- GAME_EDITOR::EDITOR_UNDO_ACTION action{};
- action.type = EDITOR_UNDO_CREATE_ENTITIES;
- action.start_idx = start_idx;
- action.entities.push( map->entities[start_idx] );
+ EDITOR_UNDO_ACTION action{
+ .type = EDITOR_UNDO_CREATE_ENTITIES,
+ .create = { .start_idx = start_idx }
+ };
+ action.create.entities.push( map->entities[start_idx] );
editor_push_undo_action( e, action );
}
-static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_UNDO_ACTION& action ) {
+// NOTE:
+// this is a util func.
+// individual components create records manually
+void editor_undo_record_change_prop( GAME_EDITOR* e, FNV1A hash, void* oldv, void* newv, U32 size ) {
if( !e || !e->map )
- return 0;
+ return;
+
+ EDITOR_UNDO_ACTION rec{ .type = EDITOR_UNDO_EDITPROPS };
+ for( auto e : e->gui.props->curselect ) {
+ EDITOR_UNDO_PROPS::CHANGES changes{};
+
+ changes.props.push( { hash, size, oldv, newv } );
+ changes.obj = (EOBJECT*)e.obj;
+ rec.props.changes.push( changes );
+ }
+
+ e->undo_actions.push( rec );
+}
+
+U8 editor_apply_undo_action_reverse_create( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
WORLD_MAP* map = e->map;
U8 clear_props_select = 0;
U8 clear_view_select = 0;
@@ -333,13 +355,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
switch( action.type ) {
case EDITOR_UNDO_CREATE_WALLS: {
- I32 count = (I32)action.walls.size;
+ I32 count = (I32)action.create.walls.size;
for( I32 i = count - 1; i >= 0; --i ) {
if( !map->walls.size )
break;
- I32 expected = action.start_idx + i;
- I32 idx = editor_find_wall_idx( map, action.walls[i], expected );
+ I32 expected = action.create.start_idx + i;
+ I32 idx = editor_find_wall_idx( map, action.create.walls[i], expected );
if( idx < 0 )
idx = editor_clamp_valid_idx( expected, (I32)map->walls.size );
@@ -350,15 +372,15 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
}
} break;
case EDITOR_UNDO_CREATE_POLY: {
- I32 count = (I32)action.polys.size;
+ I32 count = (I32)action.create.polys.size;
if( count <= 0 )
return 0;
for( I32 i = count - 1; i >= 0; --i ) {
if( !map->polygons.size )
break;
- I32 expected = action.start_idx + i;
- I32 idx = i < (I32)action.polys.size ? editor_find_poly_idx( map, action.polys[i], expected ) : -1;
+ I32 expected = action.create.start_idx + i;
+ I32 idx = i < (I32)action.create.polys.size ? editor_find_poly_idx( map, action.create.polys[i], expected ) : -1;
if( idx < 0 )
idx = editor_clamp_valid_idx( expected, (I32)map->polygons.size );
@@ -369,13 +391,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
}
} break;
case EDITOR_UNDO_CREATE_SPRITES: {
- I32 count = (I32)action.sprites.size;
+ I32 count = (I32)action.create.sprites.size;
for( I32 i = count - 1; i >= 0; --i ) {
if( !map->sprites.size )
break;
- I32 expected = action.start_idx + i;
- I32 idx = editor_find_sprite_idx( map, action.sprites[i], expected );
+ I32 expected = action.create.start_idx + i;
+ I32 idx = editor_find_sprite_idx( map, action.create.sprites[i], expected );
if( idx < 0 )
idx = editor_clamp_valid_idx( expected, (I32)map->sprites.size );
@@ -385,13 +407,13 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
}
} break;
case EDITOR_UNDO_CREATE_ENTITIES: {
- I32 count = (I32)action.entities.size;
+ I32 count = (I32)action.create.entities.size;
for( I32 i = count - 1; i >= 0; --i ) {
if( !map->entities.size )
break;
- I32 expected = action.start_idx + i;
- I32 idx = editor_find_entity_idx( map, action.entities[i], expected );
+ I32 expected = action.create.start_idx + i;
+ I32 idx = editor_find_entity_idx( map, action.create.entities[i], expected );
if( idx < 0 )
idx = editor_clamp_valid_idx( expected, (I32)map->entities.size );
@@ -422,41 +444,88 @@ static U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
return 1;
}
-static U8 editor_apply_undo_action_forward( GAME_EDITOR* e, GAME_EDITOR::EDITOR_UNDO_ACTION& action ) {
+U8 editor_apply_undo_action_reverse_props( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
+ EDITOR_UNDO_PROPS* c = &action.props;
+
+ for( auto it : c->changes ) {
+ EOBJECT* obj = it.obj;
+ for( auto it2 : it.props ) {
+ EDITOR_PROP* p = eprop_from_hash( obj, it2.hash );
+ if( !p ) {
+ dlog( "editor_apply_undo_action_reverse_props() : warn: prop not found %x\n", it2.hash );
+ return 0;
+ }
+
+ void* data = eprop_ptr( p );
+ memcpy( data, it2.oldval.data, p->size );
+ }
+ }
+
+ return 1;
+}
+
+U8 editor_apply_undo_action_reverse( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
if( !e || !e->map )
return 0;
+ if( action.type == EDITOR_UNDO_EDITPROPS )
+ return editor_apply_undo_action_reverse_props( e, action );
+
+ return editor_apply_undo_action_reverse_create( e, action );
+}
+
+U8 editor_apply_undo_action_forward_props( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
+ EDITOR_UNDO_PROPS* c = &action.props;
+
+ for( auto it : c->changes ) {
+ EOBJECT* obj = it.obj;
+ for( auto it2 : it.props ) {
+ EDITOR_PROP* p = eprop_from_hash( obj, it2.hash );
+ if( !p ) {
+ dlog( "editor_apply_undo_action_forward_props() : warn: prop not found %x\n", it2.hash );
+ return 0;
+ }
+
+ void* data = eprop_ptr( p );
+ memcpy( data, it2.newval.data, p->size );
+ }
+ }
+
+ return 1;
+}
+
+U8 editor_apply_undo_action_forward_create( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
WORLD_MAP* map = e->map;
switch( action.type ) {
case EDITOR_UNDO_CREATE_WALLS: {
- if( !action.walls.size )
+ if( !action.create.walls.size )
return 0;
- action.walls.each( fn( MAP_WALL* w ) {
+ action.create.walls.each( fn( MAP_WALL* w ) {
map->walls.push( *w );
} );
} break;
case EDITOR_UNDO_CREATE_POLY: {
- if( !action.polys.size )
+ if( !action.create.polys.size )
return 0;
- action.polys.each( fn( MAP_POLYGON* p ) {
+ action.create.polys.each( fn( MAP_POLYGON* p ) {
map->polygons.push( *p );
} );
} break;
case EDITOR_UNDO_CREATE_SPRITES: {
- if( !action.sprites.size )
+ if( !action.create.sprites.size )
return 0;
- action.sprites.each( fn( MAP_SPRITE* s ) {
+ action.create.sprites.each( fn( MAP_SPRITE* s ) {
map->sprites.push( *s );
} );
} break;
case EDITOR_UNDO_CREATE_ENTITIES: {
- if( !action.entities.size )
+ if( !action.create.entities.size )
return 0;
- action.entities.each( fn( MAP_ENTITY* ent ) {
+ action.create.entities.each( fn( MAP_ENTITY* ent ) {
map->entities.push( *ent );
} );
} break;
@@ -469,11 +538,21 @@ static U8 editor_apply_undo_action_forward( GAME_EDITOR* e, GAME_EDITOR::EDITOR_
return 1;
}
+U8 editor_apply_undo_action_forward( GAME_EDITOR* e, EDITOR_UNDO_ACTION& action ) {
+ if( !e || !e->map )
+ return 0;
+
+ if( action.type == EDITOR_UNDO_EDITPROPS )
+ return editor_apply_undo_action_forward_props( e, action );
+
+ return editor_apply_undo_action_forward_create( e, action );
+}
+
U8 editor_undo( GAME_EDITOR* e ) {
if( !e || !e->map || !e->undo_actions.size )
return 0;
- GAME_EDITOR::EDITOR_UNDO_ACTION action = e->undo_actions.pop();
+ EDITOR_UNDO_ACTION action = e->undo_actions.pop();
if( !editor_apply_undo_action_reverse( e, action ) ) {
e->undo_actions.push( action );
return 0;
@@ -487,7 +566,7 @@ U8 editor_redo( GAME_EDITOR* e ) {
if( !e || !e->map || !e->redo_actions.size )
return 0;
- GAME_EDITOR::EDITOR_UNDO_ACTION action = e->redo_actions.pop();
+ EDITOR_UNDO_ACTION action = e->redo_actions.pop();
if( !editor_apply_undo_action_forward( e, action ) ) {
e->redo_actions.push( action );
return 0;