Skip to content

Commit

Permalink
Add readonly keyword to write-once class properties
Browse files Browse the repository at this point in the history
Related to #1183.

The readonly keyword helps us to enforce that fundamental properties
of a class do not change (such as the ID of a player, sector, account,
etc.). Once they are defined, they cannot be defined again.

Readonly properties that are passed into the constructor should also
use constructor promotion to further simplify their definition.

Additional notes:

* For attributes that are objects, readonly does _not_ mean constant.
  That is, while the object cannot be overwritten, its internal state
  can still be modified.

* For readonly properties that have an associated getter function, we
  can (and should) remove the getter and simply make the property
  public. This is logically equivalent, but with less overhead. We do
  not do this here because it is a massive change.
  • Loading branch information
hemberger committed May 28, 2022
1 parent ed90f7f commit a9de9d8
Show file tree
Hide file tree
Showing 29 changed files with 146 additions and 154 deletions.
12 changes: 5 additions & 7 deletions src/lib/Default/AbstractSmrAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ abstract class AbstractSmrAccount {
];

protected Smr\Database $db;
protected readonly string $SQL;

protected int $account_id;
protected string $login;
protected string $passwordHash;
protected string $email;
Expand Down Expand Up @@ -74,7 +74,6 @@ abstract class AbstractSmrAccount {
protected string $friendlyColour;
protected string $neutralColour;
protected string $enemyColour;
protected string $SQL;

protected bool $npc;

Expand Down Expand Up @@ -202,14 +201,13 @@ public static function getUserScoreCaseStatement(Smr\Database $db): array {
return ['CASE' => $case, 'IN' => implode(',', $userRankingTypes)];
}

protected function __construct(int $accountID) {
protected function __construct(protected readonly int $accountID) {
$this->db = Smr\Database::getInstance();
$this->SQL = 'account_id = ' . $this->db->escapeNumber($accountID);
$dbResult = $this->db->read('SELECT * FROM account WHERE ' . $this->SQL . ' LIMIT 1');

if ($dbResult->hasRecord()) {
$dbRecord = $dbResult->record();
$this->account_id = $dbRecord->getInt('account_id');

$this->login = $dbRecord->getField('login');
$this->passwordHash = $dbRecord->getField('password');
Expand Down Expand Up @@ -353,7 +351,7 @@ public function updateIP(): void {

// save...first make sure there isn't one for these keys (someone could double click and get error)
$this->db->replace('account_has_ip', [
'account_id' => $this->db->escapeNumber($this->account_id),
'account_id' => $this->db->escapeNumber($this->accountID),
'time' => $this->db->escapeNumber(Smr\Epoch::time()),
'ip' => $this->db->escapeString($curr_ip),
'host' => $this->db->escapeString($host),
Expand Down Expand Up @@ -510,7 +508,7 @@ public function getReferrer(): SmrAccount {
public function log(int $log_type_id, string $msg, int $sector_id = 0): void {
if ($this->isLoggingEnabled()) {
$this->db->insert('account_has_logs', [
'account_id' => $this->db->escapeNumber($this->account_id),
'account_id' => $this->db->escapeNumber($this->accountID),
'microtime' => $this->db->escapeMicrotime(Smr\Epoch::microtime()),
'log_type_id' => $this->db->escapeNumber($log_type_id),
'message' => $this->db->escapeString($msg),
Expand Down Expand Up @@ -661,7 +659,7 @@ public function equals(self $other): bool {
}

public function getAccountID(): int {
return $this->account_id;
return $this->accountID;
}

/**
Expand Down
13 changes: 7 additions & 6 deletions src/lib/Default/AbstractSmrLocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ class AbstractSmrLocation {
protected static array $CACHE_SECTOR_LOCATIONS = [];

protected Smr\Database $db;
protected string $SQL;
protected readonly string $SQL;

protected int $typeID;
protected string $name;
protected ?string $processor;
protected string $image;
Expand Down Expand Up @@ -114,9 +113,12 @@ public static function getLocation(int $locationTypeID, bool $forceUpdate = fals
return self::$CACHE_LOCATIONS[$locationTypeID];
}

protected function __construct(int $locationTypeID, Smr\DatabaseRecord $dbRecord = null) {
protected function __construct(
protected readonly int $typeID,
Smr\DatabaseRecord $dbRecord = null
) {
$this->db = Smr\Database::getInstance();
$this->SQL = 'location_type_id = ' . $this->db->escapeNumber($locationTypeID);
$this->SQL = 'location_type_id = ' . $this->db->escapeNumber($typeID);

if ($dbRecord === null) {
$dbResult = $this->db->read('SELECT * FROM location_type WHERE ' . $this->SQL . ' LIMIT 1');
Expand All @@ -127,12 +129,11 @@ protected function __construct(int $locationTypeID, Smr\DatabaseRecord $dbRecord
$locationExists = $dbRecord !== null;

if ($locationExists) {
$this->typeID = $dbRecord->getInt('location_type_id');
$this->name = $dbRecord->getField('location_name');
$this->processor = $dbRecord->getField('location_processor');
$this->image = $dbRecord->getField('location_image');
} else {
throw new Exception('Cannot find location: ' . $locationTypeID);
throw new Exception('Cannot find location: ' . $typeID);
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/lib/Default/AbstractSmrPlayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ abstract class AbstractSmrPlayer {
protected static array $CACHE_PLAYERS = [];

protected Smr\Database $db;
protected string $SQL;
protected readonly string $SQL;

protected int $accountID;
protected int $gameID;
protected string $playerName;
protected int $playerID;
protected int $sectorID;
Expand Down Expand Up @@ -199,7 +197,11 @@ public static function getPlayerByPlayerName(string $playerName, int $gameID, bo
throw new Smr\Exceptions\PlayerNotFound('Player Name not found.');
}

protected function __construct(int $gameID, int $accountID, Smr\DatabaseRecord $dbRecord = null) {
protected function __construct(
protected readonly int $gameID,
protected readonly int $accountID,
Smr\DatabaseRecord $dbRecord = null
) {
$this->db = Smr\Database::getInstance();
$this->SQL = 'account_id = ' . $this->db->escapeNumber($accountID) . ' AND game_id = ' . $this->db->escapeNumber($gameID);

Expand All @@ -213,8 +215,6 @@ protected function __construct(int $gameID, int $accountID, Smr\DatabaseRecord $
throw new Smr\Exceptions\PlayerNotFound('Invalid accountID: ' . $accountID . ' OR gameID: ' . $gameID);
}

$this->accountID = $accountID;
$this->gameID = $gameID;
$this->playerName = $dbRecord->getField('player_name');
$this->playerID = $dbRecord->getInt('player_id');
$this->sectorID = $dbRecord->getInt('sector_id');
Expand Down
13 changes: 6 additions & 7 deletions src/lib/Default/AbstractSmrPort.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ class AbstractSmrPort {
public const RAZE_PAYOUT = 0.75; // fraction of base payout for razing

protected Smr\Database $db;
protected readonly string $SQL;

protected int $gameID;
protected int $sectorID;
protected int $shields;
protected int $combatDrones;
protected int $armour;
Expand All @@ -53,8 +52,6 @@ class AbstractSmrPort {
protected int $cachedTime;
protected bool $cacheIsValid = true;

protected string $SQL;

protected bool $hasChanged = false;
protected bool $isNew = false;

Expand Down Expand Up @@ -119,7 +116,11 @@ public static function getBaseExperience(int $cargo, int $distance): float {
return ($cargo / 13) * $distance;
}

protected function __construct(int $gameID, int $sectorID, Smr\DatabaseRecord $dbRecord = null) {
protected function __construct(
protected readonly int $gameID,
protected readonly int $sectorID,
Smr\DatabaseRecord $dbRecord = null
) {
$this->cachedTime = Smr\Epoch::time();
$this->db = Smr\Database::getInstance();
$this->SQL = 'sector_id = ' . $this->db->escapeNumber($sectorID) . ' AND game_id = ' . $this->db->escapeNumber($gameID);
Expand All @@ -132,8 +133,6 @@ protected function __construct(int $gameID, int $sectorID, Smr\DatabaseRecord $d
}
$this->isNew = $dbRecord === null;

$this->gameID = $gameID;
$this->sectorID = $sectorID;
if (!$this->isNew) {
$this->shields = $dbRecord->getInt('shields');
$this->combatDrones = $dbRecord->getInt('combat_drones');
Expand Down
12 changes: 5 additions & 7 deletions src/lib/Default/SmrAlliance.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ class SmrAlliance {
protected static array $CACHE_ALLIANCES = [];

protected Smr\Database $db;
protected string $SQL;
protected readonly string $SQL;

protected int $gameID;
protected int $allianceID;
protected string $allianceName;
protected ?string $description;
protected string $password;
Expand Down Expand Up @@ -73,11 +71,11 @@ public static function getAllianceByName(string $name, int $gameID, bool $forceU
throw new Smr\Exceptions\AllianceNotFound('Alliance name not found');
}

protected function __construct(int $allianceID, int $gameID) {
protected function __construct(
protected readonly int $allianceID,
protected readonly int $gameID
) {
$this->db = Smr\Database::getInstance();

$this->allianceID = $allianceID;
$this->gameID = $gameID;
$this->SQL = 'alliance_id=' . $this->db->escapeNumber($allianceID) . ' AND game_id=' . $this->db->escapeNumber($gameID);

if ($allianceID != 0) {
Expand Down
21 changes: 10 additions & 11 deletions src/lib/Default/SmrEnhancedWeaponEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ class SmrEnhancedWeaponEvent {
protected const GRACE_PERIOD = 3600; // 1 hour
protected const DURATION = 21600; // 6 hours

protected int $gameID;
protected int $sectorID;
protected int $locationTypeID;
protected int $expires;
protected SmrWeapon $weapon;
protected readonly SmrWeapon $weapon;

/**
* Return all the valid events for the given location in a sector.
Expand Down Expand Up @@ -114,12 +110,15 @@ private static function getEventFromDatabase(Smr\DatabaseRecord $dbRecord): self
);
}

protected function __construct(int $gameID, int $weaponTypeID, int $locationTypeID, int $sectorID, int $expires, bool $bonusAccuracy, bool $bonusDamage) {
$this->gameID = $gameID;
$this->locationTypeID = $locationTypeID;
$this->sectorID = $sectorID;
$this->expires = $expires;

protected function __construct(
protected readonly int $gameID,
protected readonly int $weaponTypeID,
protected readonly int $locationTypeID,
protected readonly int $sectorID,
protected readonly int $expires,
bool $bonusAccuracy,
bool $bonusDamage
) {
$this->weapon = SmrWeapon::getWeapon($weaponTypeID);
$this->weapon->setBonusDamage($bonusDamage);
$this->weapon->setBonusAccuracy($bonusAccuracy);
Expand Down
15 changes: 7 additions & 8 deletions src/lib/Default/SmrForce.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ class SmrForce {
public const MAX_SDS = 5;

protected Smr\Database $db;
protected string $SQL;
protected readonly string $SQL;

protected int $ownerID;
protected int $sectorID;
protected int $gameID;
protected int $combatDrones = 0;
protected int $scoutDrones = 0;
protected int $mines = 0;
Expand Down Expand Up @@ -103,7 +100,12 @@ public static function tidyUpForces(SmrGalaxy $galaxyToTidy): void {
}
}

protected function __construct(int $gameID, int $sectorID, int $ownerID, Smr\DatabaseRecord $dbRecord = null) {
protected function __construct(
protected readonly int $gameID,
protected readonly int $sectorID,
protected readonly int $ownerID,
Smr\DatabaseRecord $dbRecord = null
) {
$this->db = Smr\Database::getInstance();
$this->SQL = 'game_id = ' . $this->db->escapeNumber($gameID) . '
AND sector_id = ' . $this->db->escapeNumber($sectorID) . '
Expand All @@ -117,9 +119,6 @@ protected function __construct(int $gameID, int $sectorID, int $ownerID, Smr\Dat
}
$this->isNew = $dbRecord === null;

$this->gameID = $gameID;
$this->ownerID = $ownerID;
$this->sectorID = $sectorID;
if (!$this->isNew) {
$this->combatDrones = $dbRecord->getInt('combat_drones');
$this->scoutDrones = $dbRecord->getInt('scout_drones');
Expand Down
15 changes: 8 additions & 7 deletions src/lib/Default/SmrGalaxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ class SmrGalaxy {
public const TYPES = [self::TYPE_RACIAL, self::TYPE_NEUTRAL, self::TYPE_PLANET];

protected Smr\Database $db;
protected string $SQL;
protected readonly string $SQL;

protected int $gameID;
protected int $galaxyID;
protected string $name;
protected int $width;
protected int $height;
Expand All @@ -23,7 +21,7 @@ class SmrGalaxy {
protected int $startSector;

protected bool $hasChanged = false;
protected bool $isNew = false;
protected bool $isNew;

public static function clearCache(): void {
self::$CACHE_GALAXIES = [];
Expand Down Expand Up @@ -68,7 +66,12 @@ public static function createGalaxy(int $gameID, int $galaxyID): self {
return self::$CACHE_GALAXIES[$gameID][$galaxyID];
}

protected function __construct(int $gameID, int $galaxyID, bool $create = false, Smr\DatabaseRecord $dbRecord = null) {
protected function __construct(
protected readonly int $gameID,
protected readonly int $galaxyID,
bool $create = false,
Smr\DatabaseRecord $dbRecord = null
) {
$this->db = Smr\Database::getInstance();
$this->SQL = 'game_id = ' . $this->db->escapeNumber($gameID) . '
AND galaxy_id = ' . $this->db->escapeNumber($galaxyID);
Expand All @@ -81,8 +84,6 @@ protected function __construct(int $gameID, int $galaxyID, bool $create = false,
}
$this->isNew = $dbRecord === null;

$this->gameID = $gameID;
$this->galaxyID = $galaxyID;
if (!$this->isNew) {
$this->name = $dbRecord->getField('galaxy_name');
$this->width = $dbRecord->getInt('width');
Expand Down
9 changes: 4 additions & 5 deletions src/lib/Default/SmrGame.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class SmrGame {

protected Smr\Database $db;

protected int $gameID;
protected string $name;
protected string $description;
protected int $joinTime;
Expand Down Expand Up @@ -81,13 +80,15 @@ public static function createGame(int $gameID): self {
return self::$CACHE_GAMES[$gameID];
}

protected function __construct(int $gameID, bool $create = false) {
protected function __construct(
protected readonly int $gameID,
bool $create = false
) {
$this->db = Smr\Database::getInstance();

$dbResult = $this->db->read('SELECT * FROM game WHERE game_id = ' . $this->db->escapeNumber($gameID) . ' LIMIT 1');
if ($dbResult->hasRecord()) {
$dbRecord = $dbResult->record();
$this->gameID = $dbRecord->getInt('game_id');
$this->name = $dbRecord->getField('game_name');
$this->description = $dbRecord->getField('game_description');
$this->joinTime = $dbRecord->getInt('join_time');
Expand All @@ -105,9 +106,7 @@ protected function __construct(int $gameID, bool $create = false) {
$this->allianceMaxVets = $dbRecord->getInt('alliance_max_vets');
$this->startingCredits = $dbRecord->getInt('starting_credits');
} elseif ($create === true) {
$this->gameID = $gameID;
$this->isNew = true;
return;
} else {
throw new Smr\Exceptions\GameNotFound('No such game: ' . $gameID);
}
Expand Down
12 changes: 6 additions & 6 deletions src/lib/Default/SmrInvitation.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
*/
class SmrInvitation {

private int $allianceID;
private int $gameID;
private int $receiverAccountID;
private int $senderAccountID;
private int $messageID;
private int $expires;
private readonly int $allianceID;
private readonly int $gameID;
private readonly int $receiverAccountID;
private readonly int $senderAccountID;
private readonly int $messageID;
private readonly int $expires;

public static function send(int $allianceID, int $gameID, int $receiverAccountID, int $senderAccountID, int $messageID, int $expires): void {
$db = Smr\Database::getInstance();
Expand Down
Loading

0 comments on commit a9de9d8

Please sign in to comment.