Menadzer zasobów

Menadzer zasobów
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Witajcie, pracuje sobie ostatnio na pewną grą.
Postanowiłem napisać do niej menadzer zasobów lecz nie wiem jak sie za to zabrać.
Pracuje na systemie Windows 7, używam SFML 2.3
Kod w tym poście nie był kompilowany bo chwilowo nie mam takiej możliwości, więc ten kod ponizej to tak bardziej pseudo kod.
Myślałem nad czymś takim:
1)

Kopiuj
 

template<typename ResourceType>
class CResource
{
    public:
    void loadFrommFile(std::sting path)
    {
         m_PointerToResource = new ResourceType;
         m_PointerToResource->loadFromFile(path);
    }
    private:
    ResourceType * m_PointerToResource;
};


/*ResoureceManager
{
  public:
  void loadResourece(int ID,std::string pathToFile)
  {
  ////	......any code;
  }
  private:
  std::map<int,CResource> m_resourceMap;
  protected:

};*/

Moj menadżer będzie przechowywał zasoby w kontenerze std::map i stąd moje pytaie czy moge wstawić nowy element do tej mapy w taki sposób:

Kopiuj
 
///Example using
void use()
{
   std::map<int,CResource> m_resourceMap;

  m_resourceMap.insert(std::pair<int,CResource>(1,CResource<sf::Sprite>));
  m_resourceMap.insert(std::pair<int,CResource>(2,CResource<sf::Music>));
}

Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
stryku
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:607
0
kacper546 napisał(a):
Kopiuj
 
///Example using
void use()
{
   std::map<int,CResource> m_resourceMap;

  m_resourceMap.insert(std::pair<int,CResource>(1,CResource<sf::Sprite>));
  m_resourceMap.insert(std::pair<int,CResource>(2,CResource<sf::Music>));
}
  1. Nie wiem czy wiesz, ale tworzysz lokalną mapę
  2. prościej chyba będzie
Kopiuj
 
///Example using
void use()
{
   std::map<int,CResource> m_resourceMap;

  m_resourceMap[1] = CResource<sf::Sprite>;
...
}
  1. Ja bym użył jakiegoś enuma zamiast inta

To to co mi przychodzi do głowy

K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0
  1. Wiem wiem naturalnie to miało tylko obrazować użycie tej mapy
    2)Thx za odpowiedź chciałem wiedzieć czy taka konstrukcja jest możliwa.
    3)Czy takie rozwiązanie jest wydajne czy można to zrobić prościej (prościej zrobić menadżera zasobów który przechowuje zasoby różnych typów w jednej mapie) ?

Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
stryku
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:607
0

Tak teraz na to patrzę i wydaję mi się, że kompilator tego nie puści.

Kopiuj
std::map<int,CResource> m_resourceMap;

Tu będzie krzyczał, że nie ma argumentu szablonu CResource.

Żeby trzymać wszystko w jednej mapie CRecource by musiało być klasą bazową i z niej poszczególne klasy opakowujące np sf::Sprite musiały by dziedziczyć

KR
No i musiałby być to chyba mapa z referencjami lub wskaźnikami
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

@stryku @Krolik
Ewentualnie mógłbym zrobić kilka map jedna ze sprite-ami druga z dźwiękami itp.
A co myślicie o ogólnej koncepcji ze w klasie CResource umieściłfoo bym wskaźnik typu void i zmienną mówiącą jaki typ danych ten wskaźnik pokazuje (by uniknąć przypisania zasobu dźwiękowego do sprite np).
Czy może kombinuje jak koń pod górkę i jest jakiś wypracowany sposób w jaki powinno się pisać wszelkiej maści menadżery ?


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
stryku
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:607
0

