Merge
This commit is contained in:
parent
1797862bf9
commit
ba2e36fd37
@ -1305,10 +1305,12 @@ mentioned in "Nodes". However, it is possible to insert extra data into a
|
|||||||
node. It is called "node metadata"; See "`NodeMetaRef`".
|
node. It is called "node metadata"; See "`NodeMetaRef`".
|
||||||
|
|
||||||
Metadata contains two things:
|
Metadata contains two things:
|
||||||
|
|
||||||
* A key-value store
|
* A key-value store
|
||||||
* An inventory
|
* An inventory
|
||||||
|
|
||||||
Some of the values in the key-value store are handled specially:
|
Some of the values in the key-value store are handled specially:
|
||||||
|
|
||||||
* `formspec`: Defines a right-click inventory menu. See "Formspec".
|
* `formspec`: Defines a right-click inventory menu. See "Formspec".
|
||||||
* `infotext`: Text shown on the screen when the node is pointed at
|
* `infotext`: Text shown on the screen when the node is pointed at
|
||||||
|
|
||||||
@ -2938,6 +2940,7 @@ core.CONTENT_IGNORE (ID for "ignore" nodes)
|
|||||||
Inside of `on_generated()` callbacks, it is possible to retrieve the same VoxelManip object used by the
|
Inside of `on_generated()` callbacks, it is possible to retrieve the same VoxelManip object used by the
|
||||||
core's Map Generator (commonly abbreviated Mapgen). Most of the rules previously described still apply
|
core's Map Generator (commonly abbreviated Mapgen). Most of the rules previously described still apply
|
||||||
but with a few differences:
|
but with a few differences:
|
||||||
|
|
||||||
* The Mapgen VoxelManip object is retrieved using: `minetest.get_mapgen_object("voxelmanip")`
|
* The Mapgen VoxelManip object is retrieved using: `minetest.get_mapgen_object("voxelmanip")`
|
||||||
* This VoxelManip object already has the region of map just generated loaded into it; it's not necessary
|
* This VoxelManip object already has the region of map just generated loaded into it; it's not necessary
|
||||||
to call `VoxelManip:read_from_map()` before using a Mapgen VoxelManip.
|
to call `VoxelManip:read_from_map()` before using a Mapgen VoxelManip.
|
||||||
@ -2996,7 +2999,7 @@ will place the schematic inside of the VoxelManip.
|
|||||||
* `update_map()`: Update map after writing chunk back to map.
|
* `update_map()`: Update map after writing chunk back to map.
|
||||||
* To be used only by `VoxelManip` objects created by the mod itself;
|
* To be used only by `VoxelManip` objects created by the mod itself;
|
||||||
not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object`
|
not a `VoxelManip` that was retrieved from `minetest.get_mapgen_object`
|
||||||
* `set_lighting(light, p1, p2)`: Set the lighting within the `VoxelManip` to a uniform value
|
* `set_lighting(light, [p1, p2])`: Set the lighting within the `VoxelManip` to a uniform value
|
||||||
* `light` is a table, `{day=<0...15>, night=<0...15>}`
|
* `light` is a table, `{day=<0...15>, night=<0...15>}`
|
||||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||||
* (`p1`, `p2`) is the area in which lighting is set;
|
* (`p1`, `p2`) is the area in which lighting is set;
|
||||||
@ -3010,10 +3013,12 @@ will place the schematic inside of the VoxelManip.
|
|||||||
* expects lighting data in the same format that `get_light_data()` returns
|
* expects lighting data in the same format that `get_light_data()` returns
|
||||||
* `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object
|
* `get_param2_data()`: Gets the raw `param2` data read into the `VoxelManip` object
|
||||||
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
* `set_param2_data(param2_data)`: Sets the `param2` contents of each node in the `VoxelManip`
|
||||||
* `calc_lighting(p1, p2)`: Calculate lighting within the `VoxelManip`
|
* `calc_lighting([p1, p2], [propagate_shadow])`: Calculate lighting within the `VoxelManip`
|
||||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||||
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area
|
* (`p1`, `p2`) is the area in which lighting is set; defaults to the whole area
|
||||||
if left out
|
if left out or nil
|
||||||
|
* `propagate_shadow` is an optional boolean deciding whether shadows in a generated
|
||||||
|
mapchunk above are propagated down into the mapchunk; defaults to `true` if left out
|
||||||
* `update_liquids()`: Update liquid flow
|
* `update_liquids()`: Update liquid flow
|
||||||
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator
|
* `was_modified()`: Returns `true` or `false` if the data in the voxel manipulator
|
||||||
had been modified since the last read from map, due to a call to
|
had been modified since the last read from map, due to a call to
|
||||||
|
@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
static std::string getMediaCacheDir()
|
static std::string getMediaCacheDir()
|
||||||
{
|
{
|
||||||
return porting::path_user + DIR_DELIM + "cache" + DIR_DELIM + "media";
|
return porting::path_cache + DIR_DELIM + "media";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -707,5 +707,10 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Rename(const std::string &from, const std::string &to)
|
||||||
|
{
|
||||||
|
return rename(from.c_str(), to.c_str()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|
||||||
|
@ -115,6 +115,8 @@ const char *GetFilenameFromPath(const char *path);
|
|||||||
|
|
||||||
bool safeWriteToFile(const std::string &path, const std::string &content);
|
bool safeWriteToFile(const std::string &path, const std::string &content);
|
||||||
|
|
||||||
|
bool Rename(const std::string &from, const std::string &to);
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
12
src/main.cpp
12
src/main.cpp
@ -164,7 +164,13 @@ int main(int argc, char *argv[])
|
|||||||
setup_log_params(cmd_args);
|
setup_log_params(cmd_args);
|
||||||
|
|
||||||
porting::signal_handler_init();
|
porting::signal_handler_init();
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
porting::initAndroid();
|
||||||
|
porting::initializePathsAndroid();
|
||||||
|
#else
|
||||||
porting::initializePaths();
|
porting::initializePaths();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!create_userdata_path()) {
|
if (!create_userdata_path()) {
|
||||||
errorstream << "Cannot create user data directory" << std::endl;
|
errorstream << "Cannot create user data directory" << std::endl;
|
||||||
@ -422,9 +428,6 @@ static bool create_userdata_path()
|
|||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
porting::initAndroid();
|
|
||||||
|
|
||||||
porting::setExternalStorageDir(porting::jnienv);
|
|
||||||
if (!fs::PathExists(porting::path_user)) {
|
if (!fs::PathExists(porting::path_user)) {
|
||||||
success = fs::CreateDir(porting::path_user);
|
success = fs::CreateDir(porting::path_user);
|
||||||
} else {
|
} else {
|
||||||
@ -436,9 +439,6 @@ static bool create_userdata_path()
|
|||||||
success = fs::CreateDir(porting::path_user);
|
success = fs::CreateDir(porting::path_user);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
infostream << "path_share = " << porting::path_share << std::endl;
|
|
||||||
infostream << "path_user = " << porting::path_user << std::endl;
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,37 +264,20 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax)
|
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax,
|
||||||
|
bool propagate_shadow)
|
||||||
{
|
{
|
||||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||||
//TimeTaker t("updateLighting");
|
//TimeTaker t("updateLighting");
|
||||||
|
|
||||||
propagateSunlight(nmin, nmax);
|
propagateSunlight(nmin, nmax, propagate_shadow);
|
||||||
spreadLight(full_nmin, full_nmax);
|
spreadLight(full_nmin, full_nmax);
|
||||||
|
|
||||||
//printf("updateLighting: %dms\n", t.stop());
|
//printf("updateLighting: %dms\n", t.stop());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow)
|
||||||
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax)
|
|
||||||
{
|
|
||||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
|
||||||
//TimeTaker t("updateLighting");
|
|
||||||
|
|
||||||
propagateSunlight(
|
|
||||||
nmin - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
|
||||||
nmax + v3s16(1, 0, 1) * MAP_BLOCKSIZE);
|
|
||||||
|
|
||||||
spreadLight(
|
|
||||||
nmin - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
|
||||||
nmax + v3s16(1, 1, 1) * MAP_BLOCKSIZE);
|
|
||||||
|
|
||||||
//printf("updateLighting: %dms\n", t.stop());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax)
|
|
||||||
{
|
{
|
||||||
//TimeTaker t("propagateSunlight");
|
//TimeTaker t("propagateSunlight");
|
||||||
VoxelArea a(nmin, nmax);
|
VoxelArea a(nmin, nmax);
|
||||||
@ -308,7 +291,8 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax)
|
|||||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||||
if (block_is_underground)
|
if (block_is_underground)
|
||||||
continue;
|
continue;
|
||||||
} else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN) {
|
} else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN &&
|
||||||
|
propagate_shadow) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
vm->m_area.add_y(em, i, -1);
|
vm->m_area.add_y(em, i, -1);
|
||||||
@ -326,7 +310,6 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax)
|
void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax)
|
||||||
{
|
{
|
||||||
//TimeTaker t("spreadLight");
|
//TimeTaker t("spreadLight");
|
||||||
|
@ -173,12 +173,9 @@ public:
|
|||||||
|
|
||||||
void setLighting(u8 light, v3s16 nmin, v3s16 nmax);
|
void setLighting(u8 light, v3s16 nmin, v3s16 nmax);
|
||||||
void lightSpread(VoxelArea &a, v3s16 p, u8 light);
|
void lightSpread(VoxelArea &a, v3s16 p, u8 light);
|
||||||
|
void calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax,
|
||||||
void calcLighting(v3s16 nmin, v3s16 nmax);
|
bool propagate_shadow = true);
|
||||||
void calcLighting(v3s16 nmin, v3s16 nmax,
|
void propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow);
|
||||||
v3s16 full_nmin, v3s16 full_nmax);
|
|
||||||
|
|
||||||
void propagateSunlight(v3s16 nmin, v3s16 nmax);
|
|
||||||
void spreadLight(v3s16 nmin, v3s16 nmax);
|
void spreadLight(v3s16 nmin, v3s16 nmax);
|
||||||
|
|
||||||
virtual void makeChunk(BlockMakeData *data) {}
|
virtual void makeChunk(BlockMakeData *data) {}
|
||||||
|
@ -38,6 +38,9 @@ MapgenSinglenode::MapgenSinglenode(int mapgenid,
|
|||||||
c_node = ndef->getId("mapgen_singlenode");
|
c_node = ndef->getId("mapgen_singlenode");
|
||||||
if (c_node == CONTENT_IGNORE)
|
if (c_node == CONTENT_IGNORE)
|
||||||
c_node = CONTENT_AIR;
|
c_node = CONTENT_AIR;
|
||||||
|
|
||||||
|
MapNode n_node(c_node);
|
||||||
|
set_light = (ndef->get(n_node).sunlight_propagates) ? LIGHT_SUN : 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +48,7 @@ MapgenSinglenode::~MapgenSinglenode()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////// Map generator
|
//////////////////////// Map generator
|
||||||
|
|
||||||
void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
||||||
@ -53,11 +57,11 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||||||
assert(data->vmanip);
|
assert(data->vmanip);
|
||||||
assert(data->nodedef);
|
assert(data->nodedef);
|
||||||
assert(data->blockpos_requested.X >= data->blockpos_min.X &&
|
assert(data->blockpos_requested.X >= data->blockpos_min.X &&
|
||||||
data->blockpos_requested.Y >= data->blockpos_min.Y &&
|
data->blockpos_requested.Y >= data->blockpos_min.Y &&
|
||||||
data->blockpos_requested.Z >= data->blockpos_min.Z);
|
data->blockpos_requested.Z >= data->blockpos_min.Z);
|
||||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||||
|
|
||||||
this->generating = true;
|
this->generating = true;
|
||||||
this->vm = data->vmanip;
|
this->vm = data->vmanip;
|
||||||
@ -67,8 +71,8 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||||||
v3s16 blockpos_max = data->blockpos_max;
|
v3s16 blockpos_max = data->blockpos_max;
|
||||||
|
|
||||||
// Area of central chunk
|
// Area of central chunk
|
||||||
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
v3s16 node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||||
v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
|
v3s16 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
||||||
|
|
||||||
blockseed = getBlockSeed2(node_min, data->seed);
|
blockseed = getBlockSeed2(node_min, data->seed);
|
||||||
|
|
||||||
@ -87,15 +91,15 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||||||
// Add top and bottom side of water to transforming_liquid queue
|
// Add top and bottom side of water to transforming_liquid queue
|
||||||
updateLiquid(&data->transforming_liquid, node_min, node_max);
|
updateLiquid(&data->transforming_liquid, node_min, node_max);
|
||||||
|
|
||||||
// Calculate lighting
|
// Set lighting
|
||||||
if (flags & MG_LIGHT)
|
if ((flags & MG_LIGHT) && set_light == LIGHT_SUN)
|
||||||
calcLighting(node_min, node_max);
|
setLighting(LIGHT_SUN, node_min, node_max);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MapgenSinglenode::getGroundLevelAtPoint(v2s16 p)
|
int MapgenSinglenode::getGroundLevelAtPoint(v2s16 p)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ class MapgenSinglenode : public Mapgen {
|
|||||||
public:
|
public:
|
||||||
u32 flags;
|
u32 flags;
|
||||||
content_t c_node;
|
content_t c_node;
|
||||||
|
u8 set_light;
|
||||||
|
|
||||||
MapgenSinglenode(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
MapgenSinglenode(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||||
~MapgenSinglenode();
|
~MapgenSinglenode();
|
||||||
|
@ -593,7 +593,9 @@ void MapgenV6::makeChunk(BlockMakeData *data)
|
|||||||
|
|
||||||
// Calculate lighting
|
// Calculate lighting
|
||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min, node_max);
|
calcLighting(node_min - v3s16(1, 1, 1) * MAP_BLOCKSIZE,
|
||||||
|
node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
|
full_node_min, full_node_max);
|
||||||
|
|
||||||
this->generating = false;
|
this->generating = false;
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ void signal_handler_init(void)
|
|||||||
std::string path_share = "..";
|
std::string path_share = "..";
|
||||||
std::string path_user = "..";
|
std::string path_user = "..";
|
||||||
std::string path_locale = path_share + DIR_DELIM + "locale";
|
std::string path_locale = path_share + DIR_DELIM + "locale";
|
||||||
|
std::string path_cache = path_user + DIR_DELIM + "cache";
|
||||||
|
|
||||||
|
|
||||||
std::string getDataPath(const char *subpath)
|
std::string getDataPath(const char *subpath)
|
||||||
@ -463,6 +464,25 @@ bool setSystemPaths()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void migrateCachePath()
|
||||||
|
{
|
||||||
|
const std::string local_cache_path = path_user + DIR_DELIM + "cache";
|
||||||
|
|
||||||
|
// Delete tmp folder if it exists (it only ever contained
|
||||||
|
// a temporary ogg file, which is no longer used).
|
||||||
|
if (fs::PathExists(local_cache_path + DIR_DELIM + "tmp"))
|
||||||
|
fs::RecursiveDelete(local_cache_path + DIR_DELIM + "tmp");
|
||||||
|
|
||||||
|
// Bail if migration impossible
|
||||||
|
if (path_cache == local_cache_path || !fs::PathExists(local_cache_path)
|
||||||
|
|| fs::PathExists(path_cache)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!fs::Rename(local_cache_path, path_cache)) {
|
||||||
|
errorstream << "Failed to migrate local cache path "
|
||||||
|
"to system path!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void initializePaths()
|
void initializePaths()
|
||||||
{
|
{
|
||||||
@ -513,10 +533,27 @@ void initializePaths()
|
|||||||
if (!setSystemPaths())
|
if (!setSystemPaths())
|
||||||
errorstream << "Failed to get one or more system-wide path" << std::endl;
|
errorstream << "Failed to get one or more system-wide path" << std::endl;
|
||||||
|
|
||||||
|
// Initialize path_cache
|
||||||
|
// First try $XDG_CACHE_HOME/PROJECT_NAME
|
||||||
|
const char *cache_dir = getenv("XDG_CACHE_HOME");
|
||||||
|
if (cache_dir) {
|
||||||
|
path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME;
|
||||||
|
} else {
|
||||||
|
// Then try $HOME/.cache/PROJECT_NAME
|
||||||
|
const char *home_dir = getenv("HOME");
|
||||||
|
if (home_dir) {
|
||||||
|
path_cache = std::string(home_dir) + DIR_DELIM + ".cache"
|
||||||
|
+ DIR_DELIM + PROJECT_NAME;
|
||||||
|
}
|
||||||
|
// If neither works, leave it at $PATH_USER/cache
|
||||||
|
}
|
||||||
|
// Migrate cache folder to new location if possible
|
||||||
|
migrateCachePath();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
infostream << "Detected share path: " << path_share << std::endl;
|
infostream << "Detected share path: " << path_share << std::endl;
|
||||||
infostream << "Detected user path: " << path_user << std::endl;
|
infostream << "Detected user path: " << path_user << std::endl;
|
||||||
|
infostream << "Detected cache path: " << path_cache << std::endl;
|
||||||
|
|
||||||
bool found_localedir = false;
|
bool found_localedir = false;
|
||||||
#ifdef STATIC_LOCALEDIR
|
#ifdef STATIC_LOCALEDIR
|
||||||
@ -542,7 +579,6 @@ void initializePaths()
|
|||||||
if (!found_localedir) {
|
if (!found_localedir) {
|
||||||
errorstream << "Couldn't find a locale directory!" << std::endl;
|
errorstream << "Couldn't find a locale directory!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,12 +147,23 @@ extern std::string path_user;
|
|||||||
*/
|
*/
|
||||||
extern std::string path_locale;
|
extern std::string path_locale;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Path to directory for storing caches.
|
||||||
|
*/
|
||||||
|
extern std::string path_cache;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get full path of stuff in data directory.
|
Get full path of stuff in data directory.
|
||||||
Example: "stone.png" -> "../data/stone.png"
|
Example: "stone.png" -> "../data/stone.png"
|
||||||
*/
|
*/
|
||||||
std::string getDataPath(const char *subpath);
|
std::string getDataPath(const char *subpath);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move cache folder from path_user to the
|
||||||
|
system cache location if possible.
|
||||||
|
*/
|
||||||
|
void migrateCachePath();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize path_*.
|
Initialize path_*.
|
||||||
*/
|
*/
|
||||||
|
@ -177,29 +177,63 @@ void cleanupAndroid()
|
|||||||
ANativeActivity_finish(app_global->activity);
|
ANativeActivity_finish(app_global->activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setExternalStorageDir(JNIEnv* lJNIEnv)
|
static std::string javaStringToUTF8(jstring js)
|
||||||
{
|
{
|
||||||
// Android: Retrieve ablsolute path to external storage device (sdcard)
|
std::string str;
|
||||||
jclass ClassEnv = lJNIEnv->FindClass("android/os/Environment");
|
// Get string as a UTF-8 c-string
|
||||||
jmethodID MethodDir =
|
const char *c_str = jnienv->GetStringUTFChars(js, NULL);
|
||||||
lJNIEnv->GetStaticMethodID(ClassEnv,
|
// Save it
|
||||||
"getExternalStorageDirectory","()Ljava/io/File;");
|
str = c_str;
|
||||||
jobject ObjectFile = lJNIEnv->CallStaticObjectMethod(ClassEnv, MethodDir);
|
// And free the c-string
|
||||||
jclass ClassFile = lJNIEnv->FindClass("java/io/File");
|
jnienv->ReleaseStringUTFChars(js, c_str);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
jmethodID MethodPath =
|
// Calls static method if obj is NULL
|
||||||
lJNIEnv->GetMethodID(ClassFile, "getAbsolutePath",
|
static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File,
|
||||||
"()Ljava/lang/String;");
|
jmethodID mt_getAbsPath, const char *getter)
|
||||||
jstring StringPath =
|
{
|
||||||
(jstring) lJNIEnv->CallObjectMethod(ObjectFile, MethodPath);
|
// Get getter method
|
||||||
|
jmethodID mt_getter;
|
||||||
|
if (obj)
|
||||||
|
mt_getter = jnienv->GetMethodID(cls, getter,
|
||||||
|
"()Ljava/io/File;");
|
||||||
|
else
|
||||||
|
mt_getter = jnienv->GetStaticMethodID(cls, getter,
|
||||||
|
"()Ljava/io/File;");
|
||||||
|
|
||||||
const char *externalPath = lJNIEnv->GetStringUTFChars(StringPath, NULL);
|
// Call getter
|
||||||
std::string userPath(externalPath);
|
jobject ob_file;
|
||||||
lJNIEnv->ReleaseStringUTFChars(StringPath, externalPath);
|
if (obj)
|
||||||
|
ob_file = jnienv->CallObjectMethod(obj, mt_getter);
|
||||||
|
else
|
||||||
|
ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter);
|
||||||
|
|
||||||
path_storage = userPath;
|
// Call getAbsolutePath
|
||||||
path_user = userPath + DIR_DELIM + PROJECT_NAME_C;
|
jstring js_path = (jstring) jnienv->CallObjectMethod(ob_file,
|
||||||
path_share = userPath + DIR_DELIM + PROJECT_NAME_C;
|
mt_getAbsPath);
|
||||||
|
|
||||||
|
return javaStringToUTF8(js_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializePathsAndroid()
|
||||||
|
{
|
||||||
|
// Get Environment class
|
||||||
|
jclass cls_Env = jnienv->FindClass("android/os/Environment");
|
||||||
|
// Get File class
|
||||||
|
jclass cls_File = jnienv->FindClass("java/io/File");
|
||||||
|
// Get getAbsolutePath method
|
||||||
|
jmethodID mt_getAbsPath = jnienv->GetMethodID(cls_File,
|
||||||
|
"getAbsolutePath", "()Ljava/lang/String;");
|
||||||
|
|
||||||
|
path_cache = getAndroidPath(nativeActivity, app_global->activity->clazz,
|
||||||
|
cls_File, mt_getAbsPath, "getCacheDir");
|
||||||
|
path_storage = getAndroidPath(cls_Env, NULL, cls_File, mt_getAbsPath,
|
||||||
|
"getExternalStorageDirectory");
|
||||||
|
path_user = path_storage + DIR_DELIM + PROJECT_NAME_C;
|
||||||
|
path_share = path_storage + DIR_DELIM + PROJECT_NAME_C;
|
||||||
|
|
||||||
|
migrateCachePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showInputDialog(const std::string& acceptButton, const std::string& hint,
|
void showInputDialog(const std::string& acceptButton, const std::string& hint,
|
||||||
|
@ -43,10 +43,10 @@ void initAndroid();
|
|||||||
void cleanupAndroid();
|
void cleanupAndroid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set storage dir on external sdcard#
|
* Initializes path_* variables for Android
|
||||||
* @param lJNIEnv environment from android
|
* @param env Android JNI environment
|
||||||
*/
|
*/
|
||||||
void setExternalStorageDir(JNIEnv* lJNIEnv);
|
void initializePathsAndroid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* use java function to copy media from assets to external storage
|
* use java function to copy media from assets to external storage
|
||||||
|
@ -951,9 +951,9 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||||||
warn_if_field_exists(L, index, "noise_threshhold",
|
warn_if_field_exists(L, index, "noise_threshhold",
|
||||||
"Deprecated: new name is \"noise_threshold\".");
|
"Deprecated: new name is \"noise_threshold\".");
|
||||||
|
|
||||||
int nthresh;
|
float nthresh;
|
||||||
if (!getintfield(L, index, "noise_threshold", nthresh) &&
|
if (!getfloatfield(L, index, "noise_threshold", nthresh) &&
|
||||||
!getintfield(L, index, "noise_threshhold", nthresh))
|
!getfloatfield(L, index, "noise_threshhold", nthresh))
|
||||||
nthresh = 0;
|
nthresh = 0;
|
||||||
ore->nthresh = nthresh;
|
ore->nthresh = nthresh;
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
|
|||||||
v3s16 fpmax = vm->m_area.MaxEdge;
|
v3s16 fpmax = vm->m_area.MaxEdge;
|
||||||
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock;
|
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock;
|
||||||
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock;
|
v3s16 pmax = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock;
|
||||||
|
bool propagate_shadow = lua_isboolean(L, 4) ? lua_toboolean(L, 4) : true;
|
||||||
|
|
||||||
sortBoxVerticies(pmin, pmax);
|
sortBoxVerticies(pmin, pmax);
|
||||||
if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
|
if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
|
||||||
@ -191,7 +192,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
|
|||||||
mg.ndef = ndef;
|
mg.ndef = ndef;
|
||||||
mg.water_level = emerge->params.water_level;
|
mg.water_level = emerge->params.water_level;
|
||||||
|
|
||||||
mg.calcLighting(pmin, pmax, fpmin, fpmax);
|
mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
set(JTHREAD_SRCS
|
set(JTHREAD_SRCS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/event.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mutex.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/mutex.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/thread.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/thread.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/semaphore.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/semaphore.cpp
|
||||||
|
95
src/threading/event.cpp
Normal file
95
src/threading/event.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the JThread package, which contains some object-
|
||||||
|
oriented thread wrappers for different thread implementations.
|
||||||
|
|
||||||
|
Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "threading/event.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus < 201103L
|
||||||
|
Event::Event()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
event = CreateEvent(NULL, false, false, NULL);
|
||||||
|
#else
|
||||||
|
pthread_cond_init(&cv, NULL);
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Event::~Event()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
CloseHandle(event);
|
||||||
|
#else
|
||||||
|
pthread_cond_destroy(&cv);
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void Event::wait()
|
||||||
|
{
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
MutexAutoLock lock(mutex);
|
||||||
|
while (!notified) {
|
||||||
|
cv.wait(lock);
|
||||||
|
}
|
||||||
|
notified = false;
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
WaitForSingleObject(event, INFINITE);
|
||||||
|
#else
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
while (!notified) {
|
||||||
|
pthread_cond_wait(&cv, &mutex);
|
||||||
|
}
|
||||||
|
notified = false;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Event::signal()
|
||||||
|
{
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
MutexAutoLock lock(mutex);
|
||||||
|
notified = true;
|
||||||
|
cv.notify_one();
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
SetEvent(event);
|
||||||
|
#else
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
notified = true;
|
||||||
|
pthread_cond_signal(&cv);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
@ -26,30 +26,42 @@ DEALINGS IN THE SOFTWARE.
|
|||||||
#ifndef THREADING_EVENT_H
|
#ifndef THREADING_EVENT_H
|
||||||
#define THREADING_EVENT_H
|
#define THREADING_EVENT_H
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if __cplusplus >= 201103L
|
||||||
#include <windows.h>
|
#include <condition_variable>
|
||||||
|
#include "threading/mutex.h"
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#include <windef.h>
|
||||||
#else
|
#else
|
||||||
#include "threading/semaphore.h"
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** A syncronization primitive that will wake up one waiting thread when signaled.
|
||||||
|
* Calling @c signal() multiple times before a waiting thread has had a chance
|
||||||
|
* to notice the signal will wake only one thread. Additionally, if no threads
|
||||||
|
* are waiting on the event when it is signaled, the next call to @c wait()
|
||||||
|
* will return (almost) immediately.
|
||||||
|
*/
|
||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
#ifdef _WIN32
|
#if __cplusplus < 201103L
|
||||||
Event() { event = CreateEvent(NULL, false, false, NULL); }
|
Event();
|
||||||
~Event() { CloseHandle(event); }
|
~Event();
|
||||||
void wait() { WaitForSingleObject(event, INFINITE); }
|
|
||||||
void signal() { SetEvent(event); }
|
|
||||||
#else
|
|
||||||
void wait() { sem.wait(); }
|
|
||||||
void signal() { sem.post(); }
|
|
||||||
#endif
|
#endif
|
||||||
|
void wait();
|
||||||
|
void signal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _WIN32
|
#if __cplusplus >= 201103L
|
||||||
|
std::condition_variable cv;
|
||||||
|
Mutex mutex;
|
||||||
|
bool notified;
|
||||||
|
#elif defined(_WIN32)
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
#else
|
#else
|
||||||
Semaphore sem;
|
pthread_cond_t cv;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
bool notified;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user