-1
pub trait Observer{
    type DataType;
    fn new(action: fn(&mut Self::DataType))->Self;
    fn update(&self, data:&mut Self::DataType);
}

pub trait Subject{
    type ObserverType: Observer;
    fn new()-> Self;
    fn add_observer(&mut self,observer:Rc<Self::ObserverType>);
    fn remove_observer(&mut self,observer:&Rc<Self::ObserverType>);
    fn data(&mut self)-> &<<Self as Subject>::ObserverType as Observer>::DataType;
    fn notification(&mut self);
}

pub struct SubjectMgr{
}

impl SubjectMgr {
    fn new(){
        let mut map = HashMap::new();
        map.insert("PlayerList",PlayerListSubject::new());
        map.insert("MonsterList",MonsterListSubject::new());
    }
}

An attempt was made to use a hashmap with associate value as a member. But can't I have a hashmap value type?

The file structure is as follows: enter image description here

2 Answers2

0

In most Rust collections, the values (and keys) must have the same type. PlayerListSubject and MonsterListSubject are different types, therefore their values can't be put into the same map unless you type-erase them behind trait objects (assuming the traits are object-safe, which I don't think is the case here).

In the future, you may want to provide minimal reproducible examples of the issue instead of incomplete unusable bits of code. That makes the issue much easier to experiment with and understand for the would-be helper, ensures nobody wastes time on misunderstandings, and increases the odds of getting useful answers (which I'm uncertain this one is).

The entire thing looks lifted from Java or C# though, which bodes ill for it actually working. Rust is a rather different language putting its own set of limitations on the language user. Trying to replicate Java designs in it usually leads to frustration and not getting things to work.

Masklinn
  • 34,759
  • 3
  • 38
  • 57
0
use std::{ops::Deref, rc::Rc};
use super::{Observer, Subject};

struct Monster{
    id: String,
    password: String,
}

#[derive(Default)]
struct MonsterList{
    players: Vec<Monster>
}

impl Deref for MonsterList {
    type Target = Vec<Monster>;

    fn deref(&self) -> &Self::Target {
        &self.players
    }
}

impl MonsterList {
    pub fn new() -> Self {
        MonsterList::default()
    }
}

pub struct MonsterListObserver{
    action: fn(&mut MonsterList),
}

impl Observer for MonsterListObserver{
    type DataType = MonsterList;

    fn new(action: fn(&mut Self::DataType))->Self {
        Self {action}
    }

    fn update(&self, data:&mut Self::DataType) {
        (self.action)(data);
    }
}

pub struct MonsterListSubject{
    monster_list: MonsterList,
    observers: Vec<Rc<MonsterListObserver>>,
}

impl Subject for MonsterListSubject{
    type ObserverType = MonsterListObserver;

    fn new()-> Self {
        Self {
            monster_list: MonsterList::new(),
            observers: Vec::new(),
        }
    }

    fn add_observer(&mut self,observer:Rc<Self::ObserverType>) {
        self.observers.push(observer);
    }

    fn remove_observer(&mut self,remove_observer:&Rc<Self::ObserverType>) {
        self.observers.retain(|observer|{
            let observer = &**observer as *const MonsterListObserver;
            let remove_observer = &**remove_observer as *const MonsterListObserver;
            observer != remove_observer
        })
    }

    fn data(&mut self)-> &<Self::ObserverType as Observer>::DataType {
        &mut self.monster_list
    }

    fn notification(&mut self) {
        let monster_list = &mut self.monster_list;
        self.observers
            .iter()
            .for_each(|observer| observer.update(monster_list))
    }
}