Skip to content

Commit

Permalink
experimental structure cache improvements (2x speed?)
Browse files Browse the repository at this point in the history
  • Loading branch information
InfinityDevTech committed Oct 4, 2024
1 parent 6e261bb commit f83bb81
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 8 deletions.
36 changes: 36 additions & 0 deletions js_src/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export function do_classify_find(room_name) {
let room = Game.rooms[room_name];

if (room) {
let res = room.find(FIND_STRUCTURES);

let all_structures = [];
let repairable = [];
let container = [];
let link = [];

res.forEach((structure) => {
all_structures.push(structure);

//let can_own = switch(structure.structureType) {
// case:
//}

if (structure.hits < structure.hitsMax && structure.structureType != STRUCTURE_WALL) {
repairable.push(structure)
}

if (structure.structureType == STRUCTURE_LINK) {
link.push(structure)
}

if (structure.structureType == STRUCTURE_CONTAINER) {
container.push(structure);
}
})

return [all_structures, repairable, container, link];
} else {
return [];
}
}
1 change: 1 addition & 0 deletions js_tools/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function run_wasm_pack(extra_options) {
async function run_rollup(use_terser) {
const bundle = await rollup({
input: 'js_src/main.js',

plugins: [
commonjs(),
nodeResolve(),
Expand Down
35 changes: 35 additions & 0 deletions src/room/cache/experimental_structures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use std::str::FromStr;

use js_sys::{Array, JsString};
use screeps::{RoomName, StructureContainer, StructureLink, StructureObject};
use wasm_bindgen::prelude::*;

#[wasm_bindgen(module = "test")]
extern "C" {
// Returns an array 4 long:
// 0 - All Structures
// 1 - Repairable
// 2 - Container
// 3 - Link
fn do_classify_find(room_name: JsString) -> Array;
}

pub fn do_find(room_name: &RoomName) -> (Vec<StructureObject>, Vec<StructureObject>, Vec<StructureContainer>, Vec<StructureLink>) {
let res = do_classify_find(JsString::from_str(room_name.to_string().as_str()).unwrap());

if res.length() == 0 {
return (vec![], vec![], vec![], vec![]);
}

let all_js: Array = res.get(0).into();
let repairable_js: Array = res.get(1).into();
let container: Array = res.get(2).into();
let links: Array = res.get(3).into();

let all_rs: Vec<StructureObject> = all_js.iter().map(|structure| structure.into()).collect();
let repairable_rs: Vec<StructureObject> = repairable_js.iter().map(|structure| structure.into()).collect();
let container_rs: Vec<StructureContainer> = container.iter().map(|structure| structure.into()).collect();
let links_rs: Vec<StructureLink> = links.iter().map(|structure| structure.into()).collect();

(all_rs, repairable_rs, container_rs, links_rs)
}
8 changes: 8 additions & 0 deletions src/room/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod resources;
pub mod traffic;
pub mod terminals;
pub mod stats;
pub mod experimental_structures;

pub struct RoomCache {
pub rooms: HashMap<RoomName, CachedRoom>,
Expand Down Expand Up @@ -132,6 +133,9 @@ impl CachedRoom {
let pre_structures = game::cpu::get_used();
let mut structures = RoomStructureCache::new_from_room(room, &mut resources, memory, &mut room_heap);
let total_structures = game::cpu::get_used() - pre_structures;
let pre_new_structures = game::cpu::get_used();
//structures.new_refresh_structure_cache(&mut resources, memory);
let total_new_structures = game::cpu::get_used() - pre_new_structures;
let pre_creeps = game::cpu::get_used();
let creeps = CreepCache::new_from_room(room, memory, &structures, owning_room);
let total_creeps = game::cpu::get_used() - pre_creeps;
Expand Down Expand Up @@ -197,6 +201,10 @@ impl CachedRoom {

cached.stats.cpu_cache = game::cpu::get_used() - pre_cache_cpu;

if cached.room.my() {
info!("[CACHE] Room {} took {} for old {} for new.", room.name(), total_structures, total_new_structures);
}

//if cached.room.my() {
// info!(" Creation for room {} took {:.2} CPU.", room.name(), game::cpu::get_used() - pre_cache_cpu);
// info!(" Structures took {:.2} - Creeps took {:.2} - Resources took {:.2}", total_structures, total_creeps, total_resource);
Expand Down
126 changes: 123 additions & 3 deletions src/room/cache/structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
#[cfg(feature = "season1")]
use screeps::ScoreCollector;

use super::resources::RoomResourceCache;
use super::{experimental_structures::do_find, resources::RoomResourceCache};

#[derive(Debug, Clone)]
pub struct CachedRoomContainers {
Expand Down Expand Up @@ -171,7 +171,7 @@ impl RoomStructureCache {
cache.controller = Some(controller);
}

cache.refresh_structure_cache(resource_cache, memory);
cache.new_refresh_structure_cache(resource_cache, memory);

#[cfg(feature = "season1")]
{
Expand Down Expand Up @@ -464,7 +464,7 @@ impl RoomStructureCache {
}

if let Some(repairable) = structure.as_repairable() {
if repairable.hits() < repairable.hits_max() {
if repairable.hits() < repairable.hits_max() && structure.structure_type() != StructureType::Wall {
self.needs_repair.push(structure.clone());
}
}
Expand Down Expand Up @@ -523,6 +523,126 @@ impl RoomStructureCache {
//}
}

pub fn new_refresh_structure_cache(
&mut self,
resource_cache: &mut RoomResourceCache,
memory: &mut ScreepsMemory,
) {
let room_memory = memory.rooms.get_mut(&self.room.name());

/*
let mut can_structures_be_placed = true;
if let Some(controller) = self.room.controller() {
if !controller.my() {
can_structures_be_placed = false;
}
} else {
can_structures_be_placed = false;
}*/

let mut check_ownable = false;
if let Some(room_memory) = room_memory {
if room_memory.rcl < room_memory.max_rcl {
check_ownable = true;
}
}

let mut has_containers = false;
let mut has_links = false;

let pre_structure = game::cpu::get_used();

let (all_structures, repairables, containers, links) = do_find(&self.room.name());

self.needs_repair = repairables;
for container in containers {
self.containers.insert(container.id(), container);
}
for link in links {
self.links.insert(link.id(), link);
}

// TODO:
// Roads decay every 1k ticks, and containers every 500 (100 in remotes), so we can probably cut down what we are iterating
for structure in all_structures {
let ty = structure.structure_type();
let entry = self
.structures_at_pos
.entry(structure.pos().xy())
.or_default();
if !entry.contains(&ty) {
entry.push(ty);
}

//if self.skip_check(can_structures_be_placed, &structure) {
// continue;
//}

// Dont to the is_active check UNLESS we downgraded.
// Its very expensive from what I have heard.
// This information has been reported by: Gadjung
if check_ownable && !structure.is_active() {
self.inactive_structures.push(structure);

info!("Inactive structure found: {:?}", false);

continue;
}

// TODO: Improve this code...
if let Some(ownable) = structure.as_owned() {
if !ownable.my() && ty != StructureType::InvaderCore {
continue;
}
}

self.classify_structure(
resource_cache,
structure,
&mut has_links,
&mut has_containers,
);
}

let structure_used = game::cpu::get_used() - pre_structure;

let pre_container = game::cpu::get_used();
if has_containers {
self.process_containers(resource_cache);
}
let container_used = game::cpu::get_used() - pre_container;

let pre_link = game::cpu::get_used();
if has_links {
self.process_links(resource_cache);
}
let link_used = game::cpu::get_used() - pre_link;

let pre_csite = game::cpu::get_used();
let mut csites = Vec::new();
for csite in self.room.find(find::CONSTRUCTION_SITES, None) {
let entry = self.structures_at_pos.entry(csite.pos().xy()).or_default();
if !entry.contains(&csite.structure_type()) {
entry.push(csite.structure_type());
}

csites.push(csite)
}
self.construction_sites = csites;
let csite_used = game::cpu::get_used() - pre_csite;

let pre_ruin = game::cpu::get_used();
let ruins = self.room.find(find::RUINS, None).into_iter();
for ruin in ruins {
self.ruins.insert(ruin.id(), ruin);
}
let ruin_used = game::cpu::get_used() - pre_ruin;

//if self.room.my() {
// info!(" Structures used: {:.2} - Containers: {:.2} - Links: {:.2} - Csites: {:.2} - Ruins: {:.2}", structure_used, container_used, link_used, csite_used, ruin_used);
//}
}

pub fn process_links(&mut self, resource_cache: &mut RoomResourceCache) {
//if self.classified_links.is_some() {
// return &self.classified_links.as_ref().unwrap();
Expand Down
10 changes: 5 additions & 5 deletions src/room/spawning/creep_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,23 @@ pub fn miner_body(room: &Room, cache: &CachedRoom, is_remote: bool, source_parts

#[cfg_attr(feature = "profile", screeps_timing_annotate::timing)]
pub fn mineral_miner_body(room: &Room, cache: &CachedRoom) -> Vec<Part> {
let mut body = Vec::new();
let mut body: Vec<Part> = Vec::new();
let stamp = vec![Part::Work, Part::Work, Part::Work, Part::Work, Part::Move];
let cost = get_body_cost(&stamp);

let max_cost = room.energy_capacity_available();
let mut current_cost = cost;
let mut current_cost = 0;

while current_cost < max_cost {
if current_cost + cost > max_cost {
if current_cost + cost > max_cost || body.len() >= 50 {
break;
}

body.extend_from_slice(&stamp);
body.extend(&stamp.clone());
current_cost += cost;
}

stamp
body
}

#[cfg_attr(feature = "profile", screeps_timing_annotate::timing)]
Expand Down

0 comments on commit f83bb81

Please sign in to comment.