Piszesz w C++ to pisz w C++ :p To nowe rozwiązanie nadawało by się do C.
C++ daje Ci obiektowość, wykorzystuj ją (:

K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Tylko nie za bardzo kuman np o co chodzi np z tym zdaniem :CRecource by musiało być klasą bazową i z niej poszczególne klasy opakowujące np sf::Sprite musiały by dziedziczyć

Wiesz korzystam z klas ale ni tak bardziej zaawansowanego i teraz nie wiem jak to w ogóle zacząć.


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
stryku
  • Rejestracja:ponad 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:607
1

Ogólnie chodzi o wykorzystanie polimorfizmu. Prosty przykład do tego co napisałem.

Kopiuj
#include <iostream>
#include <map>
using namespace std;

namespace sf
{
	class Sprite
	{
	public:
		void introduceYourself() const
		{
			cout<<"Sprite\n";
		}
	};
	
	class Sound
	{
	public:
		void introduceYourself() const
		{
			cout<<"Sound\n";
		}
	};
}

class CResource
{
public:
	virtual ~CResource() {}
	virtual void doSomething() const = 0;
};

class CSound : public CResource
{
public:
	void doSomething() const
	{
		sound.introduceYourself();
	}
	
private:
	sf::Sound sound;
};

class CSprite : public CResource
{
public:
	void doSomething() const
	{
		sprite.introduceYourself();
	}
	
private:
	sf::Sprite sprite;
};

class CResourceManager
{
public:
	CResourceManager()
	{
		resourcesMap[0] = new CSprite;
		resourcesMap[1] = new CSprite;
		resourcesMap[2] = new CSound;
		resourcesMap[3] = new CSound;
		resourcesMap[4] = new CSprite;
	}
	~CResourceManager()
	{
		for( const auto &res : resourcesMap )
			delete res.second;
	}
	
	void printResources()
	{
		for( const auto &res : resourcesMap )
			res.second->doSomething();
	}
	
private:
	map<int, CResource*> resourcesMap;
	
};

int main() {
	CResourceManager resMngr;
	
	resMngr.printResources();
	return 0;
}

http://ideone.com/B9B3S1

Lecz to na nic się zda w Twoim projekcie bo sf::Sprite i sf::Music są dwoma zupełnie różnymi klasami.

Więc lepsze będą różne mapy do różnych zasobów. Czyli tak jak pisałeś wcześniej. Wtedy w menadżerze byś miał metody getSprite, getMusic itd.
Unikniesz też przymusu tworzenia wrapperów na to.

K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

@stryku

Ok dzięki przeanalizuje to co napisałeś i zaraz coś popełnię jak coś to przyjdę na forum :) Idę popełniać....


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:około 11 godzin
0

Warto się zastanowić, czy wiele homogenicznych menadżerów nie będzie lepszym pomysłem. Koniec koniec końców i tak musisz to sprowadzić do konkretnych typów, bo "tekstura", "model" i "muzyka" nie mają za wiele wspólnego :) Czyli i tak polimorfizm szlag trafi.

Można byłoby się jeszcze pokusić o rejestrację takich menadżerów, żeby sprowadzić to do jakiejś fasady.

Jeżeli jednak wymagana byłaby zabawa w runtime (nie wiem, chociażby jakieś dlle), to stawiałbym na kontener ze zobojętnionymi danymi, przechowującymi tylko ich szczątkowe dane (może jakieś typeid do asercji). Takiemu kontenerowi wystarczyłoby zapewnić tylko zbiór akcji (ładowanie, odładowywanie, współdzielony dostęp)

K5
@spartanPAGE masz na myśli jakiś menadżer zasobów który ma w sobie menadżery tekstur dźwięków itp ?
spartanPAGE
@kacper546 Tak. Sybsystem do ogólnego zarządzania zasobami, na który składać się będą poszczególni zarządcy. Najbardziej zwarty przykład wyszedłby z użyciem subsytemu w postaci singletona i variable-templates z C++14, ale musiałbyś zrobić ładne oczy :)
K5
variable templates ? ło panie jestem bardziej w to tyłu w c++ niż sądziłem.
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

@spartanPAGE
Mam pytanie czy powinienem wskazywać pliki do załadowania w kodzie programu czy nie lepszy był by do tego jakaś moja klasa "czytacz plików konfiguracyjnych" ?


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:około 11 godzin
0

Pojedynczy menadżerowie zasobów nie muszą nic wiedzieć, niech żądają prostych ścieżek.

Te proste ścieżki niech porozsyła fasada, która wydobędzie je w jakiś sposób z konfiguracji.

edytowany 1x, ostatnio: spartanPAGE
K5
Mam pytanie czy klasa menadżera menadżerów zasobów powinna być statyczna czy lepiej użyć singeltona?
spartanPAGE
singleton łatwiej przetestować, dlatego skłaniałbym się ku niemu
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Szybkie pytanie: czy obiekt klasy CResource powinna liczyć ilość odwołań do zasobu czy przerzucić liczenie użyć zasobu na menadżera ? a może w ogóle nie liczyć ile obiektów używa aktualnie zasobu ?


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:około 11 godzin
1

Dodaj zliczanie, kiedy będzie ono naprawdę potrzebne. Zazwyczaj nie jest

edytowany 1x, ostatnio: spartanPAGE
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Mam problem założmy zę mamy coś takieg: 3 klasy

Kopiuj
class Bazowa
{
   public:
   protected: 
   Bazowa(){}
   ~Bazowa(){}
   private:
}

