1
0
Fork 0

Refactored cWebPlugin for C++11 style and proper WebTab clearing.

This commit is contained in:
Mattes D 2015-04-19 14:35:04 +02:00
parent a9b5a6c3a6
commit 288d2280fa
6 changed files with 156 additions and 110 deletions

View File

@ -2647,22 +2647,16 @@ static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S)
static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S)
{
cWebPlugin* self = (cWebPlugin*) tolua_tousertype(tolua_S, 1, nullptr);
const cWebPlugin::TabNameList & TabNames = self->GetTabNames();
// Returns a map of (SafeTitle -> Title) for the plugin's web tabs.
auto self = reinterpret_cast<cWebPlugin *>(tolua_tousertype(tolua_S, 1, nullptr));
auto TabNames = self->GetTabNames();
lua_newtable(tolua_S);
int index = 1;
cWebPlugin::TabNameList::const_iterator iter = TabNames.begin();
while (iter != TabNames.end())
for (auto itr = TabNames.cbegin(), end = TabNames.cend(); itr != end; ++itr)
{
const AString & FancyName = iter->first;
const AString & WebName = iter->second;
tolua_pushstring(tolua_S, WebName.c_str()); // Because the WebName is supposed to be unique, use it as key
tolua_pushstring(tolua_S, FancyName.c_str());
//
tolua_pushstring(tolua_S, itr->second.c_str()); // Because the SafeTitle is supposed to be unique, use it as key
tolua_pushstring(tolua_S, itr->first.c_str());
lua_rawset(tolua_S, -3);
++iter;
++index;
}
return 1;

View File

@ -200,6 +200,7 @@ bool cPluginLua::Load(void)
void cPluginLua::Unload(void)
{
ClearTabs();
super::Unload();
Close();
}
@ -2000,40 +2001,29 @@ void cPluginLua::AddResettable(cPluginLua::cResettablePtr a_Resettable)
AString cPluginLua::HandleWebRequest(const HTTPRequest * a_Request)
AString cPluginLua::HandleWebRequest(const HTTPRequest & a_Request)
{
cCSLock Lock(m_CriticalSection);
std::string RetVal = "";
std::pair< std::string, std::string > TabName = GetTabNameForRequest(a_Request);
std::string SafeTabName = TabName.second;
if (SafeTabName.empty())
// Find the tab to use for the request:
auto TabName = GetTabNameForRequest(a_Request);
AString SafeTabTitle = TabName.second;
if (SafeTabTitle.empty())
{
return "";
}
auto Tab = GetTabBySafeTitle(SafeTabTitle);
if (Tab == nullptr)
{
return "";
}
sWebPluginTab * Tab = 0;
for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr)
// Get the page content from the plugin:
cCSLock Lock(m_CriticalSection);
AString Contents = Printf("WARNING: WebPlugin tab '%s' did not return a string!", Tab->m_Title.c_str());
if (!m_LuaState.Call(Tab->m_UserData, &a_Request, cLuaState::Return, Contents))
{
if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr
{
Tab = *itr;
break;
}
return "Lua encountered error while processing the page request";
}
if (Tab != nullptr)
{
AString Contents = Printf("WARNING: WebPlugin tab '%s' did not return a string!", Tab->Title.c_str());
if (!m_LuaState.Call(Tab->UserData, a_Request, cLuaState::Return, Contents))
{
return "Lua encountered error while processing the page request";
}
RetVal += Contents;
}
return RetVal;
return Contents;
}
@ -2048,13 +2038,7 @@ bool cPluginLua::AddWebTab(const AString & a_Title, lua_State * a_LuaState, int
LOGERROR("Only allowed to add a tab to a WebPlugin of your own Plugin!");
return false;
}
sWebPluginTab * Tab = new sWebPluginTab();
Tab->Title = a_Title;
Tab->SafeTitle = SafeString(a_Title);
Tab->UserData = a_FunctionReference;
GetTabs().push_back(Tab);
AddNewWebTab(a_Title, a_FunctionReference);
return true;
}

View File

