前回は、こんなコードを書きました。
main.rs
use std::collections::HashMap;
use rand;
#[derive(Debug)]
struct Position {
x: i32,
y: i32,
}
#[derive(Debug)]
struct Velocity {
x: i32,
y: i32,
}
fn main() {
// idは配列の要素数を表す
let mut id = 0;
// ベクタをやめて、ハッシュマップで宣言する
// Position構造体のハッシュマップ
let mut pos_ary: HashMap<u32, Position> = HashMap::new();
// Velocity構造体のハッシュマップ
let mut vel_ary: HashMap<u32, Velocity> = HashMap::new();
// 効果を確かめるために、2回づつ create_entity を呼び出す
// Positionコンポーネントのみ
for i in 0..2 {
let (x, y) = rand::random();
let key = create_entity(&mut id);
add_component(&key, &mut pos_ary, Position { x, y });
}
// Velocityコンポーネントのみ
for i in 0..2 {
let (x, y) = rand::random();
let key = create_entity(&mut id);
add_component(&key, &mut vel_ary, Velocity{ x, y });
}
// PositionとVelocityの両方
for i in 0..2 {
let (x ,y) = rand::random();
let key = create_entity(&mut id);
add_component(&key, &mut pos_ary, Position { x, y });
add_component(&key, &mut vel_ary, Velocity { x, y })
}
// 各要素の値を出力する
for i in 0..id {
let pos = pos_ary.get(&i);
let vel = vel_ary.get(&i);
println!("{}: {:?}", i, pos);
println!("{}: {:?}", i, vel);
}
}
// id に +1 して作成したエンティティを返す
fn create_entity (id: &mut u32) -> u32 {
let key = *id;
*id += 1;
key
}
// ハッシュマップにコンポーネントを追加する
fn add_component <T> (id: &u32, v: &mut HashMap<u32, T>, data: T) {
v.insert(*id, data);
}
// ジェネリックなデータ型を引数に取る set_data 関数
fn generic_set_data <T> (id: &usize, v: &mut Vec<T>, data: T) {
v[*id] = data;
}
そろそろ id という変数名を変えたいです。
main.rs
// 現時点で作られたエンティティの数を表す。
// それと、次に作るエンティティのidも表す。
let mut entity_count = 0;
変えました。
ついでに、Entity 構造体を定義します。
main.rs
#[derive(Debug)]
struct Entity {
id: u32,
}
create_entity 関数が Entity 構造体のインスタンスを返すように変更します。
main.rs
// 現在のentity_countをidにしたエンティティを返す
fn create_entity (id: &mut u32) -> Entity {
let entity = Entity { id: *id };
*id += 1;
entity
}
あと、set_dataは不要になったので消します。(add_componentするときに値を設定するので不要と判断)
for ループの i を _ に変更
_ を変数の前に付けると変数が未使用でもワーニングが出なくなる。 _ だけでも問題はない。
main.rs
// 効果を確かめるために、2回づつ create_entity を呼び出す
// Positionコンポーネントのみ
for _ in 0..2 {
let (x, y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut pos_ary, Position { x, y });
}
// Velocityコンポーネントのみ
for _ in 0..2 {
let (x, y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut vel_ary, Velocity{ x, y });
}
// PositionとVelocityの両方
for _ in 0..2 {
let (x ,y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut pos_ary, Position { x, y });
add_component(&entity, &mut vel_ary, Velocity { x, y })
}
最後に、コードの全体を記載して終わります。
main.rs
use std::collections::HashMap;
use rand;
#[derive(Debug)]
struct Entity {
id: u32,
}
#[derive(Debug)]
struct Position {
x: i32,
y: i32,
}
#[derive(Debug)]
struct Velocity {
x: i32,
y: i32,
}
fn main() {
// 現時点で作られたエンティティの数を表す。
// それと、次に作るエンティティのidも表す。
let mut entity_count = 0;
// ベクタをやめて、ハッシュマップで宣言する
// Position構造体のハッシュマップ
let mut pos_ary: HashMap<u32, Position> = HashMap::new();
// Velocity構造体のハッシュマップ
let mut vel_ary: HashMap<u32, Velocity> = HashMap::new();
// 効果を確かめるために、2回づつ create_entity を呼び出す
// Positionコンポーネントのみ
for _ in 0..2 {
let (x, y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut pos_ary, Position { x, y });
}
// Velocityコンポーネントのみ
for _ in 0..2 {
let (x, y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut vel_ary, Velocity{ x, y });
}
// PositionとVelocityの両方
for _ in 0..2 {
let (x ,y) = rand::random();
let entity = create_entity(&mut entity_count);
add_component(&entity, &mut pos_ary, Position { x, y });
add_component(&entity, &mut vel_ary, Velocity { x, y })
}
// 各要素の値を出力する
for i in 0..entity_count {
let pos = pos_ary.get(&i);
let vel = vel_ary.get(&i);
println!("{}: {:?}", i, pos);
println!("{}: {:?}", i, vel);
}
}
// 現在のentity_countをidにしたエンティティを返す
fn create_entity (id: &mut u32) -> Entity {
let entity = Entity { id: *id };
*id += 1;
entity
}
// ハッシュマップにコンポーネントを追加する
fn add_component <T> (entity: &Entity, v: &mut HashMap<u32, T>, data: T) {
v.insert(entity.id, data);
}