template<typename Type>
class Pochodna
{
   public:
   protected: 
   Pochodna(){}
   ~Pochodna(){}
   virtual void doSomething(){}
   private:
}

class Klasa
{
  Bazowa * m_pointer;

  Klasa()
 {
   m_pointer = new Pochodna<Type>;
   m_pointer->doSomething(); ////Nie mozna tego zrobic bo wskzanik pokazuje na klase Bazowa ktora nie posaida tej metody.
 }
 ~Klasa
 {
   delete m_pointer;
 }
}

Moje pytanie czy można zrobić tak żeby wskaźnik wskazywał na obiekt typu Pochodna i pozwalał użyć jej metod jednoczenie będąc typu bazowa ?
Próbowałem konwersji wskaźnika za pomocą dynamic_cast i przychodzi mi już do głowy tylko to by zamineic to:
Bazowa * m_pointer;
na
Pochodna<Type> * m_pointer;


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Wrocław
  • Postów:399
0

Dwa wyjścia:

  • Skorzystać z metod wirtualnych;
  • Castować do góry;

1.:

Kopiuj
 
class Bazowa
{
   public:
   protected: 
   Bazowa(){}
   ~Bazowa(){}
   virtual void doSomething(){}
   private:
}
 
template<typename Type>
class Pochodna
{
   public:
   protected: 
   Pochodna(){}
   ~Pochodna(){}
   virtual void doSomething(){}
   private:
}
 
class Klasa
{
  Bazowa * m_pointer;
 
  Klasa()
 {
   m_pointer = new Pochodna<Type>;
   m_pointer->doSomething();
 }
 ~Klasa
 {
   delete m_pointer;
 }
}

2.:

Kopiuj
 
class Bazowa
{
   public:
   protected: 
   Bazowa(){}
   ~Bazowa(){}
   private:
}
 
template<typename Type>
class Pochodna
{
   public:
   protected: 
   Pochodna(){}
   ~Pochodna(){}
   virtual void doSomething(){}
   private:
}
 
class Klasa
{
  Bazowa * m_pointer;
 
  Klasa()
 {
   m_pointer = new Pochodna<Type>;
   Pochodna *pochodna = dynamic_cast<Pochodna *>(m_pointer);
   pochodna->doSomething(); // zakładamy, że pochodna != nullptr
 }
 ~Klasa
 {
   delete m_pointer;
 }
}

Asm/C/C++
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Cześć ! Jak wiecie pisze sobie prosty menadżer zasobów.
Mam powiedzmy menadżera tekstur i dźwięków.
Mam teraz kłopot z wymyśleniem w jaki sposób ładować pliki - pojedynczy menadżer będzie żądać ścieżek do pliku (ewentualnie ID zasobu)ale
nie mam pojęcia skąd powinienem pobrać te ścieżki.

Myślałem nad kilkoma rozwiązaniami

  • W kodzie mam pełną ścieżkę do pliku który mnie interesuje. (najprostsze)
  • Mam menadżera który wyszukuje pliki w katalogu - przypisuje im ID i można się go spytać jakie ID ma plik o tej ścieżce - potem posługuje się tylko ID od danego zasobu.
  • Menadżer ma ustalone w pewnym pliku konfiguracyjnym ID zasobu i ścieżkę do jego pliku.

Nie wiem na które rozwiązanie się zdecydować, czy ewentualnie jakaś wariacja 3 powyższych idei.


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

@spartanPAGE
@stryku

Pomyślałem ze za wcześnie zabieram się za optymalizację mojego menadżera.
Czy dobrym pomysłem będzie odwoływanie się do zasobu za pomocą ścieżek?


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:około 11 godzin
0

Jeżeli twój menadżer ma być wydajny, stosuj jedynie indeksowane klucze.
Jeżeli chcesz mieć -przy okazji- ścieżki, to napisz owijkę mapującą ścieżki z kluczami. Po drodze mógłbyś użyć np. ścieżek hashowanych w czasie kompilacji, to by dodatkowo pomogło.

K5
  • Rejestracja:około 12 lat
  • Ostatnio:około 7 lat
  • Lokalizacja:Tutaj,obok
  • Postów:759
0

Dzieki za szybka odpowiedz - na razie napisze wyszukiwanie za pomocą ścieżek później się pomyśli nad optymalizacją - po prostu czuje że utknąłem z tym menadżerem :(


Jeśli mój post jest dowodem mojej niekompetencji, to trudno, ale po to pytam, żeby się czegoś dowiedzieć.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.