Sketching rc.
This commit is contained in:
parent
aff2fe2a2b
commit
b5e6f1c502
81
sketching/september_2025/dll_rc/dll_rc.dm
Normal file
81
sketching/september_2025/dll_rc/dll_rc.dm
Normal file
@ -0,0 +1,81 @@
|
||||
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
|
||||
Loading…
Reference in New Issue
Block a user