ã¬ã¬ã·ãŒç¬¬13ç« ïŒã¢ã»ãã管çãšãªãœãŒã¹ãã£ãã·ã¥èšèš
äºéèªã¿èŸŒã¿é²æ¢ã»ãã³ãã«ååç
§ã»Flyweightãã£ãã·ã¥ãã¿ãŒã³
æµãã£ã©ã¯ã¿ãŒã匟å¹ãBGMã广é³ã倧éã«ç»å Žããæ¬æ Œã²ãŒã ã§ã¯ãããªããžã§ã¯ããçæããããã³ã«ãã¡ã€ã«ããç»åãé³å£°ãããŒãããããšããçŽ æŽãªèšèšã¯ç¬æã«ã¡ã¢ãªç Žç¶»ãšæ¿ããããŒãã¹ãã€ã¯ãåŒãèµ·ãããŸããæ¬ç« ã§ã¯ããã¶ã€ã³ãã¿ãŒã³ã®èŠã§ãããFlyweightïŒãã©ã€ãŠã§ã€ãïŒãã¿ãŒã³ããå°å
¥ããäœåäœãã®æµãåäžã®ãã¯ã¹ãã£ããŒã¿ãã¡ã¢ãªäžã§å®å
šã«å
±æãããã£ãã·ã¥ã¢ãŒããã¯ãã£ãæ§ç¯ããŸããããã«ãçãã€ã³ã¿ã®å±éºæ§ïŒèª°ãè§£æŸãããããããã¯ã©ãã·ã¥ãããã³ã°ãªã³ã°ãã€ã³ã¿ïŒãæé€ããããã®ãäžä»£çªå·ä»ããã³ãã«åç
§ïŒHandle IdiomïŒãããC++03ç°å¢ã§ãå
ç¢ã«åããåç
§ã«ãŠã³ãåŒResourceManagerããèšèšã»å®è£
ããŸãã
L13.1 ãæµãäœããã³ã«ãã¯ã¹ãã£èªèŸŒãã®æ²åïŒã¡ã¢ãªççºãšãã³ã°ãªã³ã°ãã€ã³ã¿
ãªãã²ãŒã ãšã³ãã£ãã£èªèº«ã«ãã¯ã¹ãã£ãæãããŠã¯ãããªãã®ãïŒã¡ã¢ãªéè€ãšç Žæ£ã¿ã€ãã³ã°ã®ç Žç¶»ã培åºè§£æããŸãã
ð§ ãã³ã®ã³å
茩
ã·ãã¯ãå
çïŒã€ã³ããŒããŒã100äœç»é¢ã«åºããããã¡ã¢ãªäœ¿çšéã2GBãè¶
ããŠPCãããªãŒãºããããŸããïŒæµ1äœã®ç»åã¯ãã£ã500KBã®ã¯ããªã®ã«âŠïŒ
ð»ââïž ã·ãã¯ãå
ç
ãµãã£ãµãã£ãµãïŒæµã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã§ãæ¯å "loadTexture(\"invader.png\")" ãšæçŽã«ãã£ã¹ã¯ããç»åãèªã¿èŸŒãã§ãããããïŒ
ð§ ãã³ã®ã³å
茩
ã®ã¯ãïŒã¯ãâŠæµããšã« Texture* texture = new Texture("invader.png"); ãšãã£ãŠããŸããããããæµãåããããšãã« delete texture; ãããããŸã çãæ®ã£ãŠããä»ã®æµã®ç»åãåããŠã¯ã©ãã·ã¥ããŠããŸããŸããâŠïŒ
ð»ââïž ã·ãã¯ãå
ç
åã
ã®ã²ãŒã ãªããžã§ã¯ãïŒå¯¿åœãçãïŒãšãã¢ã»ãããªãœãŒã¹ïŒå¯¿åœãé·ãã»å
±æãããã¹ãïŒã®ã©ã€ããµã€ã¯ã«ããã¡ãæ··ãã«ããŠããã®ãåå ããïŒå
±æãããéãããŒã¿ã¯ããªãœãŒã¹ãããŒãžã£ãŒããäžå
管çããåã
ã®ãªããžã§ã¯ãã«ã¯ãå
±æãªãœãŒã¹ãžã®è»œãåç
§ãã ããæãããã®ãããã®éåããïŒ
FlyweightïŒãã©ã€ãŠã§ã€ãïŒãã¿ãŒã³ãšã¯ã倧éã®ãªããžã§ã¯ããååšãããšãã«ããããå
šäœã§å
±æã§ããäžå€ïŒImmutableïŒãªéšåãå€ã«æœåºããã¡ã¢ãªæ¶è²»éãåçã«åæžãããã¶ã€ã³ãã¿ãŒã³ã§ããã²ãŒã ããã°ã©ãã³ã°ã«ãããŠã¯ããã¯ã¹ãã£ã3Dã¡ãã·ã¥ã广é³ãããã¡ããã©ã³ãããŒã¿ãªã©ã代衚çãªFlyweight察象ãšãªããŸãã
L13.2 Flyweightãã¿ãŒã³ïŒåºæç¶æ
ïŒExtrinsicïŒãšå
±æç¶æ
ïŒIntrinsicïŒã®å®å
šåé¢
ãªããžã§ã¯ãã®ç¶æ
ããå
šå¡åãéšåããšãåäœããšã«éãéšåãã«å€ç§æè¡ã®ããã«åãåããŸãã
ð§ ãã³ã®ã³å
茩
ãåºæç¶æ
ïŒExtrinsic StateïŒããšãå
±æç¶æ
ïŒIntrinsic StateïŒãã£ãŠãã©ãåããã°ãããã§ããïŒ
ð»ââïž ã·ãã¯ãå
ç
ç°¡åããïŒãç»é¢äžã®å
šæµãåããã®ãã¯å
±æç¶æ
ããæµAãšæµBã§ç°ãªããã®ãã¯åºæç¶æ
ããïŒ
L13.3 çãã€ã³ã¿ãæšãŠãïŒäžä»£çªå·ä»ããã³ãã«åç
§ïŒHandle IdiomïŒ
Texture* ã Sound* ã®ãããªçãã€ã³ã¿ãã²ãŒã ãšã³ãã£ãã£ã«æãããã®ããªãå±éºãªã®ãããã³ãã«åç
§ã®åªäœæ§ãåŠã³ãŸãã
ð§ ãã³ã®ã³å
茩
ãªãœãŒã¹ãããŒãžã£ãŒããã¯ã¹ãã£ã1ã€æã£ãŠãããªããæµã«ã¯ Texture* ãæž¡ãã°ããããããªãã§ããïŒãã€ã³ã¿ã®ã³ããŒãªã8ãã€ãã§æžã¿ãŸãããïŒ
ð»ââïž ã·ãã¯ãå
ç
ã¹ããŒãžã¯ãªã¢æã«ãªãœãŒã¹ãããŒãžã£ãŒããã¹ããŒãž1ã®ãã¯ã¹ãã£ãå
šç Žæ£ãããæãããæµã®æ®éªžãé
å»¶ãšãã§ã¯ããçãã€ã³ã¿ãä¿æããŠãããã©ããªãïŒ
ð§ ãã³ã®ã³å
茩
ããã£ïŒãã§ã«è§£æŸãããã¡ã¢ãªãæãããã³ã°ãªã³ã°ãã€ã³ã¿ãã«ãªã£ãŠãã¢ã¯ã»ã¹ããç¬éã«ã¯ã©ãã·ã¥ïŒã¢ã¯ã»ã¹ãã€ãªã¬ãŒã·ã§ã³ïŒããŸãïŒ
ð»ââïž ã·ãã¯ãå
ç
ããã§ç»å Žããã®ããäžä»£çªå·ä»ããã³ãã«ïŒGenerational HandleïŒãããïŒã€ã³ããã¯ã¹çªå·ãšäžä»£ã«ãŠã³ã¿ãããã¯ããæŽæ°æ§é äœã䜿ãããšã§ããªãœãŒã¹ãç Žæ£ã»åå²ãåœãŠãããããšã100%å®å
šã«æ€ç¥ã§ããã®ããïŒ
ð ResourceHandle.h
#ifndef RESOURCE_HANDLE_H
#define RESOURCE_HANDLE_H
#include <stdint.h>
// 32ãããã®æŽæ°ã« [äžä»£çªå· 16bit | ã¹ãããçªå· 16bit] ãããã¯
struct ResourceHandle {
uint32_t id;
ResourceHandle() : id(0) {}
ResourceHandle(uint16_t index, uint16_t generation) {
id = (static_cast<uint32_t>(generation) << 16) | static_cast<uint32_t>(index);
}
uint16_t getIndex() const {
return static_cast<uint16_t>(id & 0xFFFF);
}
uint16_t getGeneration() const {
return static_cast<uint16_t>((id >> 16) & 0xFFFF);
}
bool isValid() const {
return id != 0;
}
bool operator==(const ResourceHandle& other) const { return id == other.id; }
bool operator!=(const ResourceHandle& other) const { return id != other.id; }
};
#endif // RESOURCE_HANDLE_H
L13.4 å®è£
ç·šïŒã¬ã¬ã·ãŒåç
§ã«ãŠã³ãåŒResourceManagerã®å®å
šæ§ç¯
åäžãã¡ã€ã«ã®åããŒããé²ãæååãã£ãã·ã¥ãšãåç
§ã«ãŠã³ã¿ã«ããèªåããŒãžæ©æ§ãå®è£
ããŸãã
ð ResourceManager.cpp
#include <iostream>
#include <string>
#include <map>
struct TextureResource {
std::string filename;
int width;
int height;
int refCount; // åç
§ã«ãŠã³ã¿
TextureResource(const std::string& name)
: filename(name), width(64), height(64), refCount(1) {
std::cout << "[Disk I/O] ãã¯ã¹ãã£èªèŸŒ: " << filename << " (ã¡ã¢ãªç¢ºä¿)" << std::endl;
}
~TextureResource() {
std::cout << "[VRAM Release] ãã¯ã¹ãã£ç Žæ£: " << filename << std::endl;
}
};
class ResourceManager {
private:
std::map<std::string, TextureResource*> cache_;
public:
~ResourceManager() {
unloadAll();
}
// ãªãœãŒã¹ã®ååŸïŒæªããŒããªãæ°èŠããŒããããŒãæžã¿ãªãæ¢åãå
±æïŒ
TextureResource* acquireTexture(const std::string& filepath) {
std::map<std::string, TextureResource*>::iterator it = cache_.find(filepath);
if (it != cache_.end()) {
it->second->refCount++;
std::cout << "[Cache HIT] " << filepath << " ãåå©çš (åç
§æ°: "
<< it->second->refCount << ")" << std::endl;
return it->second;
}
// æ°èŠããŒã
TextureResource* res = new TextureResource(filepath);
cache_[filepath] = res;
return res;
}
// ãªãœãŒã¹ã®è¿åŽïŒåç
§ã«ãŠã³ããæžããã0ã«ãªã£ãã峿ãŸãã¯é
å»¶è§£æŸïŒ
void releaseTexture(const std::string& filepath) {
std::map<std::string, TextureResource*>::iterator it = cache_.find(filepath);
if (it == cache_.end()) return;
it->second->refCount--;
std::cout << "[Release] " << filepath << " è¿åŽ (æ®ãåç
§æ°: "
<< it->second->refCount << ")" << std::endl;
if (it->second->refCount <= 0) {
delete it->second;
cache_.erase(it);
}
}
void unloadAll() {
for (std::map<std::string, TextureResource*>::iterator it = cache_.begin();
it != cache_.end(); ++it) {
delete it->second;
}
cache_.clear();
}
size_t getLoadedCount() const { return cache_.size(); }
};
int main() {
ResourceManager mgr;
std::cout << "=== 10äœã®æµãçæ ===" << std::endl;
TextureResource* enemies[10];
for (int i = 0; i < 10; ++i) {
// å
šå¡åãç»åãèŠæ±ãããããã£ã¹ã¯ããŒãã¯æåã®1åã ãïŒ
enemies[i] = mgr.acquireTexture("sprites/invader.png");
}
std::cout << "\nãã£ãã·ã¥äžãã¯ã¹ãã£ç·æ°: " << mgr.getLoadedCount() << std::endl;
std::cout << "\n=== æµãé æ¬¡æç ŽïŒè§£æŸïŒ ===" << std::endl;
for (int i = 0; i < 10; ++i) {
mgr.releaseTexture("sprites/invader.png");
}
std::cout << "\nå
šè§£æŸåŸã®ãã£ãã·ã¥æ°: " << mgr.getLoadedCount() << std::endl;
return 0;
}
ð¡ ãã®ã»ã¯ã·ã§ã³ã®éèŠãã€ã³ã
- Flyweightãã¿ãŒã³ã®æ¬è³ª: å
šãšã³ãã£ãã£å
±éã®äžå€ããŒã¿ïŒç»åã»é³å£°ïŒãäžå
ãã£ãã·ã¥ããåäœããšã®å¯å€ããŒã¿ïŒåº§æšã»HPïŒãšå³æ Œã«åé¢ããã
- éè€ããŒãã®æ ¹çµ¶: ãã¡ã€ã«ãã¹ãããŒã«ãããããã§ç®¡çããåäžã¢ã»ããã¯ã¡ã¢ãªäžã«å¯äžç¡äºã®1ã€ã³ã¹ã¿ã³ã¹ã®ã¿ãä¿èšŒããã
- çãã€ã³ã¿ãããã³ãã«ãžã®æè¯: ã¢ã³ããŒãæã®ãã³ã°ãªã³ã°ãã€ã³ã¿äºæ
ãé²ããããäžä»£çªå·ä»ããã³ãã«ãåç
§ã«ãŠã³ãæ©æ§ãèšããã
- ãã©ãŒã«ããã¯æ©æ§ã®åžžå: ãã¡ã€ã«ãååšããªãã»ç ŽæããŠããå Žåã«ã¯ã©ãã·ã¥ããããç®ç«ã€ä»£æ¿è²ïŒãã³ã¯çŽ«åžæŸæš¡æ§ãªã©ïŒã衚瀺ããŠéçºãæ¢ããªãã
ð ç解床ãã§ãã¯ã¯ã€ãº
Q1. ã²ãŒã ããã°ã©ãã³ã°ã«ãããŠãFlyweightãã¿ãŒã³ãé©çšããäž»ãªç®çãšããŠæãé©åãªãã®ã¯ã©ãã§ããïŒ
- 1. ã²ãŒã ã«ãŒãã®ãã¬ãŒã ã¬ãŒããåºå®åãããã
- 2. 倧éã®ãªããžã§ã¯ãéã§å
±éããäžå€ããŒã¿ãå
±æããã¡ã¢ãªæ¶è²»éãšããŒãè² è·ãæ¿æžããããã
- 3. ä»®æ³é¢æ°ã®åŒã³åºããªãŒããŒãããããŒãã«ãããã
- 4. ãã«ãã¹ã¬ããã«ããããããããã¯ã鲿¢ãããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒå€§éã®ãªããžã§ã¯ãéã§å
±éããäžå€ããŒã¿ãå
±æããã¡ã¢ãªæ¶è²»éãšããŒãè² è·ãæ¿æžããããã
Flyweightãã¿ãŒã³ã¯ã倿°ã®ãªããžã§ã¯ããå
±éããŠæã€éãããŒã¿ïŒãã¯ã¹ãã£ãã¯ã»ã«ãé³å£°æ³¢åœ¢ãªã©ïŒãå
±æãã£ãã·ã¥ã«ãŸãšããåãªããžã§ã¯ãã«ã¯è»œãèå¥åã®ã¿ãæãããããšã§ã¡ã¢ãªãåçã«ç¯çŽããææ³ã§ãã
Q2. çãã€ã³ã¿ïŒTexture*ïŒã®ä»£ããã«ãäžä»£çªå·ä»ããã³ãã«ïŒGenerational HandleïŒãã䜿çšããæå€§ã®å©ç¹ã¯äœã§ããïŒ
- 1. ãã€ã³ã¿ãããæ¶è²»ã¡ã¢ãªãåžžã«å°ãããªããã
- 2. ãªãœãŒã¹ãç Žæ£ãããåŸãå¥ã®ãªãœãŒã¹ã«åå©çšãããåŸã«ã¢ã¯ã»ã¹ããŠããç¡å¹ãªåç
§ã§ããããšã確å®ã«æ€ç¥ã§ãããã
- 3. ã³ã³ãã€ã«æã®åãã§ãã¯ãå®å
šã«ç¡å¹åã§ãããã
- 4. ãã£ã¹ã¯ããã®èªã¿èŸŒã¿é床ãç©ççã«2åã«ãªããã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒãªãœãŒã¹ãç Žæ£ãããåŸãå¥ã®ãªãœãŒã¹ã«åå©çšãããåŸã«ã¢ã¯ã»ã¹ããŠããç¡å¹ãªåç
§ã§ããããšã確å®ã«æ€ç¥ã§ãããã
ã¹ãããã®ã€ã³ããã¯ã¹ã«å ããŠãäžä»£çªå·ïŒGenerationïŒããä¿æããããšã§ãå€ããªãœãŒã¹ãç Žæ£ãããåŸã«åãã¹ããããåå©çšãããå Žåã§ãäžä»£çªå·ã®äžäžèŽã«ãã£ãŠãã³ã°ãªã³ã°ã¢ã¯ã»ã¹ã100%æ€ç¥ã»é²åŸ¡ã§ããŸãã
Q3. ãªãœãŒã¹ãããŒãžã£ãŒã®å®è£
ã«ãããŠãããŒã察象ã®ç»åãã¡ã€ã«ãèŠã€ãããªãã£ãå Žåã®åçšã²ãŒã ã§ã®æšå¥šèšèšã¯ã©ãã§ããïŒ
- 1. å³åº§ã« std::abort() ãŸã㯠assert() ã§ã²ãŒã ãã¯ã©ãã·ã¥ããã
- 2. nullptr ãè¿ããåŒã³åºãåŽãNULLãã§ãã¯ããŠããªãç®æã§SEGVãåŒãèµ·ãã
- 3. ç®ç«ã€ãããŒç»åïŒããŒã³ã¿ã®ãã§ãã«ãŒæš¡æ§ãªã©ïŒããã©ãŒã«ããã¯ãšããŠè¿ããèŠåãã°ãåºåããŠã²ãŒã ã¯ç¶ç¶ããã
- 4. èŠã€ãããŸã§ç¡éã«ãŒãã§ãã£ã¹ã¯ãå詊è¡ãç¶ãã
æ£è§£ãšè§£èª¬ãèŠã
æ£è§£ïŒç®ç«ã€ãããŒç»åïŒããŒã³ã¿ã®ãã§ãã«ãŒæš¡æ§ãªã©ïŒããã©ãŒã«ããã¯ãšããŠè¿ããèŠåãã°ãåºåããŠã²ãŒã ã¯ç¶ç¶ããã
åçšã²ãŒã ãšã³ãžã³ïŒUnreal EngineãSource Engineãªã©ïŒã§ã¯ãã¢ã»ããæ¬ ææã«ã²ãŒã ãèœãšãã®ã§ã¯ãªããäžç®ã§æªããŒããšããããããŒã³ã¿ãšé»ã®åžæŸæš¡æ§ïŒMissing TextureïŒãããã©ãŒã«ããã¯ãšããŠè¿ãèšèšãäžè¬çã§ãã
ð»ââïž ã·ãã¯ãC++ã©ã ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ã·ã¹ãã
ãã©ãŠã¶ã§JavaScriptãæå¹ã«ãããšããã©ãŠã¶å
ã€ã³ããŒããŒã²ãŒã ãšãã¥ã¬ãŒã¿ãã¡ã¢ãªãããå¯èŠåãUMLã¯ã©ã¹å³ã察話å解説ãç解床ã¯ã€ãºãèµ·åããŸãã
ã€ã³ã¿ã©ã¯ãã£ãåŠç¿ãéå§ãã â