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:ponad rok
  • 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:ponad rok
  • 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:ponad rok
  • 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:ponad rok
  • 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:prawie 12 lat
  • Ostatnio:10 dni
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:prawie 12 lat
  • Ostatnio:10 dni
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:prawie 12 lat
  • Ostatnio:10 dni
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 8 godzin
  • 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:prawie 12 lat
  • Ostatnio:10 dni
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ć.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)