कैसे एक पुनर्जन्म परीक्षण दुनिया को लागू करने के लिए नहीं?


23

निम्नलिखित करने के तरीकों के बारे में विचारों की तलाश में हूँ: मैं जावा में एक सरल "दुनिया" लिखना चाहता हूं। एक जिसे मैं शुरू कर सकता था और फिर नई वस्तुओं को बाद की तारीख में मौजूदा वस्तुओं के बीच विभिन्न व्यवहारों को अनुकरण / निरीक्षण करने के लिए जोड़ सकता था। योजना तो यह है कि कुछ समय के लिए पुराने को देखने के बाद नई वस्तुओं को कोडित करें और फिर उन्हें मौजूदा दुनिया में लोड / ड्रॉप करें। समस्या यह है कि मैं दुनिया को शुरू करने से पहले कभी रोकना या फिर से शुरू नहीं करना चाहता, मैं चाहता हूं कि यह कुछ हफ्तों तक चले लेकिन मुझे वस्तुओं को छोड़ने और फिर से लिखने / फिर से लिखने / हटाने / उन्हें बदलने की क्षमता की आवश्यकता है एक रिबूट की आवश्यकता के बिना समय के साथ। दुनिया X / Y स्थानों की 100 x 100 सरणी जितनी सरल हो सकती है, दुनिया का प्रतिनिधित्व करने के लिए एक संभावित टाइल-मैप GUI के साथ। मुझे पता है कि मुझे वस्तुओं पर नज़र रखने और हर एक को 'कार्य करने का मौका' देने के लिए किसी तरह की टिकटीमर प्रक्रिया की ज़रूरत है

उदाहरण: मैं सोमवार को World.java को कोड करता हूं और इसे चलाना छोड़ देता हूं। फिर मंगलवार को मैं एक नया वर्ग लिखता हूं जिसका नाम Rock.java है (जो नहीं चलता है)। मैं इसे पहले से ही चल रही दुनिया में (किसी भी तरह से) लोड / ड्रॉप करता हूं (जो इसे विश्व सरणी में यादृच्छिक रूप से कहीं भी छोड़ देता है और कभी नहीं चलता है)। फिर बुधवार को मैं कैट.जावा नामक एक नया वर्ग बनाता हूं और इसे दुनिया में छोड़ देता हूं, फिर से यादृच्छिक रूप से रखा जाता है, लेकिन यह नई वस्तु दुनिया भर में घूम सकती है (समय की किसी इकाई पर), फिर गुरुवार को मैं एक वर्ग लिखता हूं जिसे डॉग कहा जाता है। जावा जो आसपास भी घूमता है लेकिन किसी अन्य वस्तु पर 'कार्य' कर सकता है यदि वह पड़ोसी स्थान पर है और इसके विपरीत।

ये रही चीजें। मुझे नहीं पता कि मैं किस प्रकार की संरचना / डिज़ाइन का पता लगाने के लिए वास्तविक विश्व वर्ग को कोड करने की आवश्यकता होगी, ताकि भविष्य का पता लगाने / लोड करने (या वर्तमान में गैर-मौजूद) ऑब्जेक्ट्स का पता लगाने के लिए कैसे।

जावा का उपयोग करके आप इस तरह का कोई विचार कैसे करेंगे?


2
हॉट स्वैपिंग बहुत पसंद है । शायद इस पर कुछ साहित्य है जो सहायक हो सकता है। वैसे भी, बहुत दिलचस्प सवाल। +1…
कोनराड रूडोल्फ

जवाबों:


5

जो आप मूल रूप से देख रहे हैं वह एक हॉट-प्लग करने योग्य प्रणाली है। आप एक मुख्य एप्लिकेशन चलाते हैं और फिर रन-टाइम पर प्लग-इन जोड़ते हैं जो ईवेंट लूप में एकीकृत हो जाते हैं। सबसे पहले, यह सोचना शुरू करें कि आपकी दुनिया किसी खेल इकाई से क्या उम्मीद करती है। उदाहरण के लिए (आपके विवरण के आधार पर):

interface Entity {
   void init(World world);
   // Called when loaded for the first time in the world and adds itself
   // to the world (correct position in the array, scheduler for updates)

   void update(World world);
   // Called when scheduler fires (allows the entity to think about its
   // next move)

   Image getImage();
   // Called by the GUI when it is time to draw the entity on the screen
}

बेशक, आप अन्य तरीकों को जोड़ सकते हैं जिन्हें आप आवश्यक हैं। दो प्रासंगिक तरीकों के साथ विश्व पैरामीटर पर ध्यान दें। यह आपकी नई इकाई की स्थापना या अद्यतन करते समय दुनिया पर विचार करने की अनुमति देता है। उदाहरण के लिए, आपके डॉग वर्ग में, आप दुनिया से सभी बिल्लियों के लिए पूछ सकते हैं। इसके बाद, आप अपनी दुनिया बनाते हैं जो इस इंटरफ़ेस और गतिशील रूप से जावा कोड को संकलित और लोड करने के लिए एक प्रणाली के साथ काम करती है। इसका एक उदाहरण यहां पाया जा सकता है

void injectEntity(String filename, World world) {
    // Load the class as described in the mentioned link
    Entity e = (Entity) loadClass(filename);
    e.init(world);
}

नई संस्थाओं को जोड़ने के लिए वर्ल्ड जीयूआई से इस विधि को कॉल करें। आपके विश्व कार्यान्वयन के आधार पर, एक इकाई इनिट फ़ंक्शन इस तरह दिख सकता है:

void init(World world) {
   // Register entity with world for easy access
   world.register(this, "RockImpl A");

   // Place the entity on the world map
   Point initialLocation = Point(10,5);
   world.place(this, initialLocation);

   // Schedule its update method for every 5 seconds
   world.schedule(this, 5);
}

1
Google को कीवर्ड: "IoC कंटेनर", "नियंत्रण का व्युत्क्रम", "निर्भरता इंजेक्शन"। ये जेनेरिक हॉट-प्लगबल सिस्टम के लिए तकनीक हैं, जो रनटाइम के दौरान घटकों को खोज और लोड कर सकते हैं।
नेवरमाइंड

16

हमने कुछ ऐसा ही किया था स्टेंडल में छापेमारी के लिए।

हमने पुनरारंभ को पूरी तरह से टालने का लक्ष्य नहीं रखा। इसलिए हमारी मुख्य अवसंरचना सेवाओं में परिवर्तन जैसे कि क्लाइंट / सर्वर संचार को पुनः आरंभ करने की आवश्यकता है। लेकिन संस्थाओं, प्राणियों और एनपीसी को जोड़ना, और मौजूदा वस्तुओं को संशोधित करना काम करता है। (ओह, और कभी-कभी लाइव बग फिक्सिंग, प्रतिबिंब का उपयोग निजी क्षेत्रों में हेरफेर करने के लिए भी किया जा सकता है)।

चूंकि हम न केवल नए डेटा (दूसरी त्वचा की तरह) के आधार पर नई वस्तु चाहते हैं , बल्कि नए व्यवहार को भी जोड़ना चाहते हैं, विश्व कार्यक्रम के लिए नई कक्षा की फ़ाइलों को लोड करने में सक्षम होना चाहिए । हम उन्हें "स्क्रिप्ट" कहते हैं, लेकिन वे वास्तविक संकलित जावा कक्षाएं हैं। वे कक्षाएं Script.java इंटरफ़ेस को लागू करती हैं ।

मारिया.जावा इसका सरल उदाहरण है। वह एक नया एनपीसी है जो खिलाड़ियों को पेय और भोजन बेचता है। हम वहां बहुत जटिल वस्तुओं को भी परिभाषित कर सकते हैं ।

एक नया वर्ग इस तरह से भरा गया है:

// create a new class loader, with the script folder as classpath.
final File file = new File("./data/script");
final ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});

// load class through new loader
final Class< ? > aClass = loader.loadClass(classname);
script = (Script) aClass.newInstance();

यदि आप अद्वितीय नाम सुनिश्चित कर सकते हैं और कक्षाओं को कभी भी अनलोड नहीं करना चाहते हैं, तो आपको निम्न स्तर के सामान के साथ किया जाता है।

हालांकि, उतारना काफी महत्वपूर्ण लगता है। इसे प्राप्त करने के लिए, जब भी आप नए कोड को इंजेक्ट करना चाहते हैं, तो आपको एक नए क्लास लोडर को तुरंत भेजना होगा। ताकि GC उस कोड के अंतिम संदर्भ को साफ करने के बाद अपना काम कर सके।

हमारे पास एक / अनलोड कमांड है जो हमारे इंटरफ़ेस में एक अनलोड विधि को आमंत्रित करता है ताकि स्क्रिप्ट क्लीनअप कर सकें। वास्तविक उतराई स्वचालित रूप से जीसी द्वारा की जाती है।

हम अक्सर छापे के दौरान बहुत सारी अस्थायी वस्तुओं का निर्माण करते हैं । और हम चाहते हैं कि छापे के समाप्त होने के बाद उन सभी को हटा दिया जाए। उदाहरण के लिए Gnomes छापे, जो अदृश्य व्यवस्थापक के पास gnome इसके के एक नंबर spawns के लिए, हम इस कोड का उपयोग: GnomeRaid.java फैली CreateRaid.java

स्क्रिप्ट सीधे दुनिया तक पहुंच सकती है (जैसा कि पहले उदाहरण से पता चलता है) और अनलोड () विधि में अपनी सफाई करें। लेकिन जावा कोडर्स का उपयोग सफाई करने के लिए नहीं किया जाता है, और यह कष्टप्रद है। इसलिए हमने एक सैंडबॉक्स बनाया जिसे स्क्रिप्ट उपयोग कर सकते हैं। सैंडबॉक्स वर्ग के माध्यम से दुनिया में जोड़े गए सभी वस्तुओं को उतारने पर हटा दिया जाता है।


3

दुनिया को बचाएं (कोई भी इरादा नहीं) और उसके सभी राज्य (स्थिति, वेग, सभी चर)।

  • कार्यक्रम बंद करो।
  • परिवर्तन लागू करें (बचत के साथ पिछड़ी संगतता सुनिश्चित करना)।
  • पुनरावर्ती कार्यक्रम।
  • कार्यक्रम को पुनरारंभ करें।
  • लोड दुनिया और राज्य।
  • दोहराना

यह एक सामान्य समाधान है, हालांकि, मुझे नहीं पता है कि आप यह जान सकते हैं कि क्या आप गतिशील रूप से कोड ब्लॉक और कक्षाओं को लागू कर सकते हैं जैसे आप आशा करते हैं ...

विकल्प 2 , एक स्क्रिप्टिंग भाषा को बांधना है जिसे मक्खी पर लोड किया जा सकता है।


स्क्रिप्टिंग भाषा के लिए +1। यदि आप जावा के लिए बाध्य नहीं हैं, तो LPC- आधारित MUD के कुछ ड्राइवर और मडलिब भी आज़माएँ।
मार्टिन सोज्का

1

जावा के लिए, आपको बस एक OSGi प्लेटफ़ॉर्म चाहिए । इसके साथ ही यह हॉट-स्वैप मॉड्यूल या एप्लिकेशन के लिए तुच्छ है, और यहां तक ​​कि दूरस्थ प्रबंधन या आंशिक उन्नयन भी करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.