2011-01-13 17 views
5

क्या किसी को C++ लाइब्रेरी के बारे में पता है जो टेक्स्ट-आधारित इंटरैक्टिव इंटरफ़ेस प्रदान करेगा? मैं एक आवेदन के दो संस्करण बनाना चाहता हूँ; एक कंसोल आधारित प्रोग्राम जो कमांड लाइन पर या कंसोल पर इंटरैक्टिव रूप से एक जीयूआई आधारित प्रोग्राम (मैक कोको और विंडोज एमएफसी) पर किए गए कार्यों को करेगा। दोनों संस्करण एक सामान्य सी ++ बैकएंड साझा करेंगे।क्रॉस प्लेटफ़ॉर्म, कमांड पूर्ण होने के साथ इंटरैक्टिव टेक्स्ट-आधारित इंटरफ़ेस

कंसोल आधारित प्रोग्राम के लिए मैं कमांड पूर्णता (उदाहरण के लिए टैब-सक्रिय) के साथ readline (जिसे मैं इस एप्लिकेशन के रूप में उपयोग नहीं कर सकता) के समान इतिहास क्षमताओं को पसंद करूंगा।

शायद ऐसा कुछ पहले से ही उपलब्ध है?

उत्तर

1

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

#ifndef INTERACT_H 
#define INTERACT_H 

class Interact; 
class InteractCommand; 
typedef void (Interact::*PF_FUNC)(const InteractCommand &command, const StringVector &args); 

struct InteractCommand 
{ 
    const char *command; 
    const char *argDesc; 
    const char *desc; 
    PF_FUNC func; 
}; 

class Interact 
{ 
private: 
    static Log m_log; 
    static InteractCommand m_commands[]; 
    static unsigned m_numCommands; 

    bool m_stop; 
    Database &m_database; 
    StringVector &m_dirs; 

public: 
    Interact(Database &database, StringVector &dirs); 
    ~Interact(); 

    /** 
    * Main 'interact' loop. 
    * 
    * @return true if the loop exitted normally, else false if an error occurred. 
    */ 
    bool interact(); 

private: 
    // Functions 
#define DEFFUNC(f) void FUNC_##f(const InteractCommand &command, const StringVector &args) 
    DEFFUNC(database); 
    DEFFUNC(dirs); 
    DEFFUNC(exit); 
    DEFFUNC(help); 
#undef DEFFUNC 


    /** 
    * Print usage information for the specified command. 
    * 
    * @param command The command to print usage for. 
    */ 
    static void usage(const InteractCommand &command); 

    static void describeCommand(string &dest, const InteractCommand &command); 
}; 

#endif // INTERACT_H 

सहभागिता: नीचे प्रारंभिक कार्यान्वयन दूसरों की मदद कि हो सकता है (ध्यान दें कि यह कोड का संदर्भ देता है तरीकों और प्रकार मैं प्रकाशित नहीं किया है, तो बॉक्स से बाहर संकलन नहीं होगा)

Interact.h है .cpp:

#include "Interact.h" 

Log Interact::m_log("Interact"); 

#define IFUNC(f) &Interact::FUNC_##f 
InteractCommand Interact::m_commands[] = 
{ 
    { "database", "<file>|close", "Use database <file> or close opened database", IFUNC(database) }, 
    { "dirs", "dir[,dir...]", "Set the directories to scan", IFUNC(dirs) }, 
    { "exit", 0, "Exit", IFUNC(exit) }, 
    { "help", 0, "Print help", IFUNC(help) } 
}; 
#undef IFUNC 

unsigned Interact::m_numCommands = sizeof(m_commands)/sizeof(m_commands[0]); 

Interact::Interact(MusicDatabase &database, StringVector &dirs) : 
    m_stop(false), 
    m_database(database), 
    m_dirs(dirs) 
{ 
} 

Interact::~Interact() 
{ 
} 

bool Interact::interact() 
{ 
    string line; 
    StringVector args; 
    unsigned i; 

    m_stop = false; 
    while (!m_stop) 
    { 
     args.clear(); 
     cout << "> "; 
     if (!getline(cin, line) || cin.eof()) 
      break; 
     else if (cin.fail()) 
      return false; 

     if (!Util::splitString(line, " ", args) || args.size() == 0) 
      continue; 

     for (i = 0; i < m_numCommands; i++) 
      if (strncasecmp(args[0].c_str(), m_commands[i].command, args[0].length()) == 0) 
       break; 
     if (i < m_numCommands) 
      (this->*m_commands[i].func)(m_commands[i], args); 
     else 
      cout << "Unknown command '" << args[0] << "'" << endl; 
    } 
    return true; 
} 

void Interact::FUNC_database(const InteractCommand &command, const StringVector &args) 
{ 
    if (args.size() != 2) 
    { 
     usage(command); 
     return; 
    } 

    if (args[1] == "close") 
    { 
     if (m_database.opened()) 
      m_database.close(); 
     else 
      cout << "Database is not open" << endl; 
    } 
    else 
    { 
     if (!m_database.open(args[1])) 
     { 
      cout << "Failed to open database" << endl; 
     } 
    } 
} 

void Interact::FUNC_dirs(const InteractCommand &command, const StringVector &args) 
{ 
    if (args.size() == 1) 
    { 
     usage(command); 
     return; 
    } 
    // TODO 

} 

void Interact::FUNC_exit(const InteractCommand &command, const StringVector &args) 
{ 
    m_stop = true; 
} 

void Interact::FUNC_help(const InteractCommand &command, const StringVector &/*args*/) 
{ 
    string descr; 
    for (unsigned i = 0; i < m_numCommands; i++) 
    { 
     describeCommand(descr, m_commands[i]); 
     cout << descr << endl; 
    } 
} 

void Interact::usage(const InteractCommand &command) 
{ 
    string descr; 
    describeCommand(descr, command); 
    cout << "usage: " << endl; 
    cout << descr << endl; 
} 

void Interact::describeCommand(string &dest, const InteractCommand &command) 
{ 
    dest.clear(); 
    string cmdStr = command.command; 
    if (command.argDesc != 0) 
    { 
     cmdStr += " "; 
     cmdStr += command.argDesc; 
    } 
    Util::format(dest, " %-30s%s", cmdStr.c_str(), command.desc); 
} 
2

किसी विशेष क्रम में, (मैं उनमें से कोई भी उपयोग किया है,) आप पर एक नज़र होनी चाहिए:

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

+0

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

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^