Merge
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`".
|
||||
|
||||
Metadata contains two things:
|
||||
|
||||
* A key-value store
|
||||
* An inventory
|
||||
|
||||
Some of the values in the key-value store are handled specially:
|
||||
|
||||
* `formspec`: Defines a right-click inventory menu. See "Formspec".
|
||||
* `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
|
||||
core's Map Generator (commonly abbreviated Mapgen). Most of the rules previously described still apply
|
||||
but with a few differences:
|
||||
|
||||
* 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
|
||||
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.
|
||||
* To be used only by `VoxelManip` objects created by the mod itself;
|
||||
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>}`
|
||||
* To be used only by a `VoxelManip` object from `minetest.get_mapgen_object`
|
||||
* (`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
|
||||
* `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`
|
||||
* `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`
|
||||
* (`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
|
||||
* `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
|
||||
|
|
|
@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ const char *GetFilenameFromPath(const char *path);
|
|||
|
||||
bool safeWriteToFile(const std::string &path, const std::string &content);
|
||||
|
||||
bool Rename(const std::string &from, const std::string &to);
|
||||
|
||||
} // namespace fs
|
||||
|
||||
#endif
|
||||
|
|
12
src/main.cpp
12
src/main.cpp
|
@ -164,7 +164,13 @@ int main(int argc, char *argv[])
|
|||
setup_log_params(cmd_args);
|
||||
|
||||
porting::signal_handler_init();
|
||||
|
||||
#ifdef __ANDROID__
|
||||
porting::initAndroid();
|
||||
porting::initializePathsAndroid();
|
||||
#else
|
||||
porting::initializePaths();
|
||||
#endif
|
||||
|
||||
if (!create_userdata_path()) {
|
||||
errorstream << "Cannot create user data directory" << std::endl;
|
||||
|
@ -422,9 +428,6 @@ static bool create_userdata_path()
|
|||
bool success;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
porting::initAndroid();
|
||||
|
||||
porting::setExternalStorageDir(porting::jnienv);
|
||||
if (!fs::PathExists(porting::path_user)) {
|
||||
success = fs::CreateDir(porting::path_user);
|
||||
} else {
|
||||
|
@ -436,9 +439,6 @@ static bool create_userdata_path()
|
|||
success = fs::CreateDir(porting::path_user);
|
||||
#endif
|
||||
|
||||
infostream << "path_share = " << porting::path_share << std::endl;
|
||||
infostream << "path_user = " << porting::path_user << std::endl;
|
||||
|
||||
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);
|
||||
//TimeTaker t("updateLighting");
|
||||
|
||||
propagateSunlight(nmin, nmax);
|
||||
propagateSunlight(nmin, nmax, propagate_shadow);
|
||||
spreadLight(full_nmin, full_nmax);
|
||||
|
||||
//printf("updateLighting: %dms\n", t.stop());
|
||||
}
|
||||
|
||||
|
||||
|
||||
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)
|
||||
void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow)
|
||||
{
|
||||
//TimeTaker t("propagateSunlight");
|
||||
VoxelArea a(nmin, nmax);
|
||||
|
@ -308,7 +291,8 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax)
|
|||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||
if (block_is_underground)
|
||||
continue;
|
||||
} else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN) {
|
||||
} else if ((vm->m_data[i].param1 & 0x0F) != LIGHT_SUN &&
|
||||
propagate_shadow) {
|
||||
continue;
|
||||
}
|
||||
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)
|
||||
{
|
||||
//TimeTaker t("spreadLight");
|
||||
|
|
|
@ -173,12 +173,9 @@ public:
|
|||
|
||||
void setLighting(u8 light, v3s16 nmin, v3s16 nmax);
|
||||
void lightSpread(VoxelArea &a, v3s16 p, u8 light);
|
||||
|
||||
void calcLighting(v3s16 nmin, v3s16 nmax);
|
||||
void calcLighting(v3s16 nmin, v3s16 nmax,
|
||||
v3s16 full_nmin, v3s16 full_nmax);
|
||||
|
||||
void propagateSunlight(v3s16 nmin, v3s16 nmax);
|
||||
void calcLighting(v3s16 nmin, v3s16 nmax, v3s16 full_nmin, v3s16 full_nmax,
|
||||
bool propagate_shadow = true);
|
||||
void propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow);
|
||||
void spreadLight(v3s16 nmin, v3s16 nmax);
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data) {}
|
||||
|
|
|
@ -38,6 +38,9 @@ MapgenSinglenode::MapgenSinglenode(int mapgenid,
|
|||
c_node = ndef->getId("mapgen_singlenode");
|
||||
if (c_node == CONTENT_IGNORE)
|
||||
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
|
||||
|
||||
void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
||||
|
@ -53,11 +57,11 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||
assert(data->vmanip);
|
||||
assert(data->nodedef);
|
||||
assert(data->blockpos_requested.X >= data->blockpos_min.X &&
|
||||
data->blockpos_requested.Y >= data->blockpos_min.Y &&
|
||||
data->blockpos_requested.Z >= data->blockpos_min.Z);
|
||||
data->blockpos_requested.Y >= data->blockpos_min.Y &&
|
||||
data->blockpos_requested.Z >= data->blockpos_min.Z);
|
||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
this->generating = true;
|
||||
this->vm = data->vmanip;
|
||||
|
@ -67,8 +71,8 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||
v3s16 blockpos_max = data->blockpos_max;
|
||||
|
||||
// Area of central chunk
|
||||
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
||||
v3s16 node_max = (blockpos_max+v3s16(1,1,1))*MAP_BLOCKSIZE-v3s16(1,1,1);
|
||||
v3s16 node_min = blockpos_min * MAP_BLOCKSIZE;
|
||||
v3s16 node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
||||
|
||||
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
|
||||
updateLiquid(&data->transforming_liquid, node_min, node_max);
|
||||
|
||||
// Calculate lighting
|
||||
if (flags & MG_LIGHT)
|
||||
calcLighting(node_min, node_max);
|
||||
// Set lighting
|
||||
if ((flags & MG_LIGHT) && set_light == LIGHT_SUN)
|
||||
setLighting(LIGHT_SUN, node_min, node_max);
|
||||
|
||||
this->generating = false;
|
||||
}
|
||||
|
||||
|
||||
int MapgenSinglenode::getGroundLevelAtPoint(v2s16 p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ class MapgenSinglenode : public Mapgen {
|
|||
public:
|
||||
u32 flags;
|
||||
content_t c_node;
|
||||
u8 set_light;
|
||||
|
||||
MapgenSinglenode(int mapgenid, MapgenParams *params, EmergeManager *emerge);
|
||||
~MapgenSinglenode();
|
||||
|
|
|
@ -593,7 +593,9 @@ void MapgenV6::makeChunk(BlockMakeData *data)
|
|||
|
||||
// Calculate lighting
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ void signal_handler_init(void)
|
|||
std::string path_share = "..";
|
||||
std::string path_user = "..";
|
||||
std::string path_locale = path_share + DIR_DELIM + "locale";
|
||||
std::string path_cache = path_user + DIR_DELIM + "cache";
|
||||
|
||||
|
||||
std::string getDataPath(const char *subpath)
|
||||
|
@ -463,6 +464,25 @@ bool setSystemPaths()
|
|||
|
||||
#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()
|
||||
{
|
||||
|
@ -513,10 +533,27 @@ void initializePaths()
|
|||
if (!setSystemPaths())
|
||||
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
|
||||
|
||||
infostream << "Detected share path: " << path_share << std::endl;
|
||||
infostream << "Detected user path: " << path_user << std::endl;
|
||||
infostream << "Detected cache path: " << path_cache << std::endl;
|
||||
|
||||
bool found_localedir = false;
|
||||
#ifdef STATIC_LOCALEDIR
|
||||
|
@ -542,7 +579,6 @@ void initializePaths()
|
|||
if (!found_localedir) {
|
||||
errorstream << "Couldn't find a locale directory!" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -147,12 +147,23 @@ extern std::string path_user;
|
|||
*/
|
||||
extern std::string path_locale;
|
||||
|
||||
/*
|
||||
Path to directory for storing caches.
|
||||
*/
|
||||
extern std::string path_cache;
|
||||
|
||||
/*
|
||||
Get full path of stuff in data directory.
|
||||
Example: "stone.png" -> "../data/stone.png"
|
||||
*/
|
||||
std::string getDataPath(const char *subpath);
|
||||
|
||||
/*
|
||||
Move cache folder from path_user to the
|
||||
system cache location if possible.
|
||||
*/
|
||||
void migrateCachePath();
|
||||
|
||||
/*
|
||||
Initialize path_*.
|
||||
*/
|
||||
|
|
|
@ -177,29 +177,63 @@ void cleanupAndroid()
|
|||
ANativeActivity_finish(app_global->activity);
|
||||
}
|
||||
|
||||
void setExternalStorageDir(JNIEnv* lJNIEnv)
|
||||
static std::string javaStringToUTF8(jstring js)
|
||||
{
|
||||
// Android: Retrieve ablsolute path to external storage device (sdcard)
|
||||
jclass ClassEnv = lJNIEnv->FindClass("android/os/Environment");
|
||||
jmethodID MethodDir =
|
||||
lJNIEnv->GetStaticMethodID(ClassEnv,
|
||||
"getExternalStorageDirectory","()Ljava/io/File;");
|
||||
jobject ObjectFile = lJNIEnv->CallStaticObjectMethod(ClassEnv, MethodDir);
|
||||
jclass ClassFile = lJNIEnv->FindClass("java/io/File");
|
||||
std::string str;
|
||||
// Get string as a UTF-8 c-string
|
||||
const char *c_str = jnienv->GetStringUTFChars(js, NULL);
|
||||
// Save it
|
||||
str = c_str;
|
||||
// And free the c-string
|
||||
jnienv->ReleaseStringUTFChars(js, c_str);
|
||||
return str;
|
||||
}
|
||||
|
||||
jmethodID MethodPath =
|
||||
lJNIEnv->GetMethodID(ClassFile, "getAbsolutePath",
|
||||
"()Ljava/lang/String;");
|
||||
jstring StringPath =
|
||||
(jstring) lJNIEnv->CallObjectMethod(ObjectFile, MethodPath);
|
||||
// Calls static method if obj is NULL
|
||||
static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File,
|
||||
jmethodID mt_getAbsPath, const char *getter)
|
||||
{
|
||||
// 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);
|
||||
std::string userPath(externalPath);
|
||||
lJNIEnv->ReleaseStringUTFChars(StringPath, externalPath);
|
||||
// Call getter
|
||||
jobject ob_file;
|
||||
if (obj)
|
||||
ob_file = jnienv->CallObjectMethod(obj, mt_getter);
|
||||
else
|
||||
ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter);
|
||||
|
||||
path_storage = userPath;
|
||||
path_user = userPath + DIR_DELIM + PROJECT_NAME_C;
|
||||
path_share = userPath + DIR_DELIM + PROJECT_NAME_C;
|
||||
// Call getAbsolutePath
|
||||
jstring js_path = (jstring) jnienv->CallObjectMethod(ob_file,
|
||||
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,
|
||||
|
|
|
@ -43,10 +43,10 @@ void initAndroid();
|
|||
void cleanupAndroid();
|
||||
|
||||
/**
|
||||
* set storage dir on external sdcard#
|
||||
* @param lJNIEnv environment from android
|
||||
* Initializes path_* variables for Android
|
||||
* @param env Android JNI environment
|
||||
*/
|
||||
void setExternalStorageDir(JNIEnv* lJNIEnv);
|
||||
void initializePathsAndroid();
|
||||
|
||||
/**
|
||||
* 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",
|
||||
"Deprecated: new name is \"noise_threshold\".");
|
||||
|
||||
int nthresh;
|
||||
if (!getintfield(L, index, "noise_threshold", nthresh) &&
|
||||
!getintfield(L, index, "noise_threshhold", nthresh))
|
||||
float nthresh;
|
||||
if (!getfloatfield(L, index, "noise_threshold", nthresh) &&
|
||||
!getfloatfield(L, index, "noise_threshhold", nthresh))
|
||||
nthresh = 0;
|
||||
ore->nthresh = nthresh;
|
||||
|
||||
|
|
|
@ -181,6 +181,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
|
|||
v3s16 fpmax = vm->m_area.MaxEdge;
|
||||
v3s16 pmin = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + 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);
|
||||
if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
|
||||
|
@ -191,7 +192,7 @@ int LuaVoxelManip::l_calc_lighting(lua_State *L)
|
|||
mg.ndef = ndef;
|
||||
mg.water_level = emerge->params.water_level;
|
||||
|
||||
mg.calcLighting(pmin, pmax, fpmin, fpmax);
|
||||
mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
set(JTHREAD_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/event.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mutex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/thread.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/semaphore.cpp
|
||||
|
|
|
@ -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
|
||||
#define THREADING_EVENT_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#if __cplusplus >= 201103L
|
||||
#include <condition_variable>
|
||||
#include "threading/mutex.h"
|
||||
#elif defined(_WIN32)
|
||||
#include <windef.h>
|
||||
#else
|
||||
#include "threading/semaphore.h"
|
||||
#include <pthread.h>
|
||||
#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 {
|
||||
public:
|
||||
#ifdef _WIN32
|
||||
Event() { event = CreateEvent(NULL, false, false, NULL); }
|
||||
~Event() { CloseHandle(event); }
|
||||
void wait() { WaitForSingleObject(event, INFINITE); }
|
||||
void signal() { SetEvent(event); }
|
||||
#else
|
||||
void wait() { sem.wait(); }
|
||||
void signal() { sem.post(); }
|
||||
#if __cplusplus < 201103L
|
||||
Event();
|
||||
~Event();
|
||||
#endif
|
||||
void wait();
|
||||
void signal();
|
||||
|
||||
private:
|
||||
#ifdef _WIN32
|
||||
#if __cplusplus >= 201103L
|
||||
std::condition_variable cv;
|
||||
Mutex mutex;
|
||||
bool notified;
|
||||
#elif defined(_WIN32)
|
||||
HANDLE event;
|
||||
#else
|
||||
Semaphore sem;
|
||||
pthread_cond_t cv;
|
||||
pthread_mutex_t mutex;
|
||||
bool notified;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue