Add ability to write on map
Todo: - make ChunkDiffs contain deletions - inserting a " " counts as deletion on chunk level - allow for more unicode characters! ^^ (only harmless ones though - no newline or control characters etc.)
This commit is contained in:
parent
7b5458e1d5
commit
38ab48d6f8
3 changed files with 107 additions and 10 deletions
97
chunks.py
97
chunks.py
|
|
@ -1,12 +1,59 @@
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
from utils import CHUNK_WIDTH, CHUNK_HEIGHT
|
||||||
|
|
||||||
class ChunkDiff():
|
class ChunkDiff():
|
||||||
"""
|
"""
|
||||||
Represents differences between two chunks (changes to be made to a chunk).
|
Represents differences between two chunks (changes to be made to a chunk).
|
||||||
Can be used to transform a chunk into another chunk.
|
Can be used to transform a chunk into another chunk.
|
||||||
|
|
||||||
|
Todo: Implement delete diff
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
@classmethod
|
||||||
|
def combine(cls, diff_a, diff_b):
|
||||||
|
diff = cls()
|
||||||
|
diff.apply(diff_a)
|
||||||
|
diff.apply(diff_b)
|
||||||
|
return diff
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._chars = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, d):
|
||||||
|
diff = cls()
|
||||||
|
diff._chars = d
|
||||||
|
return diff
|
||||||
|
#self._chars = d.copy()
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
return ChunkDiff.from_dict(self.to_dict().copy())
|
||||||
|
|
||||||
|
def combine(self, diff):
|
||||||
|
newdiff = self.copy()
|
||||||
|
newdiff.apply(diff)
|
||||||
|
return newdiff
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return self._chars
|
||||||
|
#return self._chars.copy()
|
||||||
|
|
||||||
|
def set(self, x, y, character):
|
||||||
|
self._chars[x+y*CHUNK_WIDTH] = character
|
||||||
|
|
||||||
|
def delete(self, x, y):
|
||||||
|
del self._chars[x+y*CHUNK_WIDTH]
|
||||||
|
|
||||||
|
def apply(self, diff):
|
||||||
|
for i, c in diff._chars.items():
|
||||||
|
self._chars[i] = c
|
||||||
|
|
||||||
|
def lines(self):
|
||||||
|
d = self._chars
|
||||||
|
s = "".join(d.get(i, " ") for i in range(CHUNK_WIDTH*CHUNK_HEIGHT))
|
||||||
|
return [s[i:i+CHUNK_WIDTH] for i in range(0, CHUNK_WIDTH*CHUNK_HEIGHT, CHUNK_WIDTH)]
|
||||||
|
|
||||||
|
|
||||||
class Chunk():
|
class Chunk():
|
||||||
"""
|
"""
|
||||||
|
|
@ -17,7 +64,35 @@ class Chunk():
|
||||||
- from accumulated changes
|
- from accumulated changes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pass
|
def __init__(self):
|
||||||
|
self._content = ChunkDiff()
|
||||||
|
self._modifications = ChunkDiff()
|
||||||
|
|
||||||
|
self.touch()
|
||||||
|
|
||||||
|
def set(self, x, y, character):
|
||||||
|
self._modifications.set(x, y, character)
|
||||||
|
|
||||||
|
def delete(self, x, y):
|
||||||
|
self._modifications.delete(x, y)
|
||||||
|
|
||||||
|
def commit_changes(self):
|
||||||
|
self._content.apply(self._modifications)
|
||||||
|
self._modifications = ChunkDiff()
|
||||||
|
|
||||||
|
def drop_changes(self):
|
||||||
|
self._modifications = ChunkDiff()
|
||||||
|
|
||||||
|
def get_changes(self):
|
||||||
|
return self._modifications
|
||||||
|
|
||||||
|
def touch(self):
|
||||||
|
self.last_modified = time.time()
|
||||||
|
|
||||||
|
def draw_to(self, x, y, window):
|
||||||
|
for line in self._content.combine(self._modifications).lines():
|
||||||
|
window.addstr(y, x, line)
|
||||||
|
y += 1
|
||||||
|
|
||||||
class ChunkPool():
|
class ChunkPool():
|
||||||
"""
|
"""
|
||||||
|
|
@ -27,6 +102,7 @@ class ChunkPool():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self._chunks = {}
|
||||||
self._lock = threading.RLock()
|
self._lock = threading.RLock()
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
|
|
@ -36,8 +112,17 @@ class ChunkPool():
|
||||||
def __exit__(self, type, value, tb):
|
def __exit__(self, type, value, tb):
|
||||||
self._lock.release()
|
self._lock.release()
|
||||||
|
|
||||||
def load_list(self, coords):
|
def create(self, pos):
|
||||||
pass
|
self._chunks[pos] = Chunk()
|
||||||
|
return self._chunks[pos]
|
||||||
|
|
||||||
def get(self, x, y):
|
def load(self, pos):
|
||||||
pass
|
if not pos in self._chunks:
|
||||||
|
self.create(pos)
|
||||||
|
|
||||||
|
def load_list(self, coords):
|
||||||
|
for pos in coords:
|
||||||
|
self.load(pos)
|
||||||
|
|
||||||
|
def get(self, pos):
|
||||||
|
return self._chunks.get(pos)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import curses
|
import curses
|
||||||
|
import string
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from maps import Map
|
from maps import Map
|
||||||
|
|
@ -60,6 +61,9 @@ class Client():
|
||||||
elif i == "kDN5": self.map_.scroll(0, 10)
|
elif i == "kDN5": self.map_.scroll(0, 10)
|
||||||
elif i == "kLFT5": self.map_.scroll(-20, 0)
|
elif i == "kLFT5": self.map_.scroll(-20, 0)
|
||||||
elif i == "kRIT5": self.map_.scroll(20, 0)
|
elif i == "kRIT5": self.map_.scroll(20, 0)
|
||||||
|
# edit world
|
||||||
|
elif i in string.digits + string.ascii_letters + string.punctuation + " ":
|
||||||
|
self.map_.write(i)
|
||||||
|
|
||||||
else: sys.stdout.write(repr(i) + "\n")
|
else: sys.stdout.write(repr(i) + "\n")
|
||||||
|
|
||||||
|
|
|
||||||
16
maps.py
16
maps.py
|
|
@ -43,7 +43,7 @@ class Map():
|
||||||
with self.chunkpool as pool:
|
with self.chunkpool as pool:
|
||||||
for x in range(chunkx(self.width) + 2): # +2, not +1, or there will be empty gaps
|
for x in range(chunkx(self.width) + 2): # +2, not +1, or there will be empty gaps
|
||||||
for y in range(chunky(self.height) + 2): # in the bottom and right borders
|
for y in range(chunky(self.height) + 2): # in the bottom and right borders
|
||||||
chunk = pool.get(x+chunkx(self.worldx), y+chunky(self.worldy))
|
chunk = pool.get(Position(x+chunkx(self.worldx), y+chunky(self.worldy)))
|
||||||
if chunk:
|
if chunk:
|
||||||
chunk.draw_to(x*CHUNK_WIDTH, y*CHUNK_HEIGHT, self._pad)
|
chunk.draw_to(x*CHUNK_WIDTH, y*CHUNK_HEIGHT, self._pad)
|
||||||
else:
|
else:
|
||||||
|
|
@ -97,14 +97,22 @@ class Map():
|
||||||
|
|
||||||
def write(self, char):
|
def write(self, char):
|
||||||
with self.chunkpool as pool:
|
with self.chunkpool as pool:
|
||||||
chunk = pool.get(chunkx(self.cursorx), chunky(self.cursory))
|
chunk = pool.get(Position(chunkx(self.cursorx), chunky(self.cursory)))
|
||||||
if not chunk:
|
if not chunk:
|
||||||
chunk = pool.create(chunkx(self.cursorx), chunky(self.cursory))
|
chunk = pool.create(Position(chunkx(self.cursorx), chunky(self.cursory)))
|
||||||
|
|
||||||
chunk.setch(inchunkx(self.cursorx), inchunky(self.cursory), char)
|
chunk.set(inchunkx(self.cursorx), inchunky(self.cursory), char)
|
||||||
|
|
||||||
self.move_cursor(1, 0)
|
self.move_cursor(1, 0)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
with self.chunkpool as pool:
|
||||||
|
chunk = pool.get(Position(chunkx(self.cursorx-1), chunky(self.cursory)))
|
||||||
|
if chunk:
|
||||||
|
chunk.delete(inchunkx(self.cursorx-1), inchunky(self.cursory), char)
|
||||||
|
|
||||||
|
self.move_cursor(-1, 0)
|
||||||
|
|
||||||
def move_cursor(self, dx, dy):
|
def move_cursor(self, dx, dy):
|
||||||
self.cursorx += dx
|
self.cursorx += dx
|
||||||
self.cursory += dy
|
self.cursory += dy
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue