00001 /* 00002 * Copyright 2016 The Cartographer Authors 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef CARTOGRAPHER_COMMON_LUA_PARAMETER_DICTIONARY_H_ 00018 #define CARTOGRAPHER_COMMON_LUA_PARAMETER_DICTIONARY_H_ 00019 00020 #include <map> 00021 #include <memory> 00022 #include <string> 00023 #include <vector> 00024 00025 #include "cartographer/common/lua.h" 00026 #include "cartographer/common/port.h" 00027 #include "glog/logging.h" 00028 00029 namespace cartographer { 00030 namespace common { 00031 00032 // Resolves file paths and file content for the Lua 'read' and 'include' 00033 // functions. Use this to configure where those functions load other files from. 00034 class FileResolver { 00035 public: 00036 virtual ~FileResolver() {} 00037 virtual std::string GetFullPathOrDie(const std::string& basename) = 0; 00038 virtual std::string GetFileContentOrDie(const std::string& basename) = 0; 00039 }; 00040 00041 // A parameter dictionary that gets loaded from Lua code. 00042 class LuaParameterDictionary { 00043 public: 00044 // Constructs the dictionary from a Lua Table specification. 00045 LuaParameterDictionary(const std::string& code, 00046 std::unique_ptr<FileResolver> file_resolver); 00047 00048 LuaParameterDictionary(const LuaParameterDictionary&) = delete; 00049 LuaParameterDictionary& operator=(const LuaParameterDictionary&) = delete; 00050 00051 // Constructs a LuaParameterDictionary without reference counting. 00052 static std::unique_ptr<LuaParameterDictionary> NonReferenceCounted( 00053 const std::string& code, std::unique_ptr<FileResolver> file_resolver); 00054 00055 ~LuaParameterDictionary(); 00056 00057 // Returns all available keys. 00058 std::vector<std::string> GetKeys() const; 00059 00060 // Returns true if the key is in this dictionary. 00061 bool HasKey(const std::string& key) const; 00062 00063 // These methods CHECK() that the 'key' exists. 00064 std::string GetString(const std::string& key); 00065 double GetDouble(const std::string& key); 00066 int GetInt(const std::string& key); 00067 bool GetBool(const std::string& key); 00068 std::unique_ptr<LuaParameterDictionary> GetDictionary(const std::string& key); 00069 00070 // Gets an int from the dictionary and CHECK()s that it is non-negative. 00071 int GetNonNegativeInt(const std::string& key); 00072 00073 // Returns a string representation for this LuaParameterDictionary. 00074 std::string ToString() const; 00075 00076 // Returns the values of the keys '1', '2', '3' as the given types. 00077 std::vector<double> GetArrayValuesAsDoubles(); 00078 std::vector<std::string> GetArrayValuesAsStrings(); 00079 std::vector<std::unique_ptr<LuaParameterDictionary>> 00080 GetArrayValuesAsDictionaries(); 00081 00082 private: 00083 enum class ReferenceCount { YES, NO }; 00084 LuaParameterDictionary(const std::string& code, 00085 ReferenceCount reference_count, 00086 std::unique_ptr<FileResolver> file_resolver); 00087 00088 // For GetDictionary(). 00089 LuaParameterDictionary(lua_State* L, ReferenceCount reference_count, 00090 std::shared_ptr<FileResolver> file_resolver); 00091 00092 // Function that recurses to keep track of indent for ToString(). 00093 std::string DoToString(const std::string& indent) const; 00094 00095 // Pop the top of the stack and CHECKs that the type is correct. 00096 double PopDouble() const; 00097 int PopInt() const; 00098 bool PopBool() const; 00099 00100 // Pop the top of the stack and CHECKs that it is a string. The returned value 00101 // is either quoted to be suitable to be read back by a Lua interpretor or 00102 // not. 00103 enum class Quoted { YES, NO }; 00104 std::string PopString(Quoted quoted) const; 00105 00106 // Creates a LuaParameterDictionary from the Lua table at the top of the 00107 // stack, either with or without reference counting. 00108 std::unique_ptr<LuaParameterDictionary> PopDictionary( 00109 ReferenceCount reference_count) const; 00110 00111 // CHECK() that 'key' is in the dictionary. 00112 void CheckHasKey(const std::string& key) const; 00113 00114 // CHECK() that 'key' is in this dictionary and reference it as being used. 00115 void CheckHasKeyAndReference(const std::string& key); 00116 00117 // If desired, this can be called in the destructor of a derived class. It 00118 // will CHECK() that all keys defined in the configuration have been used 00119 // exactly once and resets the reference counter. 00120 void CheckAllKeysWereUsedExactlyOnceAndReset(); 00121 00122 // Reads a file into a Lua string. 00123 static int LuaRead(lua_State* L); 00124 00125 // Handles inclusion of other Lua files and prevents double inclusion. 00126 static int LuaInclude(lua_State* L); 00127 00128 lua_State* L_; // The name is by convention in the Lua World. 00129 int index_into_reference_table_; 00130 00131 // This is shared with all the sub dictionaries. 00132 const std::shared_ptr<FileResolver> file_resolver_; 00133 00134 // If true will check that all keys were used on destruction. 00135 const ReferenceCount reference_count_; 00136 00137 // This is modified with every call to Get* in order to verify that all 00138 // parameters are read exactly once. 00139 std::map<std::string, int> reference_counts_; 00140 00141 // List of all included files in order of inclusion. Used to prevent double 00142 // inclusion. 00143 std::vector<std::string> included_files_; 00144 }; 00145 00146 } // namespace common 00147 } // namespace cartographer 00148 00149 #endif // CARTOGRAPHER_COMMON_LUA_PARAMETER_DICTIONARY_H_