@ -176,12 +176,13 @@ public:
/** Returns true if the plugin contains the function for the specified hook type, using the old-style registration (#121) */
bool CanAddOldStyleHook(int a_HookType);
// cWebPlugin override
// cWebPlugin overrides
virtual const AString GetWebTitle(void) const {return GetName(); }
virtual AString HandleWebRequest(const HTTPRequest & a_Request) override;
// cWebPlugin and WebAdmin stuff
virtual AString HandleWebRequest(const HTTPRequest * a_Request) override;
bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS <<
/** Adds a new web tab to webadmin.
Displaying the tab calls the referenced function. */
bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // Exported in ManualBindings.cpp
/** Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap. */
void BindCommand(const AString & a_Command, int a_FnRef);

View File

@ -24,32 +24,26 @@ cWebPlugin::cWebPlugin()
cWebPlugin::~cWebPlugin()
{
ASSERT(m_Tabs.empty()); // Has ClearTabs() been called?
// Remove from WebAdmin:
cWebAdmin * WebAdmin = cRoot::Get()->GetWebAdmin();
if (WebAdmin != nullptr)
{
WebAdmin->RemovePlugin(this);
}
for (TabList::iterator itr = m_Tabs.begin(); itr != m_Tabs.end(); ++itr)
{
delete *itr;
}
m_Tabs.clear();
}
std::list<std::pair<AString, AString> > cWebPlugin::GetTabNames(void)
cWebPlugin::cTabNames cWebPlugin::GetTabNames(void) const
{
std::list< std::pair< AString, AString > > NameList;
for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr)
std::list< std::pair<AString, AString>> NameList;
for (auto itr = m_Tabs.cbegin(), end = m_Tabs.cend(); itr != end; ++itr)
{
std::pair< AString, AString > StringPair;
StringPair.first = (*itr)->Title;
StringPair.second = (*itr)->SafeTitle;
NameList.push_back( StringPair);
NameList.push_back(std::make_pair((*itr)->m_Title, (*itr)->m_SafeTitle));
}
return NameList;
}
@ -58,41 +52,54 @@ std::list<std::pair<AString, AString> > cWebPlugin::GetTabNames(void)
std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest * a_Request)
cWebPlugin::cTabPtr cWebPlugin::GetTabBySafeTitle(const AString & a_SafeTitle) const
{
std::pair< AString, AString > Names;
AStringVector Split = StringSplit(a_Request->Path, "/");
if (Split.size() > 1)
cCSLock Lock(m_CSTabs);
for (auto itr = m_Tabs.cbegin(), end = m_Tabs.cend(); itr != end; ++itr)
{
sWebPluginTab * Tab = nullptr;
if (Split.size() > 2) // If we got the tab name, show that page
if ((*itr)->m_SafeTitle == a_SafeTitle)
{
for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr)
{
if ((*itr)->SafeTitle.compare(Split[2]) == 0) // This is the one!
{
Tab = *itr;
break;
}
}
}
else // Otherwise show the first tab
{
if (GetTabs().size() > 0)
{
Tab = *GetTabs().begin();
}
}
if (Tab != nullptr)
{
Names.first = Tab->Title;
Names.second = Tab->SafeTitle;
return *itr;
}
}
return nullptr;
}
return Names;
std::pair<AString, AString> cWebPlugin::GetTabNameForRequest(const HTTPRequest & a_Request)
{
AStringVector Split = StringSplit(a_Request.Path, "/");
if (Split.empty())
{
return std::make_pair(AString(), AString());
}
cCSLock Lock(m_CSTabs);
cTabPtr Tab;
if (Split.size() > 2) // If we got the tab name, show that page
{
for (auto itr = m_Tabs.cbegin(), end = m_Tabs.cend(); itr != end; ++itr)
{
if ((*itr)->m_SafeTitle.compare(Split[2]) == 0) // This is the one!
{
return std::make_pair((*itr)->m_Title, (*itr)->m_SafeTitle);
}
}
// Tab name not found, display an "empty" page:
return std::make_pair(AString(), AString());
}
// Show the first tab:
if (!m_Tabs.empty())
{
return std::make_pair(m_Tabs.front()->m_SafeTitle, m_Tabs.front()->m_SafeTitle);
}
// No tabs at all:
return std::make_pair(AString(), AString());
}
@ -101,14 +108,16 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest
AString cWebPlugin::SafeString(const AString & a_String)
{
AString RetVal;
for (unsigned int i = 0; i < a_String.size(); ++i)
auto len = a_String.size();
RetVal.reserve(len);
for (size_t i = 0; i < len; ++i)
{
char c = a_String[i];
if (c == ' ')
{
c = '_';
}
RetVal.push_back( c);
RetVal.push_back(c);
}
return RetVal;
}
@ -116,3 +125,28 @@ AString cWebPlugin::SafeString(const AString & a_String)
void cWebPlugin::AddNewWebTab(const AString & a_Title, int a_UserData)
{
auto Tab = std::make_shared<cTab>(a_Title, a_UserData);
cCSLock Lock(m_CSTabs);
m_Tabs.push_back(Tab);
}
void cWebPlugin::ClearTabs(void)
{
// Remove the webadmin tabs:
cTabPtrs Tabs;
{
cCSLock Lock(m_CSTabs);
std::swap(Tabs, m_Tabs);
}
}

View File

@ -12,34 +12,67 @@ class cWebPlugin
{
public:
// tolua_end
struct cTab
{
AString m_Title;
AString m_SafeTitle;
int m_UserData;
cTab(const AString & a_Title, int a_UserData):
m_Title(a_Title),
m_SafeTitle(cWebPlugin::SafeString(a_Title)),
m_UserData(a_UserData)
{
}
};
typedef SharedPtr<cTab> cTabPtr;
typedef std::list<cTabPtr> cTabPtrs;
typedef std::list<std::pair<AString, AString>> cTabNames;
cWebPlugin();
virtual ~cWebPlugin();
// tolua_begin
/** Returns the title of the plugin, as it should be presented in the webadmin's pages tree. */
virtual const AString GetWebTitle(void) const = 0;
virtual AString HandleWebRequest(const HTTPRequest * a_Request) = 0;
/** Sanitizes the input string, replacing spaces with underscores. */
static AString SafeString(const AString & a_String);
static AString SafeString( const AString & a_String);
// tolua_end
struct sWebPluginTab
{
std::string Title;
std::string SafeTitle;
virtual AString HandleWebRequest(const HTTPRequest & a_Request) = 0;
int UserData;
};
/** Adds a new web tab with the specified contents. */
void AddNewWebTab(const AString & a_Title, int a_UserData);
typedef std::list< sWebPluginTab* > TabList;
TabList & GetTabs() { return m_Tabs; }
/** Removes all the tabs. */
void ClearTabs(void);
typedef std::list< std::pair<AString, AString> > TabNameList;
TabNameList GetTabNames(); // >> EXPORTED IN MANUALBINDINGS <<
std::pair< AString, AString > GetTabNameForRequest(const HTTPRequest* a_Request);
/** Returns all the tabs that this plugin has registered. */
const cTabPtrs & GetTabs(void) const { return m_Tabs; }
/** Returns all of the tabs that this plugin has registered. */
cTabNames GetTabNames(void) const; // Exported in ManualBindings.cpp
/** Returns the tab that has the specified SafeTitle.
Returns nullptr if no such tab. */
cTabPtr GetTabBySafeTitle(const AString & a_SafeTitle) const;
std::pair<AString, AString> GetTabNameForRequest(const HTTPRequest & a_Request);
private:
TabList m_Tabs;
/** All tabs that this plugin has registered.
Protected against multithreaded access by m_CSTabs. */
cTabPtrs m_Tabs;
/** Protects m_Tabs against multithreaded access. */
mutable cCriticalSection m_CSTabs;
}; // tolua_export

View File

@ -464,10 +464,10 @@ sWebAdminPage cWebAdmin::GetPage(const HTTPRequest & a_Request)
{
if ((*itr)->GetWebTitle() == Split[1])
{
Page.Content = (*itr)->HandleWebRequest(&a_Request);
Page.Content = (*itr)->HandleWebRequest(a_Request);
cWebPlugin * WebPlugin = *itr;
FoundPlugin = WebPlugin->GetWebTitle();
AString TabName = WebPlugin->GetTabNameForRequest(&a_Request).first;
AString TabName = WebPlugin->GetTabNameForRequest(a_Request).first;
Page.PluginName = FoundPlugin;
Page.TabName = TabName;
break;