Skip to content

Commit ecff86f

Browse files
authored
Merge pull request #182 from Poeschl/map-editor
Move map editing and map list to separate pages
2 parents 5267290 + 0ebccb8 commit ecff86f

File tree

19 files changed

+539
-377
lines changed

19 files changed

+539
-377
lines changed

backend/src/main/kotlin/xyz/poeschl/roborush/controller/ConfigRestController.kt

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@ import org.springframework.http.MediaType
77
import org.springframework.security.access.prepost.PreAuthorize
88
import org.springframework.web.bind.annotation.*
99
import org.springframework.web.multipart.MultipartFile
10-
import xyz.poeschl.roborush.controller.restmodels.MapActiveDto
11-
import xyz.poeschl.roborush.controller.restmodels.MapAttributeSaveDto
12-
import xyz.poeschl.roborush.controller.restmodels.MapGenerationResult
13-
import xyz.poeschl.roborush.controller.restmodels.TextConfigDto
10+
import xyz.poeschl.roborush.controller.restmodels.*
1411
import xyz.poeschl.roborush.exceptions.InvalidConfigKeyException
1512
import xyz.poeschl.roborush.exceptions.InvalidHeightMapException
1613
import xyz.poeschl.roborush.exceptions.MapNotFound
1714
import xyz.poeschl.roborush.models.settings.ClientSettings
1815
import xyz.poeschl.roborush.models.settings.SaveSettingDto
1916
import xyz.poeschl.roborush.models.settings.Setting
2017
import xyz.poeschl.roborush.models.settings.SettingKey
21-
import xyz.poeschl.roborush.repositories.Map
2218
import xyz.poeschl.roborush.security.repository.User
2319
import xyz.poeschl.roborush.service.ConfigService
2420
import xyz.poeschl.roborush.service.MapService
@@ -71,18 +67,18 @@ class ConfigRestController(private val configService: ConfigService, private val
7167
@SecurityRequirement(name = "Bearer Authentication")
7268
@PreAuthorize("hasRole('${User.ROLE_ADMIN}')")
7369
@GetMapping("/map", produces = [MediaType.APPLICATION_JSON_VALUE])
74-
fun getMaps(): List<Map> {
75-
return mapService.getAllMaps()
70+
fun getMaps(): List<PlaygroundMap> {
71+
return mapService.getAllMaps().map { PlaygroundMap(it) }
7672
}
7773

7874
@SecurityRequirement(name = "Bearer Authentication")
7975
@PreAuthorize("hasRole('${User.ROLE_ADMIN}')")
8076
@PostMapping("/map/{id}/active", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
81-
fun setMapActive(@PathVariable id: Long, @RequestBody activeDto: MapActiveDto): Map {
77+
fun setMapActive(@PathVariable id: Long, @RequestBody activeDto: MapActiveDto): PlaygroundMap {
8278
val map = mapService.getMap(id)
8379

8480
if (map != null) {
85-
return mapService.setMapActive(map, activeDto.active)
81+
return PlaygroundMap(mapService.setMapActive(map, activeDto.active))
8682
} else {
8783
throw MapNotFound("No matching map found for setting active")
8884
}
@@ -91,11 +87,11 @@ class ConfigRestController(private val configService: ConfigService, private val
9187
@SecurityRequirement(name = "Bearer Authentication")
9288
@PreAuthorize("hasRole('${User.ROLE_ADMIN}')")
9389
@PostMapping("/map/{id}", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
94-
fun setMapAttributes(@PathVariable id: Long, @RequestBody attributes: MapAttributeSaveDto): Map {
90+
fun setMapAttributes(@PathVariable id: Long, @RequestBody attributes: MapAttributeSaveDto): PlaygroundMap {
9591
val map = mapService.getMap(id)
9692

9793
if (map != null) {
98-
return mapService.setMapAttributes(map, attributes)
94+
return PlaygroundMap(mapService.setMapAttributes(map, attributes))
9995
} else {
10096
throw MapNotFound("No matching map found for given id.")
10197
}

backend/src/main/kotlin/xyz/poeschl/roborush/controller/GameRestController.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class GameRestController(private val gameHandler: GameHandler) {
1818

1919
@GetMapping("/map", produces = [MediaType.APPLICATION_JSON_VALUE])
2020
fun getMap(): PlaygroundMap {
21-
return gameHandler.getCurrentPlaygroundMap()
21+
return PlaygroundMap(gameHandler.getCurrentMap())
2222
}
2323

2424
@Operation(

backend/src/main/kotlin/xyz/poeschl/roborush/controller/restmodels/MapDtos.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ data class PlaygroundMap(
2525
val maxHeight: Int
2626
) {
2727

28-
constructor(map: Map, minHeight: Int, maxHeight: Int) : this(
28+
constructor(map: Map) : this(
2929
map.id!!,
3030
map.mapName,
3131
map.size,
@@ -35,7 +35,7 @@ data class PlaygroundMap(
3535
map.solarChargeRate,
3636
map.active,
3737
map.mapData,
38-
minHeight,
39-
maxHeight
38+
minHeight = map.mapData.minOf { it.height },
39+
maxHeight = map.mapData.maxOf { it.height }
4040
)
4141
}

backend/src/main/kotlin/xyz/poeschl/roborush/gamelogic/GameHandler.kt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import org.springframework.cache.annotation.CacheEvict
55
import org.springframework.cache.annotation.Cacheable
66
import xyz.poeschl.roborush.configuration.GameLogic
77
import xyz.poeschl.roborush.controller.WebsocketController
8-
import xyz.poeschl.roborush.controller.restmodels.PlaygroundMap
98
import xyz.poeschl.roborush.exceptions.PositionNotAllowedException
109
import xyz.poeschl.roborush.exceptions.PositionOutOfMapException
1110
import xyz.poeschl.roborush.gamelogic.actions.RobotAction
@@ -46,16 +45,6 @@ class GameHandler(
4645
return mapHandler.getMapWithPositions(getGlobalKnownPositions())
4746
}
4847

49-
@Cacheable("playgroundMap")
50-
fun getCurrentPlaygroundMap(): PlaygroundMap {
51-
val fullMap = mapHandler.getCurrentFullMap()
52-
53-
val minHeight = fullMap.mapData.minOf { it.height }
54-
val maxHeight = fullMap.mapData.maxOf { it.height }
55-
56-
return PlaygroundMap(getCurrentMap(), minHeight, maxHeight)
57-
}
58-
5948
fun getTileAtPosition(position: Position): Tile {
6049
return mapHandler.getTileAtPosition(position)
6150
}
@@ -129,7 +118,7 @@ class GameHandler(
129118
}
130119
}
131120

132-
@CacheEvict(cacheNames = ["knownMap", "playgroundMap"], allEntries = true)
121+
@CacheEvict(cacheNames = ["knownMap"], allEntries = true)
133122
fun executeAllRobotActions() {
134123
robotHandler.executeRobotActions(this)
135124
setGameTurn(currentTurn + 1)

backend/src/test/kotlin/xyz/poeschl/roborush/gamelogic/GameHandlerTest.kt

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -68,37 +68,6 @@ class GameHandlerTest {
6868
assertThat(result.mapData).containsAll(tiles)
6969
}
7070

71-
@Test
72-
fun getCurrentPlaygroundMap() {
73-
// WHEN
74-
val tiles = listOf(a(`$Tile`().withHeight(10)), a(`$Tile`().withHeight(50)), a(`$Tile`().withHeight(20)))
75-
val positions = tiles.map { it.position }.toSet()
76-
val map = a(`$Map`().withId(2))
77-
tiles.forEach { map.addTile(it) }
78-
val activeRobot1 = a(`$ActiveRobot`().withKnownPositions(positions))
79-
val activeRobot2 = a(`$ActiveRobot`().withKnownPositions(positions))
80-
81-
every { robotHandler.getAllActiveRobots() } returns setOf(activeRobot1, activeRobot2)
82-
every { mapHandler.getCurrentFullMap() } returns map
83-
every { mapHandler.getMapWithPositions(positions) } returns map
84-
every { configService.getBooleanSetting(SettingKey.TARGET_POSITION_IN_GAMEINFO) } returns a(`$BooleanSetting`().withValue(false))
85-
86-
// THEN
87-
val result = gameHandler.getCurrentPlaygroundMap()
88-
89-
// VERIFY
90-
assertThat(result.id).isEqualTo(map.id)
91-
assertThat(result.mapName).isEqualTo(map.mapName)
92-
assertThat(result.possibleStartPositions).isEqualTo(map.possibleStartPositions)
93-
assertThat(result.targetPosition).isEqualTo(map.targetPosition)
94-
assertThat(result.active).isEqualTo(map.active)
95-
assertThat(result.maxRobotFuel).isEqualTo(map.maxRobotFuel)
96-
assertThat(result.solarChargeRate).isEqualTo(map.solarChargeRate)
97-
assertThat(result.mapData).containsAll(tiles)
98-
assertThat(result.minHeight).isEqualTo(10)
99-
assertThat(result.maxHeight).isEqualTo(50)
100-
}
101-
10271
@Test
10372
fun isPositionValidForMove() {
10473
// WHEN

frontend/src/assets/main.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
@forward "bulma/sass/components/card";
4242
@forward "bulma/sass/components/modal";
4343
@forward "bulma/sass/components/navbar";
44+
@forward "bulma/sass/components/tabs";
4445
@forward "bulma/sass/elements/button";
4546
@forward "bulma/sass/elements/content";
4647
@forward "bulma/sass/elements/delete";

frontend/src/components/MapCanvasComponent.vue

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const cellSize = 16;
2424
const cellBorder = 1;
2525
const specialTileBorderWidth = 4;
2626
const fullTileSize = cellSize + 2 * cellBorder;
27+
const smallCanvasThresholdInPixel = 160;
2728
2829
const mapBorderColor = new Color(0, 0, 0);
2930
const mapColor = new Color(10, 60, 1);
@@ -74,6 +75,7 @@ const heightMap = computed<Tile[]>(() => {
7475
const currentPath = ref<Path>({ points: [] });
7576
const mapTileMinHeight = ref<number>(0);
7677
const mapTileMaxHeight = ref<number>(255);
78+
const smallCanvas = ref<boolean>(false);
7779
7880
const emits = defineEmits<{
7981
(e: "pathUpdate", path: Path): void;
@@ -90,11 +92,9 @@ onMounted(() => {
9092
watch(
9193
() => props.drawablePath,
9294
(newValue) => {
93-
if (newValue) {
94-
currentPath.value.points = [];
95-
emits("pathUpdate", currentPath.value);
96-
redraw();
97-
}
95+
currentPath.value.points = [];
96+
emits("pathUpdate", currentPath.value);
97+
redraw();
9898
},
9999
);
100100
watch(() => props.map, redraw);
@@ -176,6 +176,10 @@ const updateCanvasData = () => {
176176
177177
mapTileMinHeight.value = props.map.minHeight;
178178
mapTileMaxHeight.value = props.map.maxHeight;
179+
180+
if (container.value && container.value.offsetWidth < smallCanvasThresholdInPixel) {
181+
smallCanvas.value = true;
182+
}
179183
}
180184
};
181185
@@ -235,21 +239,31 @@ const drawRobots = () => {
235239
};
236240
237241
const drawTile = (drawContext: CanvasRenderingContext2D, color: Color) => {
238-
drawContext.fillStyle = mapBorderColor.toHex();
239-
drawContext.fillRect(0, 0, fullTileSize, fullTileSize);
240-
drawContext.fillStyle = color.toHex();
241-
drawContext.fillRect(cellBorder, cellBorder, cellSize, cellSize);
242+
if (smallCanvas.value) {
243+
drawContext.fillStyle = color.toHex();
244+
drawContext.fillRect(0, 0, fullTileSize, fullTileSize);
245+
} else {
246+
drawContext.fillStyle = mapBorderColor.toHex();
247+
drawContext.fillRect(0, 0, fullTileSize, fullTileSize);
248+
drawContext.fillStyle = color.toHex();
249+
drawContext.fillRect(cellBorder, cellBorder, cellSize, cellSize);
250+
}
242251
};
243252
244253
const drawTileBorder = (drawContext: CanvasRenderingContext2D, color: Color) => {
245-
drawContext.lineWidth = specialTileBorderWidth;
246-
drawContext.strokeStyle = color.toHex();
247-
drawContext.strokeRect(
248-
cellBorder + specialTileBorderWidth / 2,
249-
cellBorder + specialTileBorderWidth / 2,
250-
cellSize - specialTileBorderWidth,
251-
cellSize - specialTileBorderWidth,
252-
);
254+
if (smallCanvas.value) {
255+
drawContext.fillStyle = color.toHex();
256+
drawContext.fillRect(0, 0, fullTileSize, fullTileSize);
257+
} else {
258+
drawContext.lineWidth = specialTileBorderWidth;
259+
drawContext.strokeStyle = color.toHex();
260+
drawContext.strokeRect(
261+
cellBorder + specialTileBorderWidth / 2,
262+
cellBorder + specialTileBorderWidth / 2,
263+
cellSize - specialTileBorderWidth,
264+
cellSize - specialTileBorderWidth,
265+
);
266+
}
253267
};
254268
255269
const drawRobot = (drawContext: CanvasRenderingContext2D, color: Color) => {
@@ -366,7 +380,6 @@ const pixelOriginOfPosition = (position: Position): PixelPosition => {
366380
367381
.map-container {
368382
position: relative;
369-
min-width: 200px;
370383
width: auto;
371384
height: auto;
372385

frontend/src/components/MapEditModal.vue

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)