deimos-lang/sketching/september_2025/dll_rc/dll_rc.dm
2025-09-22 08:45:31 -05:00

81 lines
1.7 KiB
Plaintext

pub class Rc<T> : Drop, Copy
class Inner<T>(t: T)
mut count = 1
end
inner: &weak Inner = Null
pub ctor(t: T)
inner = Inner(t)
end
ctor(parent: &Self)
parent.inner++
inner = &weak parent.inner
end
pub fn copy() -> Self
Self(self)
end
impl fn drop(self)
if inner.upgrade() is Some(inner) then
inner.count--
if inner.count == 0 then
drop inner
end
else
throw Exception('rc.inner could not be converted from a weak reference')
end
end
end
class Game(player: Player) end
class Player
pub mut game: &weak Game = Null
end
fn circular()
let player = Player()
let game = Game(player)
expectThrows(EmptyWeakReferenceException) {
player.game.upgrade()
}
player.game = &weak game
expectDoesNotThrow {
player.game.upgrade()
}
end
class Board
pub fn flip()
println 'Flipped!'
end
end
class ChessGame(pub board: rc Board) end
class ChessPlayer(pub board: rc Board) end
fn getGameAndPlayer() -> (ChessGame, ChessPlayer)
let board = rc Board() // Rc<Board> count is 1
let game = ChessGame(board) // Rc<Board> copied, count is 2
let player = ChessPlayer(board) // Rc<Board> copied, count is 3
(game, player) // initial Rc<Board> dropped before fn return, count now 2
end
fn playChess()
let (game, player) = getGameAndPlayer()
// Rc<Board> count is 2
let board = game.board // Copy, so count is now 3
board.flip()
drop board // count now 2
drop game // count now 1
drop player // count now 0, board memory finally dropped
end