Merge pull request #2 from okamstudio/master

pull
This commit is contained in:
Kevin Choi 2015-05-31 01:37:56 -04:00
commit 6813a1f1e1
63 changed files with 3981 additions and 628 deletions

View file

@ -339,7 +339,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) {
//try to load settings in ascending through dirs shape!
//tries to open pack, but only first time
if (first_time && _load_resource_pack(current_dir+"/data.pck")) {
if (first_time && (_load_resource_pack(current_dir+"/data.pck") || _load_resource_pack(current_dir+"/data.pcz") )) {
if (_load_settings("res://engine.cfg")==OK || _load_settings_binary("res://engine.cfb")==OK) {
_load_settings("res://override.cfg");
@ -1460,6 +1460,7 @@ Globals::Globals() {
custom_prop_info["display/orientation"]=PropertyInfo(Variant::STRING,"display/orientation",PROPERTY_HINT_ENUM,"landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
custom_prop_info["render/mipmap_policy"]=PropertyInfo(Variant::INT,"render/mipmap_policy",PROPERTY_HINT_ENUM,"Allow,Allow For Po2,Disallow");
custom_prop_info["render/thread_model"]=PropertyInfo(Variant::INT,"render/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["physics_2d/thread_model"]=PropertyInfo(Variant::INT,"physics_2d/thread_model",PROPERTY_HINT_ENUM,"Single-Unsafe,Single-Safe,Multi-Threaded");
set("display/emulate_touchscreen",false);
using_datapack=false;

View file

@ -1746,6 +1746,10 @@ Error Image::_decompress_bc() {
return OK;
}
bool Image::is_compressed() const {
return format>=FORMAT_BC1;
}
Image Image::decompressed() const {
@ -1998,7 +2002,7 @@ void Image::blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2&
}
Image (*Image::_png_mem_loader_func)(const uint8_t*)=NULL;
Image (*Image::_png_mem_loader_func)(const uint8_t*,int)=NULL;
void (*Image::_image_compress_bc_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc2_func)(Image *)=NULL;
void (*Image::_image_compress_pvrtc4_func)(Image *)=NULL;
@ -2167,7 +2171,7 @@ void Image::fix_alpha_edges() {
}
Image::Image(const uint8_t* p_png) {
Image::Image(const uint8_t* p_png,int p_len) {
width=0;
height=0;
@ -2175,7 +2179,7 @@ Image::Image(const uint8_t* p_png) {
format=FORMAT_GRAYSCALE;
if (_png_mem_loader_func) {
*this = _png_mem_loader_func(p_png);
*this = _png_mem_loader_func(p_png,p_len);
}
}

View file

@ -94,7 +94,7 @@ public:
/* INTERPOLATE GAUSS */
};
static Image (*_png_mem_loader_func)(const uint8_t* p_png);
static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size);
static void (*_image_compress_bc_func)(Image *);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
@ -335,6 +335,7 @@ public:
Image compressed(int p_mode); /* from the Image::CompressMode enum */
Error decompress();
Image decompressed() const;
bool is_compressed() const;
void fix_alpha_edges();
void premultiply_alpha();
@ -349,7 +350,7 @@ public:
Image get_rect(const Rect2& p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *));
Image(const uint8_t* p_mem_png);
Image(const uint8_t* p_mem_png, int p_len=-1);
Image(const char **p_xpm);
~Image();

View file

@ -74,6 +74,14 @@ bool FileAccessMemory::file_exists(const String& p_name) {
}
Error FileAccessMemory::open_custom(const uint8_t* p_data, int p_len) {
data=(uint8_t*)p_data;
length=p_len;
pos=0;
return OK;
}
Error FileAccessMemory::_open(const String& p_path, int p_mode_flags) {
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);

View file

@ -44,6 +44,7 @@ public:
static void register_file(String p_name, Vector<uint8_t> p_data);
static void cleanup();
virtual Error open_custom(const uint8_t* p_data, int p_len); ///< open a file
virtual Error _open(const String& p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open

View file

@ -31,6 +31,7 @@
#include "file_access_zip.h"
#include "core/os/file_access.h"
#include "core/os/copymem.h"
ZipArchive* ZipArchive::instance = NULL;
@ -103,9 +104,17 @@ static int godot_testerror(voidpf opaque, voidpf stream) {
return f->get_error()!=OK?1:0;
};
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
return memalloc(items * size);
};
static void godot_free(voidpf opaque, voidpf address) {
memfree(address);
};
}; // extern "C"
void ZipArchive::close_handle(unzFile p_file) const {
@ -125,6 +134,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
ERR_FAIL_COND_V(!f, NULL);
zlib_filefunc_def io;
zeromem(&io, sizeof(io));
io.opaque = f;
io.zopen_file = godot_open;
@ -136,9 +146,13 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
io.zclose_file = godot_close;
io.zerror_file = godot_testerror;
io.alloc_mem = godot_alloc;
io.free_mem = godot_free;
unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io);
ERR_FAIL_COND_V(!pkg, NULL);
unzGoToFilePos(pkg, &file.file_pos);
int unz_err = unzGoToFilePos(pkg, &file.file_pos);
ERR_FAIL_COND_V(unz_err != UNZ_OK, NULL);
if (unzOpenCurrentFile(pkg) != UNZ_OK) {
unzClose(pkg);
@ -150,7 +164,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
bool ZipArchive::try_open_pack(const String& p_name) {
//printf("opening pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
if (p_name.extension().nocasecmp_to("zip") != 0 && p_name.extension().nocasecmp_to("pcz") != 0)
return false;
@ -198,7 +212,8 @@ bool ZipArchive::try_open_pack(const String& p_name) {
files[fname] = f;
uint8_t md5[16]={0,0,0,0,0,0,0,0 , 0,0,0,0,0,0,0,0};
PackedData::get_singleton()->add_path(p_name, fname, 0, 0, md5, this);
PackedData::get_singleton()->add_path(p_name, fname, 1, 0, md5, this);
//printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str());
if ((i+1)<gi.number_entry) {
unzGoToNextFile(zfile);

View file

@ -1351,7 +1351,7 @@ Error Object::connect(const StringName& p_signal, Object *p_to_object, const Str
if (!s) {
bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_signal);
if (!signal_is_valid) {
ERR_EXPLAIN("Attempt to connect to nonexistent signal: "+p_signal);
ERR_EXPLAIN("Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_method+"'");
ERR_FAIL_COND_V(!signal_is_valid,ERR_INVALID_PARAMETER);
}
signal_map[p_signal]=Signal();

View file

@ -302,8 +302,8 @@ bool Variant::can_convert(Variant::Type p_type_from,Variant::Type p_type_to) {
case COLOR: {
static const Type valid[] = {
//STRING,
//INT,
STRING,
INT,
NIL,
};
@ -1653,6 +1653,10 @@ Variant::operator Color() const {
if (type==COLOR)
return *reinterpret_cast<const Color*>(_data._mem);
else if (type==STRING)
return Color::html( operator String() );
else if (type==INT)
return Color::hex( operator int() );
else
return Color();
}

View file

@ -2,3 +2,10 @@
name="Motion Test"
main_scene="res://motion.scn"
[display]
width=800
height=600
stretch_mode="2d"
stretch_aspect="keep"

View file

@ -31,6 +31,8 @@
#include "print_string.h"
#include "os/os.h"
void ImageLoaderPNG::_read_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length) {
FileAccess *f = (FileAccess*)png_get_io_ptr(png_ptr);
@ -253,6 +255,7 @@ void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const
struct PNGReadStatus {
int offset;
int size;
const unsigned char *image;
};
@ -261,17 +264,26 @@ static void user_read_data(png_structp png_ptr,png_bytep data, png_size_t p_leng
PNGReadStatus *rstatus;
rstatus=(PNGReadStatus*)png_get_io_ptr(png_ptr);
memcpy(data,&rstatus->image[rstatus->offset],p_length);
rstatus->offset+=p_length;
int to_read=p_length;
if (rstatus->size>=0) {
to_read = MIN( p_length, rstatus->size - rstatus->offset);
}
memcpy(data,&rstatus->image[rstatus->offset],to_read);
rstatus->offset+=to_read;
if (to_read<p_length) {
memset(&data[to_read],0,p_length-to_read);
}
}
static Image _load_mem_png(const uint8_t* p_png) {
static Image _load_mem_png(const uint8_t* p_png,int p_size) {
PNGReadStatus prs;
prs.image=p_png;
prs.offset=0;
prs.size=p_size;
Image img;
Error err = ImageLoaderPNG::_load_image(&prs,user_read_data,&img);
@ -283,9 +295,10 @@ static Image _load_mem_png(const uint8_t* p_png) {
static Image _lossless_unpack_png(const DVector<uint8_t>& p_data) {
int len = p_data.size();
DVector<uint8_t>::Read r = p_data.read();
ERR_FAIL_COND_V(r[0]!='P' || r[1]!='N' || r[2]!='G' || r[3]!=' ',Image());
return _load_mem_png(&r[4]);
return _load_mem_png(&r[4],len-4);
}
@ -424,6 +437,7 @@ static DVector<uint8_t> _lossless_pack_png(const Image& p_image) {
ImageLoaderPNG::ImageLoaderPNG() {
Image::_png_mem_loader_func=_load_mem_png;
Image::lossless_unpacker=_lossless_unpack_png;
Image::lossless_packer=_lossless_pack_png;

View file

@ -40,7 +40,10 @@ class ImageLoaderPNG : public ImageFormatLoader {
static void _read_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length);
public:
static Error _load_image(void *rf_up,png_rw_ptr p_func,Image *p_image);
virtual Error load_image(Image *p_image,FileAccess *f);
virtual void get_recognized_extensions(List<String> *p_extensions) const;

View file

@ -1356,6 +1356,8 @@ bool Main::iteration() {
message_queue->flush();
PhysicsServer::get_singleton()->step(frame_slice*time_scale);
Physics2DServer::get_singleton()->end_sync();
Physics2DServer::get_singleton()->step(frame_slice*time_scale);
time_accum-=frame_slice;

View file

@ -163,7 +163,8 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_
//
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
//physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
input = memnew( InputDefault );

View file

@ -37,6 +37,7 @@
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "servers/audio/audio_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/visual/rasterizer.h"

View file

@ -51,6 +51,12 @@ public:
Error post_score(Variant p_score);
Error award_achievement(Variant p_params);
void reset_achievements();
void request_achievements();
void request_achievement_descriptions();
Error show_game_center(Variant p_params);
void game_center_closed();
int get_pending_event_count();
Variant pop_pending_event();

View file

@ -32,6 +32,7 @@
extern "C" {
#import <GameKit/GameKit.h>
#import "app_delegate.h"
};
GameCenter* GameCenter::instance = NULL;
@ -42,6 +43,10 @@ void GameCenter::_bind_methods() {
ObjectTypeDB::bind_method(_MD("post_score"),&GameCenter::post_score);
ObjectTypeDB::bind_method(_MD("award_achievement"),&GameCenter::award_achievement);
ObjectTypeDB::bind_method(_MD("reset_achievements"),&GameCenter::reset_achievements);
ObjectTypeDB::bind_method(_MD("request_achievements"),&GameCenter::request_achievements);
ObjectTypeDB::bind_method(_MD("request_achievement_descriptions"),&GameCenter::request_achievement_descriptions);
ObjectTypeDB::bind_method(_MD("show_game_center"),&GameCenter::show_game_center);
ObjectTypeDB::bind_method(_MD("get_pending_event_count"),&GameCenter::get_pending_event_count);
ObjectTypeDB::bind_method(_MD("pop_pending_event"),&GameCenter::pop_pending_event);
@ -50,23 +55,41 @@ void GameCenter::_bind_methods() {
Error GameCenter::connect() {
//if this class isn't available, game center isn't implemented
if ((NSClassFromString(@"GKLocalPlayer")) == nil) {
GameCenter::get_singleton()->connected = false;
return ERR_UNAVAILABLE;
}
GKLocalPlayer* player = [GKLocalPlayer localPlayer];
[player authenticateWithCompletionHandler:^(NSError* error) {
ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE);
Dictionary ret;
ret["type"] = "authentication";
if (player.isAuthenticated) {
ret["result"] = "ok";
GameCenter::get_singleton()->connected = true;
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
GameCenter::get_singleton()->connected = false;
};
ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
ERR_FAIL_COND_V(!root_controller, FAILED);
//this handler is called serveral times. first when the view needs to be shown, then again after the view is cancelled or the user logs in. or if the user's already logged in, it's called just once to confirm they're authenticated. This is why no result needs to be specified in the presentViewController phase. in this case, more calls to this function will follow.
player.authenticateHandler = (^(UIViewController *controller, NSError *error) {
if (controller) {
[root_controller presentViewController:controller animated:YES completion:nil];
}
else {
Dictionary ret;
ret["type"] = "authentication";
if (player.isAuthenticated) {
ret["result"] = "ok";
GameCenter::get_singleton()->connected = true;
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
GameCenter::get_singleton()->connected = false;
};
pending_events.push_back(ret);
};
});
pending_events.push_back(ret);
}];
return OK;
};
@ -85,7 +108,9 @@ Error GameCenter::post_score(Variant p_score) {
GKScore* reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease];
reporter.value = score;
[reporter reportScoreWithCompletionHandler:^(NSError* error) {
ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE);
[GKScore reportScores:@[reporter] withCompletionHandler:^(NSError* error) {
Dictionary ret;
ret["type"] = "post_score";
@ -114,8 +139,15 @@ Error GameCenter::award_achievement(Variant p_params) {
GKAchievement* achievement = [[[GKAchievement alloc] initWithIdentifier: name_str] autorelease];
ERR_FAIL_COND_V(!achievement, FAILED);
ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE);
achievement.percentComplete = progress;
[achievement reportAchievementWithCompletionHandler:^(NSError* error) {
achievement.showsCompletionBanner = NO;
if (params.has("show_completion_banner")) {
achievement.showsCompletionBanner = params["show_completion_banner"] ? YES : NO;
}
[GKAchievement reportAchievements:@[achievement] withCompletionHandler:^(NSError *error) {
Dictionary ret;
ret["type"] = "award_achievement";
@ -132,6 +164,168 @@ Error GameCenter::award_achievement(Variant p_params) {
return OK;
};
void GameCenter::request_achievement_descriptions() {
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
Dictionary ret;
ret["type"] = "achievement_descriptions";
if (error == nil) {
ret["result"] = "ok";
StringArray names;
StringArray titles;
StringArray unachieved_descriptions;
StringArray achieved_descriptions;
IntArray maximum_points;
Array hidden;
Array replayable;
for (int i=0; i<[descriptions count]; i++) {
GKAchievementDescription* description = [descriptions objectAtIndex:i];
const char* str = [description.identifier UTF8String];
names.push_back(String::utf8(str != NULL ? str : ""));
str = [description.title UTF8String];
titles.push_back(String::utf8(str != NULL ? str : ""));
str = [description.unachievedDescription UTF8String];
unachieved_descriptions.push_back(String::utf8(str != NULL ? str : ""));
str = [description.achievedDescription UTF8String];
achieved_descriptions.push_back(String::utf8(str != NULL ? str : ""));
maximum_points.push_back(description.maximumPoints);
hidden.push_back(description.hidden == YES);
replayable.push_back(description.replayable == YES);
}
ret["names"] = names;
ret["titles"] = titles;
ret["unachieved_descriptions"] = unachieved_descriptions;
ret["achieved_descriptions"] = achieved_descriptions;
ret["maximum_points"] = maximum_points;
ret["hidden"] = hidden;
ret["replayable"] = replayable;
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
};
pending_events.push_back(ret);
}];
};
void GameCenter::request_achievements() {
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
Dictionary ret;
ret["type"] = "achievements";
if (error == nil) {
ret["result"] = "ok";
StringArray names;
RealArray percentages;
for (int i=0; i<[achievements count]; i++) {
GKAchievement* achievement = [achievements objectAtIndex:i];
const char* str = [achievement.identifier UTF8String];
names.push_back(String::utf8(str != NULL ? str : ""));
percentages.push_back(achievement.percentComplete);
}
ret["names"] = names;
ret["progress"] = percentages;
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
};
pending_events.push_back(ret);
}];
};
void GameCenter::reset_achievements() {
[GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error)
{
Dictionary ret;
ret["type"] = "reset_achievements";
if (error == nil) {
ret["result"] = "ok";
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
};
pending_events.push_back(ret);
}];
};
Error GameCenter::show_game_center(Variant p_params) {
ERR_FAIL_COND_V(!NSProtocolFromString(@"GKGameCenterControllerDelegate"), FAILED);
Dictionary params = p_params;
GKGameCenterViewControllerState view_state = GKGameCenterViewControllerStateDefault;
if (params.has("view")) {
String view_name = params["view"];
if (view_name == "default") {
view_state = GKGameCenterViewControllerStateDefault;
}
else if (view_name == "leaderboards") {
view_state = GKGameCenterViewControllerStateLeaderboards;
}
else if (view_name == "achievements") {
view_state = GKGameCenterViewControllerStateAchievements;
}
else if (view_name == "challenges") {
view_state = GKGameCenterViewControllerStateChallenges;
}
else {
return ERR_INVALID_PARAMETER;
}
}
GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init];
ERR_FAIL_COND_V(!controller, FAILED);
ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
ERR_FAIL_COND_V(!root_controller, FAILED);
controller.gameCenterDelegate = root_controller;
controller.viewState = view_state;
if (view_state == GKGameCenterViewControllerStateLeaderboards) {
controller.leaderboardIdentifier = nil;
if (params.has("leaderboard_name")) {
String name = params["leaderboard_name"];
NSString* name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
controller.leaderboardIdentifier = name_str;
}
}
[root_controller presentViewController: controller animated: YES completion:nil];
return OK;
};
void GameCenter::game_center_closed() {
Dictionary ret;
ret["type"] = "show_game_center";
ret["result"] = "ok";
pending_events.push_back(ret);
}
int GameCenter::get_pending_event_count() {
return pending_events.size();

View file

@ -210,7 +210,7 @@ Error InAppStore::request_product_info(Variant p_params) {
receipt_to_send = [receipt description];
}
Dictionary receipt_ret;
receipt_ret["receipt"] = String::utf8([receipt_to_send UTF8String]);
receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : "");
receipt_ret["sdk"] = sdk_version;
ret["receipt"] = receipt_ret;

View file

@ -136,7 +136,8 @@ void OSIPhone::initialize(const VideoMode& p_desired,int p_video_driver,int p_au
//
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
//physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
input = memnew( InputDefault );

View file

@ -38,6 +38,7 @@
#include "servers/visual/rasterizer.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/audio/audio_server_sw.h"
#include "servers/audio/sample_manager_sw.h"
#include "servers/spatial_sound/spatial_sound_server_sw.h"

View file

@ -27,8 +27,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
@interface ViewController : UIViewController {
@interface ViewController : UIViewController <GKGameCenterControllerDelegate> {
};

View file

@ -124,10 +124,15 @@ int add_cmdline(int p_argc, char** p_args) {
}
};
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController {
//[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone
GameCenter::get_singleton()->game_center_closed();
[gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
@end

View file

@ -44,6 +44,7 @@
#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/alsa/audio_driver_alsa.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "platform/osx/audio_driver_osx.h"
#include <ApplicationServices/ApplicationServices.h>

View file

@ -1015,7 +1015,8 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
//
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
//physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
input = memnew( InputDefault );

View file

@ -1177,7 +1177,7 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
if (!is_no_window_mode_enabled()) {
@ -1375,6 +1375,9 @@ void OS_Windows::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
joystick_change_queue.clear();
monitor_info.clear();
}
void OS_Windows::finalize_core() {
@ -2052,7 +2055,7 @@ String OS_Windows::get_executable_path() const {
wchar_t bufname[4096];
GetModuleFileNameW(NULL,bufname,4096);
String s= bufname;
print_line("EXEC PATHP¨®: "+s);
print_line("EXEC PATHP??: "+s);
return s;
}

View file

@ -45,6 +45,7 @@
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "drivers/unix/ip_unix.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include <windows.h>

View file

@ -35,6 +35,7 @@
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "X11/Xutil.h"
#include "X11/Xatom.h"
@ -426,7 +427,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
//
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
//physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
input = memnew( InputDefault );

View file

@ -45,6 +45,7 @@
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/pulseaudio/audio_driver_pulseaudio.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include <X11/keysym.h>
#include <X11/Xlib.h>

View file

@ -150,10 +150,10 @@ RES ResourceFormatLoaderWAV::load(const String &p_path,const String& p_original_
frames/=format_channels;
frames/=(format_bits>>3);
print_line("chunksize: "+itos(chunksize));
/*print_line("chunksize: "+itos(chunksize));
print_line("channels: "+itos(format_channels));
print_line("bits: "+itos(format_bits));
*/
sample->create(
(format_bits==8) ? Sample::FORMAT_PCM8 : Sample::FORMAT_PCM16,
(format_channels==2)?true:false,

View file

@ -692,7 +692,6 @@ void make_default_theme() {
// FileDialog
t->set_icon("folder","FileDialog",make_icon(icon_folder_png));
t->set_color("files_disabled","FileDialog",Color(0,0,0,0.7));

View file

@ -135,7 +135,7 @@ void SampleManagerMallocSW::sample_set_data(RID p_sample, const DVector<uint8_t>
ERR_EXPLAIN("Sample buffer size does not match sample size.");
print_line("len bytes: "+itos(s->length_bytes)+" bufsize: "+itos(buff_size));
//print_line("len bytes: "+itos(s->length_bytes)+" bufsize: "+itos(buff_size));
ERR_FAIL_COND(s->length_bytes!=buff_size);
DVector<uint8_t>::Read buffer_r=p_buffer.read();
const uint8_t *src = buffer_r.ptr();

View file

@ -30,7 +30,7 @@
#include "broad_phase_2d_basic.h"
#include "broad_phase_2d_hash_grid.h"
#include "collision_solver_2d_sw.h"
#include "globals.h"
RID Physics2DServerSW::shape_create(ShapeType p_shape) {
Shape2DSW *shape=NULL;
@ -261,7 +261,7 @@ Physics2DDirectSpaceState* Physics2DServerSW::space_get_direct_state(RID p_space
Space2DSW *space = space_owner.get(p_space);
ERR_FAIL_COND_V(!space,NULL);
if (/*doing_sync ||*/ space->is_locked()) {
if ((using_threads && !doing_sync) || space->is_locked()) {
ERR_EXPLAIN("Space state is inaccesible right now, wait for iteration or fixed process notification.");
ERR_FAIL_V(NULL);
@ -733,7 +733,7 @@ void Physics2DServerSW::body_set_layer_mask(RID p_body, uint32_t p_flags) {
};
uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body, uint32_t p_flags) const {
uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body,0);
@ -750,7 +750,7 @@ void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_flags) {
};
uint32_t Physics2DServerSW::body_get_collision_mask(RID p_body, uint32_t p_flags) const {
uint32_t Physics2DServerSW::body_get_collision_mask(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body,0);
@ -1196,7 +1196,7 @@ void Physics2DServerSW::set_active(bool p_active) {
void Physics2DServerSW::init() {
doing_sync=true;
doing_sync=false;
last_step=0.001;
iterations=8;// 8?
stepper = memnew( Step2DSW );
@ -1228,6 +1228,7 @@ void Physics2DServerSW::step(float p_step) {
void Physics2DServerSW::sync() {
doing_sync=true;
};
void Physics2DServerSW::flush_queries() {
@ -1235,7 +1236,7 @@ void Physics2DServerSW::flush_queries() {
if (!active)
return;
doing_sync=true;
for( Set<const Space2DSW*>::Element *E=active_spaces.front();E;E=E->next()) {
Space2DSW *space=(Space2DSW *)E->get();
@ -1244,6 +1245,10 @@ void Physics2DServerSW::flush_queries() {
};
void Physics2DServerSW::end_sync() {
doing_sync=false;
}
void Physics2DServerSW::finish() {
@ -1283,6 +1288,7 @@ Physics2DServerSW::Physics2DServerSW() {
island_count=0;
active_objects=0;
collision_pairs=0;
using_threads=int(Globals::get_singleton()->get("physics_2d/thread_model"))==2;
};

View file

@ -51,6 +51,8 @@ friend class Physics2DDirectSpaceStateSW;
int active_objects;
int collision_pairs;
bool using_threads;
Step2DSW *stepper;
Set<const Space2DSW*> active_spaces;
@ -179,10 +181,10 @@ public:
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const;
virtual uint32_t body_get_layer_mask(RID p_body) const;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const;
virtual uint32_t body_get_collision_mask(RID p_) const;
virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value);
virtual float body_get_param(RID p_body, BodyParameter p_param) const;
@ -248,8 +250,9 @@ public:
virtual void set_active(bool p_active);
virtual void init();
virtual void step(float p_step);
virtual void sync();
virtual void sync();
virtual void flush_queries();
virtual void end_sync();
virtual void finish();
int get_process_info(ProcessInfo p_info);

View file

@ -0,0 +1,169 @@
#include "physics_2d_server_wrap_mt.h"
#include "os/os.h"
void Physics2DServerWrapMT::thread_exit() {
exit=true;
}
void Physics2DServerWrapMT::thread_step(float p_delta) {
physics_2d_server->step(p_delta);
step_sem->post();
}
void Physics2DServerWrapMT::_thread_callback(void *_instance) {
Physics2DServerWrapMT *vsmt = reinterpret_cast<Physics2DServerWrapMT*>(_instance);
vsmt->thread_loop();
}
void Physics2DServerWrapMT::thread_loop() {
server_thread=Thread::get_caller_ID();
OS::get_singleton()->make_rendering_thread();
physics_2d_server->init();
exit=false;
step_thread_up=true;
while(!exit) {
// flush commands one by one, until exit is requested
command_queue.wait_and_flush_one();
}
command_queue.flush_all(); // flush all
physics_2d_server->finish();
}
/* EVENT QUEUING */
void Physics2DServerWrapMT::step(float p_step) {
if (create_thread) {
command_queue.push( this, &Physics2DServerWrapMT::thread_step,p_step);
} else {
command_queue.flush_all(); //flush all pending from other threads
physics_2d_server->step(p_step);
}
}
void Physics2DServerWrapMT::sync() {
if (step_sem) {
if (first_frame)
first_frame=false;
else
step_sem->wait(); //must not wait if a step was not issued
}
physics_2d_server->sync();;
}
void Physics2DServerWrapMT::flush_queries(){
physics_2d_server->flush_queries();
}
void Physics2DServerWrapMT::end_sync() {
physics_2d_server->end_sync();;
}
void Physics2DServerWrapMT::init() {
if (create_thread) {
step_sem = Semaphore::create();
print_line("CREATING PHYSICS 2D THREAD");
//OS::get_singleton()->release_rendering_thread();
if (create_thread) {
thread = Thread::create( _thread_callback, this );
print_line("STARTING PHYISICS 2D THREAD");
}
while(!step_thread_up) {
OS::get_singleton()->delay_usec(1000);
}
print_line("DONE PHYSICS 2D THREAD");
} else {
physics_2d_server->init();
}
}
void Physics2DServerWrapMT::finish() {
if (thread) {
command_queue.push( this, &Physics2DServerWrapMT::thread_exit);
Thread::wait_to_finish( thread );
memdelete(thread);
/*
shape_free_cached_ids();
area_free_cached_ids();
body_free_cached_ids();
pin_joint_free_cached_ids();
groove_joint_free_cached_ids();
damped_string_free_cached_ids();
*/
thread=NULL;
} else {
physics_2d_server->finish();
}
if (step_sem)
memdelete(step_sem);
}
Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer* p_contained,bool p_create_thread) : command_queue(p_create_thread) {
physics_2d_server=p_contained;
create_thread=p_create_thread;
thread=NULL;
step_sem=NULL;
step_pending=0;
step_thread_up=false;
alloc_mutex=Mutex::create();
shape_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
area_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
body_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
pin_joint_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
groove_joint_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
damped_spring_joint_pool_max_size=GLOBAL_DEF("core/thread_rid_pool_prealloc",20);
if (!p_create_thread) {
server_thread=Thread::get_caller_ID();
} else {
server_thread=0;
}
main_thread = Thread::get_caller_ID();
first_frame=true;
}
Physics2DServerWrapMT::~Physics2DServerWrapMT() {
memdelete(physics_2d_server);
memdelete(alloc_mutex);
//finish();
}

View file

@ -0,0 +1,297 @@
#ifndef PHYSICS2DSERVERWRAPMT_H
#define PHYSICS2DSERVERWRAPMT_H
#include "servers/physics_2d_server.h"
#include "command_queue_mt.h"
#include "os/thread.h"
#include "globals.h"
#ifdef DEBUG_SYNC
#define SYNC_DEBUG print_line("sync on: "+String(__FUNCTION__));
#else
#define SYNC_DEBUG
#endif
class Physics2DServerWrapMT : public Physics2DServer {
mutable Physics2DServer *physics_2d_server;
mutable CommandQueueMT command_queue;
static void _thread_callback(void *_instance);
void thread_loop();
Thread::ID server_thread;
Thread::ID main_thread;
volatile bool exit;
Thread *thread;
volatile bool step_thread_up;
bool create_thread;
Semaphore *step_sem;
int step_pending;
void thread_step(float p_delta);
void thread_flush();
void thread_exit();
Mutex*alloc_mutex;
bool first_frame;
int shape_pool_max_size;
List<RID> shape_id_pool;
int area_pool_max_size;
List<RID> area_id_pool;
int body_pool_max_size;
List<RID> body_id_pool;
int pin_joint_pool_max_size;
List<RID> pin_joint_id_pool;
int groove_joint_pool_max_size;
List<RID> groove_joint_id_pool;
int damped_spring_joint_pool_max_size;
List<RID> damped_spring_joint_id_pool;
public:
#define ServerName Physics2DServer
#define ServerNameWrapMT Physics2DServerWrapMT
#define server_name physics_2d_server
#include "servers/server_wrap_mt_common.h"
//FUNC1RID(shape,ShapeType); todo fix
FUNC1R(RID,shape_create,ShapeType);
FUNC2(shape_set_data,RID,const Variant& );
FUNC2(shape_set_custom_solver_bias,RID,real_t );
FUNC1RC(ShapeType,shape_get_type,RID );
FUNC1RC(Variant,shape_get_data,RID);
FUNC1RC(real_t,shape_get_custom_solver_bias,RID);
//these work well, but should be used from the main thread only
bool shape_collide(RID p_shape_A, const Matrix32& p_xform_A,const Vector2& p_motion_A,RID p_shape_B, const Matrix32& p_xform_B, const Vector2& p_motion_B,Vector2 *r_results,int p_result_max,int &r_result_count) {
ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),false);
return physics_2d_server->shape_collide(p_shape_A,p_xform_A,p_motion_A,p_shape_B,p_xform_B,p_motion_B,r_results,p_result_max,r_result_count);
}
/* SPACE API */
FUNC0R(RID,space_create);
FUNC2(space_set_active,RID,bool);
FUNC1RC(bool,space_is_active,RID);
FUNC3(space_set_param,RID,SpaceParameter,real_t);
FUNC2RC(real_t,space_get_param,RID,SpaceParameter);
// this function only works on fixed process, errors and returns null otherwise
Physics2DDirectSpaceState* space_get_direct_state(RID p_space) {
ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),NULL);
return physics_2d_server->space_get_direct_state(p_space);
}
/* AREA API */
//FUNC0RID(area);
FUNC0R(RID,area_create);
FUNC2(area_set_space,RID,RID);
FUNC1RC(RID,area_get_space,RID);
FUNC2(area_set_space_override_mode,RID,AreaSpaceOverrideMode);
FUNC1RC(AreaSpaceOverrideMode,area_get_space_override_mode,RID);
FUNC3(area_add_shape,RID,RID,const Matrix32&);
FUNC3(area_set_shape,RID,int,RID);
FUNC3(area_set_shape_transform,RID,int,const Matrix32&);
FUNC1RC(int,area_get_shape_count,RID);
FUNC2RC(RID,area_get_shape,RID,int);
FUNC2RC(Matrix32,area_get_shape_transform,RID,int);
FUNC2(area_remove_shape,RID,int);
FUNC1(area_clear_shapes,RID);
FUNC2(area_attach_object_instance_ID,RID,ObjectID);
FUNC1RC(ObjectID,area_get_object_instance_ID,RID);
FUNC3(area_set_param,RID,AreaParameter,const Variant&);
FUNC2(area_set_transform,RID,const Matrix32&);
FUNC2RC(Variant,area_get_param,RID,AreaParameter);
FUNC1RC(Matrix32,area_get_transform,RID);
FUNC2(area_set_collision_mask,RID,uint32_t);
FUNC2(area_set_layer_mask,RID,uint32_t);
FUNC2(area_set_monitorable,RID,bool);
FUNC2(area_set_pickable,RID,bool);
FUNC3(area_set_monitor_callback,RID,Object*,const StringName&);
FUNC3(area_set_area_monitor_callback,RID,Object*,const StringName&);
/* BODY API */
//FUNC2RID(body,BodyMode,bool);
FUNC2R(RID,body_create,BodyMode,bool)
FUNC2(body_set_space,RID,RID);
FUNC1RC(RID,body_get_space,RID);
FUNC2(body_set_mode,RID,BodyMode);
FUNC1RC(BodyMode,body_get_mode,RID);
FUNC3(body_add_shape,RID,RID,const Matrix32&);
FUNC3(body_set_shape,RID,int,RID);
FUNC3(body_set_shape_transform,RID,int,const Matrix32&);
FUNC3(body_set_shape_metadata,RID,int,const Variant&);
FUNC1RC(int,body_get_shape_count,RID);
FUNC2RC(Matrix32,body_get_shape_transform,RID,int);
FUNC2RC(Variant,body_get_shape_metadata,RID,int);
FUNC2RC(RID,body_get_shape,RID,int);
FUNC3(body_set_shape_as_trigger,RID,int,bool);
FUNC2RC(bool,body_is_shape_set_as_trigger,RID,int);
FUNC2(body_remove_shape,RID,int);
FUNC1(body_clear_shapes,RID);
FUNC2(body_attach_object_instance_ID,RID,uint32_t);
FUNC1RC(uint32_t,body_get_object_instance_ID,RID);
FUNC2(body_set_continuous_collision_detection_mode,RID,CCDMode);
FUNC1RC(CCDMode,body_get_continuous_collision_detection_mode,RID);
FUNC2(body_set_layer_mask,RID,uint32_t);
FUNC1RC(uint32_t,body_get_layer_mask,RID);
FUNC2(body_set_collision_mask,RID,uint32_t);
FUNC1RC(uint32_t,body_get_collision_mask,RID);
FUNC3(body_set_param,RID,BodyParameter,float);
FUNC2RC(float,body_get_param,RID,BodyParameter);
FUNC3(body_set_state,RID,BodyState,const Variant&);
FUNC2RC(Variant,body_get_state,RID,BodyState);
FUNC2(body_set_applied_force,RID,const Vector2&);
FUNC1RC(Vector2,body_get_applied_force,RID);
FUNC2(body_set_applied_torque,RID,float);
FUNC1RC(float,body_get_applied_torque,RID);
FUNC3(body_apply_impulse,RID,const Vector2&,const Vector2&);
FUNC2(body_set_axis_velocity,RID,const Vector2&);
FUNC2(body_add_collision_exception,RID,RID);
FUNC2(body_remove_collision_exception,RID,RID);
FUNC2S(body_get_collision_exceptions,RID,List<RID>*);
FUNC2(body_set_max_contacts_reported,RID,int);
FUNC1RC(int,body_get_max_contacts_reported,RID);
FUNC2(body_set_one_way_collision_direction,RID,const Vector2&);
FUNC1RC(Vector2,body_get_one_way_collision_direction,RID);
FUNC2(body_set_one_way_collision_max_depth,RID,float);
FUNC1RC(float,body_get_one_way_collision_max_depth,RID);
FUNC2(body_set_contacts_reported_depth_treshold,RID,float);
FUNC1RC(float,body_get_contacts_reported_depth_treshold,RID);
FUNC2(body_set_omit_force_integration,RID,bool);
FUNC1RC(bool,body_is_omitting_force_integration,RID);
FUNC4(body_set_force_integration_callback,RID ,Object *,const StringName& ,const Variant& );
bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count) {
return physics_2d_server->body_collide_shape(p_body,p_body_shape,p_shape,p_shape_xform,p_motion,r_results,p_result_max,r_result_count);
}
FUNC2(body_set_pickable,RID,bool);
bool body_test_motion(RID p_body,const Vector2& p_motion,float p_margin=0.001,MotionResult *r_result=NULL) {
ERR_FAIL_COND_V(main_thread!=Thread::get_caller_ID(),false);
return physics_2d_server->body_test_motion(p_body,p_motion,p_margin,r_result);
}
/* JOINT API */
FUNC3(joint_set_param,RID,JointParam,real_t);
FUNC2RC(real_t,joint_get_param,RID,JointParam);
///FUNC3RID(pin_joint,const Vector2&,RID,RID);
///FUNC5RID(groove_joint,const Vector2&,const Vector2&,const Vector2&,RID,RID);
///FUNC4RID(damped_spring_joint,const Vector2&,const Vector2&,RID,RID);
FUNC3R(RID,pin_joint_create,const Vector2&,RID,RID);
FUNC5R(RID,groove_joint_create,const Vector2&,const Vector2&,const Vector2&,RID,RID);
FUNC4R(RID,damped_spring_joint_create,const Vector2&,const Vector2&,RID,RID);
FUNC3(damped_string_joint_set_param,RID,DampedStringParam,real_t);
FUNC2RC(real_t,damped_string_joint_get_param,RID,DampedStringParam);
FUNC1RC(JointType,joint_get_type,RID);
/* MISC */
FUNC1(free,RID);
FUNC1(set_active,bool);
virtual void init();
virtual void step(float p_step);
virtual void sync();
virtual void end_sync();
virtual void flush_queries();
virtual void finish();
int get_process_info(ProcessInfo p_info) {
return physics_2d_server->get_process_info(p_info);
}
Physics2DServerWrapMT(Physics2DServer* p_contained,bool p_create_thread);
~Physics2DServerWrapMT();
template<class T>
static Physics2DServer* init_server() {
int tm = GLOBAL_DEF("physics_2d/thread_model",1);
if (tm==0) //single unsafe
return memnew( T );
else if (tm==1) //single saef
return memnew( Physics2DServerWrapMT( memnew( T ), false ));
else //single unsafe
return memnew( Physics2DServerWrapMT( memnew( T ), true ));
}
#undef ServerNameWrapMT
#undef ServerName
#undef server_name
};
#ifdef DEBUG_SYNC
#undef DEBUG_SYNC
#endif
#undef SYNC_DEBUG
#endif // PHYSICS2DSERVERWRAPMT_H

View file

@ -713,7 +713,7 @@ void Physics2DServer::_bind_methods() {
Physics2DServer::Physics2DServer() {
ERR_FAIL_COND( singleton!=NULL );
//ERR_FAIL_COND( singleton!=NULL );
singleton=this;
}

View file

@ -405,10 +405,10 @@ public:
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const=0;
virtual void body_set_layer_mask(RID p_body, uint32_t p_mask)=0;
virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const=0;
virtual uint32_t body_get_layer_mask(RID p_body) const=0;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask)=0;
virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const=0;
virtual uint32_t body_get_collision_mask(RID p_body) const=0;
// common body variables
enum BodyParameter {
@ -539,6 +539,7 @@ public:
virtual void step(float p_step)=0;
virtual void sync()=0;
virtual void flush_queries()=0;
virtual void end_sync()=0;
virtual void finish()=0;
enum ProcessInfo {

View file

@ -0,0 +1,700 @@
#define FUNC0R(m_r,m_type)\
virtual m_r m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type();\
}\
}
#define FUNCRID(m_type)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create() { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create();\
}\
}
#define FUNC1RID(m_type,m_arg1)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,p1,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create(p1);\
}\
}
#define FUNC2RID(m_type,m_arg1,m_arg2)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create(m_arg1 p1,m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,p1,p2,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create(p1,p2);\
}\
}
#define FUNC3RID(m_type,m_arg1,m_arg2,m_arg3)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create(m_arg1 p1,m_arg2 p2,m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,p1,p2,p3,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create(p1,p2,p3);\
}\
}
#define FUNC4RID(m_type,m_arg1,m_arg2,m_arg3,m_arg4)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create(m_arg1 p1,m_arg2 p2,m_arg3 p3,m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,p1,p2,p3,p4,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create(p1,p2,p3,p4);\
}\
}
#define FUNC5RID(m_type,m_arg1,m_arg2,m_arg3,m_arg4,m_arg5)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( server_name->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create(m_arg1 p1,m_arg2 p2,m_arg3 p3,m_arg4 p4,m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &ServerNameWrapMT::m_type##allocn,p1,p2,p3,p4,p5,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return server_name->m_type##_create(p1,p2,p3,p4,p5);\
}\
}
#define FUNC0RC(m_r,m_type)\
virtual m_r m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type();\
}\
}
#define FUNC0(m_type)\
virtual void m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type);\
} else {\
server_name->m_type();\
}\
}
#define FUNC0C(m_type)\
virtual void m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type);\
} else {\
server_name->m_type();\
}\
}
#define FUNC0S(m_type)\
virtual void m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type);\
} else {\
server_name->m_type();\
}\
}
#define FUNC0SC(m_type)\
virtual void m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type);\
} else {\
server_name->m_type();\
}\
}
///////////////////////////////////////////////
#define FUNC1R(m_r,m_type,m_arg1)\
virtual m_r m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1);\
}\
}
#define FUNC1RC(m_r,m_type,m_arg1)\
virtual m_r m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1);\
}\
}
#define FUNC1S(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1);\
} else {\
server_name->m_type(p1);\
}\
}
#define FUNC1SC(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1);\
} else {\
server_name->m_type(p1);\
}\
}
#define FUNC1(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1);\
} else {\
server_name->m_type(p1);\
}\
}
#define FUNC1C(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1);\
} else {\
server_name->m_type(p1);\
}\
}
#define FUNC2R(m_r,m_type,m_arg1, m_arg2)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2);\
}\
}
#define FUNC2RC(m_r,m_type,m_arg1, m_arg2)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2);\
}\
}
#define FUNC2S(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2);\
} else {\
server_name->m_type(p1, p2);\
}\
}
#define FUNC2SC(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2);\
} else {\
server_name->m_type(p1, p2);\
}\
}
#define FUNC2(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2);\
} else {\
server_name->m_type(p1, p2);\
}\
}
#define FUNC2C(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2);\
} else {\
server_name->m_type(p1, p2);\
}\
}
#define FUNC3R(m_r,m_type,m_arg1, m_arg2, m_arg3)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC3RC(m_r,m_type,m_arg1, m_arg2, m_arg3)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3,&ret);\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC3S(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3);\
} else {\
server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC3SC(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3);\
} else {\
server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC3(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3);\
} else {\
server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC3C(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3);\
} else {\
server_name->m_type(p1, p2, p3);\
}\
}
#define FUNC4R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4S(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4);\
} else {\
server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4);\
} else {\
server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4);\
} else {\
server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4C(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4);\
} else {\
server_name->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC5R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC6R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6,&ret);\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC7R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
server_name->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}

View file

@ -187,8 +187,8 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer* p_contained,bool p_create_t
draw_pending=0;
draw_thread_up=false;
alloc_mutex=Mutex::create();
texture_pool_max_size=GLOBAL_DEF("render/thread_textures_prealloc",20);
mesh_pool_max_size=GLOBAL_DEF("render/thread_meshes_prealloc",20);
texture_pool_max_size=GLOBAL_DEF("render/thread_textures_prealloc",5);
mesh_pool_max_size=GLOBAL_DEF("core/rid_pool_prealloc",20);
if (!p_create_thread) {
server_thread=Thread::get_caller_ID();
} else {

View file

@ -79,554 +79,10 @@ class VisualServerWrapMT : public VisualServer {
public:
#define FUNC0R(m_r,m_type)\
virtual m_r m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type();\
}\
}
#define FUNCRID(m_type)\
int m_type##allocn() {\
for(int i=0;i<m_type##_pool_max_size;i++) {\
m_type##_id_pool.push_back( visual_server->m_type##_create() );\
}\
return 0;\
}\
void m_type##_free_cached_ids() {\
while (m_type##_id_pool.size()) {\
free(m_type##_id_pool.front()->get());\
m_type##_id_pool.pop_front();\
}\
}\
virtual RID m_type##_create() { \
if (Thread::get_caller_ID()!=server_thread) {\
RID rid;\
alloc_mutex->lock();\
if (m_type##_id_pool.size()==0) {\
int ret;\
command_queue.push_and_ret( this, &VisualServerWrapMT::m_type##allocn,&ret);\
}\
rid=m_type##_id_pool.front()->get();\
m_type##_id_pool.pop_front();\
alloc_mutex->unlock();\
return rid;\
} else {\
return visual_server->m_type##_create();\
}\
}
#define FUNC0RC(m_r,m_type)\
virtual m_r m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type();\
}\
}
#define FUNC0(m_type)\
virtual void m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type);\
} else {\
visual_server->m_type();\
}\
}
#define FUNC0C(m_type)\
virtual void m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type);\
} else {\
visual_server->m_type();\
}\
}
#define FUNC0S(m_type)\
virtual void m_type() { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type);\
} else {\
visual_server->m_type();\
}\
}
#define FUNC0SC(m_type)\
virtual void m_type() const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type);\
} else {\
visual_server->m_type();\
}\
}
///////////////////////////////////////////////
#define FUNC1R(m_r,m_type,m_arg1)\
virtual m_r m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1);\
}\
}
#define FUNC1RC(m_r,m_type,m_arg1)\
virtual m_r m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1);\
}\
}
#define FUNC1S(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1);\
} else {\
visual_server->m_type(p1);\
}\
}
#define FUNC1SC(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1);\
} else {\
visual_server->m_type(p1);\
}\
}
#define FUNC1(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1);\
} else {\
visual_server->m_type(p1);\
}\
}
#define FUNC1C(m_type,m_arg1)\
virtual void m_type(m_arg1 p1) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1);\
} else {\
visual_server->m_type(p1);\
}\
}
#define FUNC2R(m_r,m_type,m_arg1, m_arg2)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2);\
}\
}
#define FUNC2RC(m_r,m_type,m_arg1, m_arg2)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2);\
}\
}
#define FUNC2S(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2);\
} else {\
visual_server->m_type(p1, p2);\
}\
}
#define FUNC2SC(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2);\
} else {\
visual_server->m_type(p1, p2);\
}\
}
#define FUNC2(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2);\
} else {\
visual_server->m_type(p1, p2);\
}\
}
#define FUNC2C(m_type,m_arg1, m_arg2)\
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2);\
} else {\
visual_server->m_type(p1, p2);\
}\
}
#define FUNC3R(m_r,m_type,m_arg1, m_arg2, m_arg3)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC3RC(m_r,m_type,m_arg1, m_arg2, m_arg3)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3,&ret);\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC3S(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3);\
} else {\
visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC3SC(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3);\
} else {\
visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC3(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3);\
} else {\
visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC3C(m_type,m_arg1, m_arg2, m_arg3)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3);\
} else {\
visual_server->m_type(p1, p2, p3);\
}\
}
#define FUNC4R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4S(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4);\
} else {\
visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4);\
} else {\
visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4);\
} else {\
visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC4C(m_type,m_arg1, m_arg2, m_arg3, m_arg4)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4);\
} else {\
visual_server->m_type(p1, p2, p3, p4);\
}\
}
#define FUNC5R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC5C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5);\
}\
}
#define FUNC6R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6,&ret);\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC6C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6);\
}\
}
#define FUNC7R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
m_r ret;\
command_queue.push_and_ret( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7,&ret);\
SYNC_DEBUG\
return ret;\
} else {\
return visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push_and_sync( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define FUNC7C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7)\
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
if (Thread::get_caller_ID()!=server_thread) {\
command_queue.push( visual_server, &VisualServer::m_type,p1, p2, p3, p4, p5, p6, p7);\
} else {\
visual_server->m_type(p1, p2, p3, p4, p5, p6, p7);\
}\
}
#define ServerName VisualServer
#define ServerNameWrapMT VisualServerWrapMT
#define server_name visual_server
#include "servers/server_wrap_mt_common.h"
//FUNC0R(RID,texture_create);
FUNCRID(texture);
@ -1242,7 +698,15 @@ public:
VisualServerWrapMT(VisualServer* p_contained,bool p_create_thread);
~VisualServerWrapMT();
#undef ServerName
#undef ServerNameWrapMT
#undef server_name
};
#ifdef DEBUG_SYNC
#undef DEBUG_SYNC
#endif
#undef SYNC_DEBUG
#endif

View file

@ -1327,8 +1327,16 @@ void AnimationKeyEditor::_track_editor_draw() {
float time = animation->track_get_key_time(idx,i);
if (time<keys_from)
continue;
if (time>keys_to)
if (time>keys_to) {
if (first && i>0 && animation->track_get_key_value(idx,i)==animation->track_get_key_value(idx,i-1)) {
//draw whole line
te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(settings_limit,y+h/2),color);
}
break;
}
float x = key_hofs + name_limit + (time-keys_from)*zoom_scale;
Ref<Texture> tex = type_icon[tt];

View file

@ -0,0 +1,874 @@
#include "editor_file_dialog.h"
#include "scene/gui/label.h"
#include "scene/gui/center_container.h"
#include "print_string.h"
#include "os/keyboard.h"
#include "editor_resource_preview.h"
EditorFileDialog::GetIconFunc EditorFileDialog::get_icon_func=NULL;
EditorFileDialog::GetIconFunc EditorFileDialog::get_large_icon_func=NULL;
EditorFileDialog::RegisterFunc EditorFileDialog::register_func=NULL;
EditorFileDialog::RegisterFunc EditorFileDialog::unregister_func=NULL;
VBoxContainer *EditorFileDialog::get_vbox() {
return vbox;
}
void EditorFileDialog::_notification(int p_what) {
if (p_what==NOTIFICATION_PROCESS) {
if (preview_waiting) {
preview_wheel_timeout-=get_process_delta_time();
if (preview_wheel_timeout<=0) {
preview_wheel_index++;
if (preview_wheel_index>=8)
preview_wheel_index=0;
Ref<Texture> frame = get_icon("WaitPreview"+itos(preview_wheel_index+1),"EditorIcons");
preview->set_texture(frame);
preview_wheel_timeout=0.1;
}
}
}
if (p_what==NOTIFICATION_DRAW) {
//RID ci = get_canvas_item();
//get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
}
}
void EditorFileDialog::set_enable_multiple_selection(bool p_enable) {
tree->set_select_mode(p_enable?Tree::SELECT_MULTI : Tree::SELECT_SINGLE);
};
Vector<String> EditorFileDialog::get_selected_files() const {
Vector<String> list;
TreeItem* item = tree->get_root();
while ( (item = tree->get_next_selected(item)) ) {
list.push_back(dir_access->get_current_dir().plus_file(item->get_text(0)));
};
return list;
};
void EditorFileDialog::update_dir() {
dir->set_text(dir_access->get_current_dir());
}
void EditorFileDialog::_dir_entered(String p_dir) {
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
update_dir();
}
void EditorFileDialog::_file_entered(const String& p_file) {
_action_pressed();
}
void EditorFileDialog::_save_confirm_pressed() {
String f=dir_access->get_current_dir().plus_file(file->get_text());
emit_signal("file_selected",f);
hide();
}
void EditorFileDialog::_post_popup() {
ConfirmationDialog::_post_popup();
if (invalidated) {
update_file_list();
invalidated=false;
}
if (mode==MODE_SAVE_FILE)
file->grab_focus();
else
tree->grab_focus();
if (is_visible() && get_current_file()!="")
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
}
void EditorFileDialog::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) {
set_process(false);
preview_waiting=false;
if (p_preview.is_valid() && get_current_path()==p_path) {
preview->set_texture(p_preview);
preview_vb->show();
} else {
preview_vb->hide();
preview->set_texture(Ref<Texture>());
}
}
void EditorFileDialog::_request_single_thumbnail(const String& p_path) {
EditorResourcePreview::get_singleton()->queue_resource_preview(p_path,this,"_thumbnail_done",p_path);
print_line("want file "+p_path);
set_process(true);
preview_waiting=true;
preview_wheel_timeout=0;
}
void EditorFileDialog::_action_pressed() {
if (mode==MODE_OPEN_FILES) {
TreeItem *ti=tree->get_next_selected(NULL);
String fbase=dir_access->get_current_dir();
DVector<String> files;
while(ti) {
files.push_back( fbase.plus_file(ti->get_text(0)) );
ti=tree->get_next_selected(ti);
}
if (files.size()) {
emit_signal("files_selected",files);
hide();
}
return;
}
String f=dir_access->get_current_dir().plus_file(file->get_text());
if (mode==MODE_OPEN_FILE && dir_access->file_exists(f)) {
emit_signal("file_selected",f);
hide();
}
if (mode==MODE_OPEN_DIR) {
String path=dir_access->get_current_dir();
/*if (tree->get_selected()) {
Dictionary d = tree->get_selected()->get_metadata(0);
if (d["dir"]) {
path=path+"/"+String(d["name"]);
}
}*/
path=path.replace("\\","/");
emit_signal("dir_selected",path);
hide();
}
if (mode==MODE_SAVE_FILE) {
bool valid=false;
if (filter->get_selected()==filter->get_item_count()-1) {
valid=true; //match none
} else if (filters.size()>1 && filter->get_selected()==0) {
// match all filters
for (int i=0;i<filters.size();i++) {
String flt=filters[i].get_slice(";",0);
for (int j=0;j<flt.get_slice_count(",");j++) {
String str = flt.get_slice(",",j).strip_edges();
if (f.match(str)) {
valid=true;
break;
}
}
if (valid)
break;
}
} else {
int idx=filter->get_selected();
if (filters.size()>1)
idx--;
if (idx>=0 && idx<filters.size()) {
String flt=filters[idx].get_slice(";",0);
int filterSliceCount=flt.get_slice_count(",");
for (int j=0;j<filterSliceCount;j++) {
String str = (flt.get_slice(",",j).strip_edges());
if (f.match(str)) {
valid=true;
break;
}
}
if (!valid && filterSliceCount>0) {
String str = (flt.get_slice(",",0).strip_edges());
f+=str.substr(1, str.length()-1);
_request_single_thumbnail(get_current_dir().plus_file(f.get_file()));
file->set_text(f.get_file());
valid=true;
}
} else {
valid=true;
}
}
if (!valid) {
exterr->popup_centered_minsize(Size2(250,80));
return;
}
if (dir_access->file_exists(f)) {
confirm_save->set_text("File Exists, Overwrite?");
confirm_save->popup_centered(Size2(200,80));
} else {
emit_signal("file_selected",f);
hide();
}
}
}
void EditorFileDialog::_cancel_pressed() {
file->set_text("");
invalidate();
hide();
}
void EditorFileDialog::_tree_selected() {
TreeItem *ti=tree->get_selected();
if (!ti)
return;
Dictionary d=ti->get_metadata(0);
if (!d["dir"]) {
file->set_text(d["name"]);
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
}
}
void EditorFileDialog::_tree_dc_selected() {
TreeItem *ti=tree->get_selected();
if (!ti)
return;
Dictionary d=ti->get_metadata(0);
if (d["dir"]) {
dir_access->change_dir(d["name"]);
if (mode==MODE_OPEN_FILE || mode==MODE_OPEN_FILES || mode==MODE_OPEN_DIR)
file->set_text("");
call_deferred("_update_file_list");
call_deferred("_update_dir");
} else {
_action_pressed();
}
}
void EditorFileDialog::update_file_list() {
tree->clear();
dir_access->list_dir_begin();
TreeItem *root = tree->create_item();
Ref<Texture> folder = get_icon("folder","FileDialog");
List<String> files;
List<String> dirs;
bool isdir;
bool ishidden;
bool show_hidden = show_hidden_files;
String item;
while ((item=dir_access->get_next(&isdir))!="") {
ishidden = dir_access->current_is_hidden();
if (show_hidden || !ishidden) {
if (!isdir)
files.push_back(item);
else
dirs.push_back(item);
}
}
dirs.sort_custom<NoCaseComparator>();
files.sort_custom<NoCaseComparator>();
while(!dirs.empty()) {
if (dirs.front()->get()!=".") {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,dirs.front()->get()+"/");
ti->set_icon(0,folder);
Dictionary d;
d["name"]=dirs.front()->get();
d["dir"]=true;
ti->set_metadata(0,d);
}
dirs.pop_front();
}
dirs.clear();
List<String> patterns;
// build filter
if (filter->get_selected()==filter->get_item_count()-1) {
// match all
} else if (filters.size()>1 && filter->get_selected()==0) {
// match all filters
for (int i=0;i<filters.size();i++) {
String f=filters[i].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
patterns.push_back(f.get_slice(",",j).strip_edges());
}
}
} else {
int idx=filter->get_selected();
if (filters.size()>1)
idx--;
if (idx>=0 && idx<filters.size()) {
String f=filters[idx].get_slice(";",0);
for (int j=0;j<f.get_slice_count(",");j++) {
patterns.push_back(f.get_slice(",",j).strip_edges());
}
}
}
String base_dir = dir_access->get_current_dir();
while(!files.empty()) {
bool match=patterns.empty();
for(List<String>::Element *E=patterns.front();E;E=E->next()) {
if (files.front()->get().matchn(E->get())) {
match=true;
break;
}
}
if (match) {
TreeItem *ti=tree->create_item(root);
ti->set_text(0,files.front()->get());
if (get_icon_func) {
Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
ti->set_icon(0,icon);
}
if (mode==MODE_OPEN_DIR) {
ti->set_custom_color(0,get_color("files_disabled"));
ti->set_selectable(0,false);
}
Dictionary d;
d["name"]=files.front()->get();
d["dir"]=false;
ti->set_metadata(0,d);
if (file->get_text()==files.front()->get())
ti->select(0);
}
files.pop_front();
}
if (tree->get_root() && tree->get_root()->get_children())
tree->get_root()->get_children()->select(0);
files.clear();
}
void EditorFileDialog::_filter_selected(int) {
update_file_list();
}
void EditorFileDialog::update_filters() {
filter->clear();
if (filters.size()>1) {
String all_filters;
const int max_filters=5;
for(int i=0;i<MIN( max_filters, filters.size()) ;i++) {
String flt=filters[i].get_slice(";",0);
if (i>0)
all_filters+=",";
all_filters+=flt;
}
if (max_filters<filters.size())
all_filters+=", ...";
filter->add_item("All Recognized ( "+all_filters+" )");
}
for(int i=0;i<filters.size();i++) {
String flt=filters[i].get_slice(";",0).strip_edges();
String desc=filters[i].get_slice(";",1).strip_edges();
if (desc.length())
filter->add_item(desc+" ( "+flt+" )");
else
filter->add_item("( "+flt+" )");
}
filter->add_item("All Files (*)");
}
void EditorFileDialog::clear_filters() {
filters.clear();
update_filters();
invalidate();
}
void EditorFileDialog::add_filter(const String& p_filter) {
filters.push_back(p_filter);
update_filters();
invalidate();
}
String EditorFileDialog::get_current_dir() const {
return dir->get_text();
}
String EditorFileDialog::get_current_file() const {
return file->get_text();
}
String EditorFileDialog::get_current_path() const {
return dir->get_text().plus_file(file->get_text());
}
void EditorFileDialog::set_current_dir(const String& p_dir) {
dir_access->change_dir(p_dir);
update_dir();
invalidate();
}
void EditorFileDialog::set_current_file(const String& p_file) {
file->set_text(p_file);
update_dir();
invalidate();
int lp = p_file.find_last(".");
if (lp!=-1) {
file->select(0,lp);
file->grab_focus();
}
if (is_visible())
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
}
void EditorFileDialog::set_current_path(const String& p_path) {
if (!p_path.size())
return;
int pos=MAX( p_path.find_last("/"), p_path.find_last("\\") );
if (pos==-1) {
set_current_file(p_path);
} else {
String dir=p_path.substr(0,pos);
String file=p_path.substr(pos+1,p_path.length());
set_current_dir(dir);
set_current_file(file);
}
}
void EditorFileDialog::set_mode(Mode p_mode) {
mode=p_mode;
switch(mode) {
case MODE_OPEN_FILE: get_ok()->set_text("Open"); set_title("Open a File"); makedir->hide(); break;
case MODE_OPEN_FILES: get_ok()->set_text("Open"); set_title("Open File(s)"); makedir->hide(); break;
case MODE_SAVE_FILE: get_ok()->set_text("Save"); set_title("Save a File"); makedir->show(); break;
case MODE_OPEN_DIR: get_ok()->set_text("Open"); set_title("Open a Directory"); makedir->show(); break;
}
if (mode==MODE_OPEN_FILES) {
tree->set_select_mode(Tree::SELECT_MULTI);
} else {
tree->set_select_mode(Tree::SELECT_SINGLE);
}
}
EditorFileDialog::Mode EditorFileDialog::get_mode() const {
return mode;
}
void EditorFileDialog::set_access(Access p_access) {
ERR_FAIL_INDEX(p_access,3);
if (access==p_access)
return;
memdelete( dir_access );
switch(p_access) {
case ACCESS_FILESYSTEM: {
dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
} break;
case ACCESS_RESOURCES: {
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
} break;
case ACCESS_USERDATA: {
dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA);
} break;
}
access=p_access;
_update_drives();
invalidate();
update_filters();
update_dir();
}
void EditorFileDialog::invalidate() {
if (is_visible()) {
update_file_list();
invalidated=false;
} else {
invalidated=true;
}
}
EditorFileDialog::Access EditorFileDialog::get_access() const{
return access;
}
void EditorFileDialog::_make_dir_confirm() {
Error err = dir_access->make_dir( makedirname->get_text() );
if (err==OK) {
dir_access->change_dir(makedirname->get_text());
invalidate();
update_filters();
update_dir();
} else {
mkdirerr->popup_centered_minsize(Size2(250,50));
}
}
void EditorFileDialog::_make_dir() {
makedialog->popup_centered_minsize(Size2(250,80));
makedirname->grab_focus();
}
void EditorFileDialog::_select_drive(int p_idx) {
String d = drives->get_item_text(p_idx);
dir_access->change_dir(d);
file->set_text("");
invalidate();
update_dir();
}
void EditorFileDialog::_update_drives() {
int dc = dir_access->get_drive_count();
if (dc==0 || access!=ACCESS_FILESYSTEM) {
drives->hide();
} else {
drives->clear();
drives->show();
for(int i=0;i<dir_access->get_drive_count();i++) {
String d = dir_access->get_drive(i);
drives->add_item(dir_access->get_drive(i));
}
drives->select(dir_access->get_current_drive());
}
}
bool EditorFileDialog::default_show_hidden_files=true;
void EditorFileDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_tree_selected"),&EditorFileDialog::_tree_selected);
ObjectTypeDB::bind_method(_MD("_tree_db_selected"),&EditorFileDialog::_tree_dc_selected);
ObjectTypeDB::bind_method(_MD("_dir_entered"),&EditorFileDialog::_dir_entered);
ObjectTypeDB::bind_method(_MD("_file_entered"),&EditorFileDialog::_file_entered);
ObjectTypeDB::bind_method(_MD("_action_pressed"),&EditorFileDialog::_action_pressed);
ObjectTypeDB::bind_method(_MD("_cancel_pressed"),&EditorFileDialog::_cancel_pressed);
ObjectTypeDB::bind_method(_MD("_filter_selected"),&EditorFileDialog::_filter_selected);
ObjectTypeDB::bind_method(_MD("_save_confirm_pressed"),&EditorFileDialog::_save_confirm_pressed);
ObjectTypeDB::bind_method(_MD("clear_filters"),&EditorFileDialog::clear_filters);
ObjectTypeDB::bind_method(_MD("add_filter","filter"),&EditorFileDialog::add_filter);
ObjectTypeDB::bind_method(_MD("get_current_dir"),&EditorFileDialog::get_current_dir);
ObjectTypeDB::bind_method(_MD("get_current_file"),&EditorFileDialog::get_current_file);
ObjectTypeDB::bind_method(_MD("get_current_path"),&EditorFileDialog::get_current_path);
ObjectTypeDB::bind_method(_MD("set_current_dir","dir"),&EditorFileDialog::set_current_dir);
ObjectTypeDB::bind_method(_MD("set_current_file","file"),&EditorFileDialog::set_current_file);
ObjectTypeDB::bind_method(_MD("set_current_path","path"),&EditorFileDialog::set_current_path);
ObjectTypeDB::bind_method(_MD("set_mode","mode"),&EditorFileDialog::set_mode);
ObjectTypeDB::bind_method(_MD("get_mode"),&EditorFileDialog::get_mode);
ObjectTypeDB::bind_method(_MD("get_vbox:VBoxContainer"),&EditorFileDialog::get_vbox);
ObjectTypeDB::bind_method(_MD("set_access","access"),&EditorFileDialog::set_access);
ObjectTypeDB::bind_method(_MD("get_access"),&EditorFileDialog::get_access);
ObjectTypeDB::bind_method(_MD("set_show_hidden_files"),&EditorFileDialog::set_show_hidden_files);
ObjectTypeDB::bind_method(_MD("is_showing_hidden_files"),&EditorFileDialog::is_showing_hidden_files);
ObjectTypeDB::bind_method(_MD("_select_drive"),&EditorFileDialog::_select_drive);
ObjectTypeDB::bind_method(_MD("_make_dir"),&EditorFileDialog::_make_dir);
ObjectTypeDB::bind_method(_MD("_make_dir_confirm"),&EditorFileDialog::_make_dir_confirm);
ObjectTypeDB::bind_method(_MD("_update_file_list"),&EditorFileDialog::update_file_list);
ObjectTypeDB::bind_method(_MD("_update_dir"),&EditorFileDialog::update_dir);
ObjectTypeDB::bind_method(_MD("_thumbnail_done"),&EditorFileDialog::_thumbnail_done);
ObjectTypeDB::bind_method(_MD("invalidate"),&EditorFileDialog::invalidate);
ADD_SIGNAL(MethodInfo("file_selected",PropertyInfo( Variant::STRING,"path")));
ADD_SIGNAL(MethodInfo("files_selected",PropertyInfo( Variant::STRING_ARRAY,"paths")));
ADD_SIGNAL(MethodInfo("dir_selected",PropertyInfo( Variant::STRING,"dir")));
BIND_CONSTANT( MODE_OPEN_FILE );
BIND_CONSTANT( MODE_OPEN_FILES );
BIND_CONSTANT( MODE_OPEN_DIR );
BIND_CONSTANT( MODE_SAVE_FILE );
BIND_CONSTANT( ACCESS_RESOURCES );
BIND_CONSTANT( ACCESS_USERDATA );
BIND_CONSTANT( ACCESS_FILESYSTEM );
}
void EditorFileDialog::set_show_hidden_files(bool p_show) {
show_hidden_files=p_show;
invalidate();
}
bool EditorFileDialog::is_showing_hidden_files() const {
return show_hidden_files;
}
void EditorFileDialog::set_default_show_hidden_files(bool p_show) {
default_show_hidden_files=p_show;
}
EditorFileDialog::EditorFileDialog() {
show_hidden_files=true;
VBoxContainer *vbc = memnew( VBoxContainer );
add_child(vbc);
set_child_rect(vbc);
mode=MODE_SAVE_FILE;
set_title("Save a File");
dir = memnew(LineEdit);
HBoxContainer *pathhb = memnew( HBoxContainer );
pathhb->add_child(dir);
dir->set_h_size_flags(SIZE_EXPAND_FILL);
drives = memnew( OptionButton );
pathhb->add_child(drives);
drives->connect("item_selected",this,"_select_drive");
makedir = memnew( Button );
makedir->set_text("Create Folder");
makedir->connect("pressed",this,"_make_dir");
pathhb->add_child(makedir);
vbc->add_margin_child("Path:",pathhb);
list_hb = memnew( HBoxContainer );
vbc->add_margin_child("Directories & Files:",list_hb,true);
tree = memnew(Tree);
tree->set_hide_root(true);
tree->set_h_size_flags(SIZE_EXPAND_FILL);
list_hb->add_child(tree);
HBoxContainer* filter_hb = memnew( HBoxContainer );
vbc->add_child(filter_hb);
VBoxContainer *filter_vb = memnew( VBoxContainer );
filter_hb->add_child(filter_vb);
filter_vb->set_h_size_flags(SIZE_EXPAND_FILL);
preview_vb = memnew( VBoxContainer );
filter_hb->add_child(preview_vb);
CenterContainer *prev_cc = memnew( CenterContainer );
preview_vb->add_margin_child("Preview:",prev_cc);
preview = memnew( TextureFrame );
prev_cc->add_child(preview);
preview_vb->hide();
file = memnew(LineEdit);
//add_child(file);
filter_vb->add_margin_child("File:",file);
filter = memnew( OptionButton );
//add_child(filter);
filter_vb->add_margin_child("Filter:",filter);
filter->set_clip_text(true);//too many extensions overflow it
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
access=ACCESS_RESOURCES;
_update_drives();
connect("confirmed", this,"_action_pressed");
//cancel->connect("pressed", this,"_cancel_pressed");
tree->connect("cell_selected", this,"_tree_selected",varray(),CONNECT_DEFERRED);
tree->connect("item_activated", this,"_tree_db_selected",varray());
dir->connect("text_entered", this,"_dir_entered");
file->connect("text_entered", this,"_file_entered");
filter->connect("item_selected", this,"_filter_selected");
confirm_save = memnew( ConfirmationDialog );
confirm_save->set_as_toplevel(true);
add_child(confirm_save);
confirm_save->connect("confirmed", this,"_save_confirm_pressed");
makedialog = memnew( ConfirmationDialog );
makedialog->set_title("Create Folder");
VBoxContainer *makevb= memnew( VBoxContainer );
makedialog->add_child(makevb);
makedialog->set_child_rect(makevb);
makedirname = memnew( LineEdit );
makevb->add_margin_child("Name:",makedirname);
add_child(makedialog);
makedialog->register_text_enter(makedirname);
makedialog->connect("confirmed",this,"_make_dir_confirm");
mkdirerr = memnew( AcceptDialog );
mkdirerr->set_text("Could not create folder.");
add_child(mkdirerr);
exterr = memnew( AcceptDialog );
exterr->set_text("Must use a valid extension.");
add_child(exterr);
//update_file_list();
update_filters();
update_dir();
set_hide_on_ok(false);
vbox=vbc;
invalidated=true;
if (register_func)
register_func(this);
preview_wheel_timeout=0;
preview_wheel_index=0;
preview_waiting=false;
}
EditorFileDialog::~EditorFileDialog() {
if (unregister_func)
unregister_func(this);
memdelete(dir_access);
}
void EditorLineEditFileChooser::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_browse"),&EditorLineEditFileChooser::_browse);
ObjectTypeDB::bind_method(_MD("_chosen"),&EditorLineEditFileChooser::_chosen);
ObjectTypeDB::bind_method(_MD("get_button:Button"),&EditorLineEditFileChooser::get_button);
ObjectTypeDB::bind_method(_MD("get_line_edit:LineEdit"),&EditorLineEditFileChooser::get_line_edit);
ObjectTypeDB::bind_method(_MD("get_file_dialog:EditorFileDialog"),&EditorLineEditFileChooser::get_file_dialog);
}
void EditorLineEditFileChooser::_chosen(const String& p_text){
line_edit->set_text(p_text);
line_edit->emit_signal("text_entered",p_text);
}
void EditorLineEditFileChooser::_browse() {
dialog->popup_centered_ratio();
}
EditorLineEditFileChooser::EditorLineEditFileChooser() {
line_edit = memnew( LineEdit );
add_child(line_edit);
line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
button = memnew( Button );
button->set_text(" .. ");
add_child(button);
button->connect("pressed",this,"_browse");
dialog = memnew( EditorFileDialog);
add_child(dialog);
dialog->connect("file_selected",this,"_chosen");
dialog->connect("dir_selected",this,"_chosen");
dialog->connect("files_selected",this,"_chosen");
}

View file

@ -0,0 +1,198 @@
/*************************************************************************/
/* file_dialog.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/*************************************************************************/
#ifndef EDITORFILEDIALOG_H
#define EDITORFILEDIALOG_H
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
#include "scene/gui/dialogs.h"
#include "os/dir_access.h"
#include "scene/gui/box_container.h"
#include "scene/gui/texture_frame.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class EditorFileDialog : public ConfirmationDialog {
OBJ_TYPE( EditorFileDialog, ConfirmationDialog );
public:
enum Access {
ACCESS_RESOURCES,
ACCESS_USERDATA,
ACCESS_FILESYSTEM
};
enum Mode {
MODE_OPEN_FILE,
MODE_OPEN_FILES,
MODE_OPEN_DIR,
MODE_SAVE_FILE,
};
typedef Ref<Texture> (*GetIconFunc)(const String&);
typedef void (*RegisterFunc)(EditorFileDialog*);
static GetIconFunc get_icon_func;
static GetIconFunc get_large_icon_func;
static RegisterFunc register_func;
static RegisterFunc unregister_func;
private:
ConfirmationDialog *makedialog;
LineEdit *makedirname;
Button *makedir;
Access access;
//Button *action;
VBoxContainer *vbox;
Mode mode;
LineEdit *dir;
OptionButton *drives;
Tree *tree;
TextureFrame *preview;
VBoxContainer *preview_vb;
HBoxContainer *list_hb;
LineEdit *file;
AcceptDialog *mkdirerr;
AcceptDialog *exterr;
OptionButton *filter;
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
Vector<String> filters;
bool preview_waiting;
int preview_wheel_index;
float preview_wheel_timeout;
static bool default_show_hidden_files;
bool show_hidden_files;
bool invalidated;
void update_dir();
void update_file_list();
void update_filters();
void _tree_selected();
void _select_drive(int p_idx);
void _tree_dc_selected();
void _dir_entered(String p_dir);
void _file_entered(const String& p_file);
void _action_pressed();
void _save_confirm_pressed();
void _cancel_pressed();
void _filter_selected(int);
void _make_dir();
void _make_dir_confirm();
void _update_drives();
virtual void _post_popup();
//callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load
void _thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata);
void _request_single_thumbnail(const String& p_path);
protected:
void _notification(int p_what);
static void _bind_methods();
//bind helpers
public:
void clear_filters();
void add_filter(const String& p_filter);
void set_enable_multiple_selection(bool p_enable);
Vector<String> get_selected_files() const;
String get_current_dir() const;
String get_current_file() const;
String get_current_path() const;
void set_current_dir(const String& p_dir);
void set_current_file(const String& p_file);
void set_current_path(const String& p_path);
void set_mode(Mode p_mode);
Mode get_mode() const;
VBoxContainer *get_vbox();
LineEdit *get_line_edit() { return file; }
void set_access(Access p_access);
Access get_access() const;
void set_show_hidden_files(bool p_show);
bool is_showing_hidden_files() const;
static void set_default_show_hidden_files(bool p_show);
void invalidate();
EditorFileDialog();
~EditorFileDialog();
};
class EditorLineEditFileChooser : public HBoxContainer {
OBJ_TYPE( EditorLineEditFileChooser, HBoxContainer );
Button *button;
LineEdit *line_edit;
EditorFileDialog *dialog;
void _chosen(const String& p_text);
void _browse();
protected:
static void _bind_methods();
public:
Button *get_button() { return button; }
LineEdit *get_line_edit() { return line_edit; }
EditorFileDialog *get_file_dialog() { return dialog; }
EditorLineEditFileChooser();
};
VARIANT_ENUM_CAST( EditorFileDialog::Mode );
VARIANT_ENUM_CAST( EditorFileDialog::Access );
#endif // EDITORFILEDIALOG_H

View file

@ -99,6 +99,7 @@
#include "tools/editor/io_plugins/editor_translation_import_plugin.h"
#include "tools/editor/io_plugins/editor_mesh_import_plugin.h"
#include "plugins/editor_preview_plugins.h"
EditorNode *EditorNode::singleton=NULL;
@ -320,6 +321,11 @@ void EditorNode::_fs_changed() {
E->get()->invalidate();
}
for(Set<EditorFileDialog*>::Element *E=editor_file_dialogs.front();E;E=E->next()) {
E->get()->invalidate();
}
}
void EditorNode::_sources_changed(bool p_exist) {
@ -386,7 +392,7 @@ void EditorNode::edit_node(Node *p_node) {
void EditorNode::open_resource(const String& p_type) {
file->set_mode(FileDialog::MODE_OPEN_FILE);
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type(p_type,&extensions);
@ -718,6 +724,96 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed,
}
void EditorNode::_find_node_types(Node* p_node, int&count_2d, int&count_3d) {
if (p_node->is_type("Viewport") || (p_node!=get_edited_scene() && p_node->get_owner()!=get_edited_scene()))
return;
if (p_node->is_type("CanvasItem"))
count_2d++;
else if (p_node->is_type("Spatial"))
count_3d++;
for(int i=0;i<p_node->get_child_count();i++)
_find_node_types(p_node->get_child(i),count_2d,count_3d);
}
void EditorNode::_save_scene_with_preview(String p_file) {
int c2d=0;
int c3d=0;
EditorProgress save("save","Saving Scene",4);
save.step("Analyzing",0);
_find_node_types(get_edited_scene(),c2d,c3d);
RID viewport;
bool is2d;
if (c3d<c2d) {
viewport=scene_root->get_viewport();
is2d=true;
} else {
viewport=SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_viewport();
is2d=false;
}
save.step("Creating Thumbnail",1);
//current view?
int screen =-1;
for(int i=0;i<editor_table.size();i++) {
if (editor_plugin_screen==editor_table[i]) {
screen=i;
break;
}
}
_editor_select(is2d?0:1);
VS::get_singleton()->viewport_queue_screen_capture(viewport);
save.step("Creating Thumbnail",2);
save.step("Creating Thumbnail",3);
Image img = VS::get_singleton()->viewport_get_screen_capture(viewport);
int preview_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");;
int width,height;
if (img.get_width() > preview_size && img.get_width() >= img.get_height()) {
width=preview_size;
height = img.get_height() * preview_size / img.get_width();
} else if (img.get_height() > preview_size && img.get_height() >= img.get_width()) {
height=preview_size;
width = img.get_width() * preview_size / img.get_height();
} else {
width=img.get_width();
height=img.get_height();
}
img.convert(Image::FORMAT_RGB);
img.resize(width,height);
String pfile = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/last_scene_preview.png");
img.save_png(pfile);
Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile);
print_line("img data is "+itos(imgdata.size()));
if (scene_import_metadata.is_null())
scene_import_metadata = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) );
scene_import_metadata->set_option("thumbnail",imgdata);
//tamanio tel thumbnail
if (screen!=-1) {
_editor_select(screen);
}
save.step("Saving Scene",4);
_save_scene(p_file);
}
void EditorNode::_save_scene(String p_file) {
Node *scene = edited_scene;
@ -1016,7 +1112,9 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
_save_scene(p_file);
//_save_scene(p_file);
_save_scene_with_preview(p_file);
}
} break;
@ -1024,7 +1122,8 @@ void EditorNode::_dialog_action(String p_file) {
case FILE_SAVE_AND_RUN: {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
_save_scene(p_file);
//_save_scene(p_file);
_save_scene_with_preview(p_file);
_run(false);
}
} break;
@ -1177,7 +1276,8 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode()==FileDialog::MODE_SAVE_FILE) {
_save_scene(p_file);
//_save_scene(p_file);
_save_scene_with_preview(p_file);
}
} break;
@ -1505,7 +1605,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
return;
}
_save_scene(scene->get_filename());
//_save_scene(scene->get_filename());
_save_scene_with_preview(scene->get_filename());
}
}
@ -1608,7 +1709,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
//print_tree();
file->set_mode(FileDialog::MODE_OPEN_FILE);
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
//not for now?
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene",&extensions);
@ -1659,7 +1760,8 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
Node *scene = edited_scene;
if (scene && scene->get_filename()!="") {
_save_scene(scene->get_filename());
//_save_scene(scene->get_filename());
_save_scene_with_preview(scene->get_filename());
return;
};
// fallthrough to save_as
@ -1678,7 +1780,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
}
file->set_mode(FileDialog::MODE_SAVE_FILE);
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool());
@ -1761,7 +1863,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
bool relpaths = (scene->has_meta("__editor_relpaths__") && scene->get_meta("__editor_relpaths__").operator bool());
file->set_mode(FileDialog::MODE_SAVE_FILE);
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
file->set_current_path(cpath);
file->set_title("Save Translatable Strings");
@ -1810,7 +1912,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
break;
}
file->set_mode(FileDialog::MODE_SAVE_FILE);
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
List<String> extensions;
Ref<PackedScene> sd = memnew( PackedScene );
@ -3132,6 +3234,7 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorImportPlugin>();
ObjectTypeDB::register_type<EditorScenePostImport>();
ObjectTypeDB::register_type<EditorScript>();
ObjectTypeDB::register_type<EditorFileDialog>();
//ObjectTypeDB::register_type<EditorImporter>();
@ -3282,6 +3385,16 @@ void EditorNode::_file_dialog_unregister(FileDialog *p_dialog){
singleton->file_dialogs.erase(p_dialog);
}
void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) {
singleton->editor_file_dialogs.insert(p_dialog);
}
void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog){
singleton->editor_file_dialogs.erase(p_dialog);
}
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
Error EditorNode::export_platform(const String& p_platform, const String& p_path, bool p_debug,const String& p_password,bool p_quit_after) {
@ -3334,6 +3447,11 @@ EditorNode::EditorNode() {
FileDialog::register_func=_file_dialog_register;
FileDialog::unregister_func=_file_dialog_unregister;
EditorFileDialog::get_icon_func=_file_dialog_get_icon;
EditorFileDialog::register_func=_editor_file_dialog_register;
EditorFileDialog::unregister_func=_editor_file_dialog_unregister;
editor_import_export = memnew( EditorImportExport );
add_child(editor_import_export);
@ -3358,6 +3476,9 @@ EditorNode::EditorNode() {
editor_register_icons(theme);
editor_register_fonts(theme);
//theme->set_icon("folder","EditorFileDialog",Theme::get_default()->get_icon("folder","EditorFileDialog"));
//theme->set_color("files_disabled","EditorFileDialog",Color(0,0,0,0.7));
String global_font = EditorSettings::get_singleton()->get("global/font");
if (global_font!="") {
Ref<Font> fnt = ResourceLoader::load(global_font);
@ -3376,6 +3497,8 @@ EditorNode::EditorNode() {
theme->set_stylebox("EditorFocus","EditorStyles",focus_sbt);
resource_preview = memnew( EditorResourcePreview );
add_child(resource_preview);
progress_dialog = memnew( ProgressDialog );
gui_base->add_child(progress_dialog);
@ -3473,6 +3596,7 @@ EditorNode::EditorNode() {
animation_panel=pc;
animation_panel->hide();
HBoxContainer *animation_hb = memnew( HBoxContainer);
animation_vb->add_child(animation_hb);
@ -4031,7 +4155,7 @@ EditorNode::EditorNode() {
file_templates->add_filter("*.tpz ; Template Package");
file = memnew( FileDialog );
file = memnew( EditorFileDialog );
gui_base->add_child(file);
file->set_current_dir("res://");
@ -4161,6 +4285,13 @@ EditorNode::EditorNode() {
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
add_editor_plugin( EditorPlugins::create(i,this) );
resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorScriptPreviewPlugin>( memnew(EditorScriptPreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorSamplePreviewPlugin>( memnew(EditorSamplePreviewPlugin )));
circle_step_msec=OS::get_singleton()->get_ticks_msec();
circle_step_frame=OS::get_singleton()->get_frames_drawn();;
circle_step=0;

View file

@ -78,7 +78,7 @@
#include "tools/editor/editor_plugin.h"
#include "fileserver/editor_file_server.h"
#include "editor_resource_preview.h"
@ -238,7 +238,7 @@ class EditorNode : public Node {
EditorSettingsDialog *settings_config_dialog;
RunSettingsDialog *run_settings_dialog;
ProjectSettings *project_settings;
FileDialog *file;
EditorFileDialog *file;
FileDialog *file_templates;
FileDialog *file_export;
FileDialog *file_export_lib;
@ -304,6 +304,7 @@ class EditorNode : public Node {
EditorSelection *editor_selection;
ProjectExport *project_export;
ProjectExportDialog *project_export_settings;
EditorResourcePreview *resource_preview;
EditorFileServer *file_server;
@ -381,11 +382,15 @@ class EditorNode : public Node {
String import_reload_fn;
Set<FileDialog*> file_dialogs;
Set<EditorFileDialog*> editor_file_dialogs;
Map<String,Ref<Texture> > icon_type_cache;
static Ref<Texture> _file_dialog_get_icon(const String& p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
static void _editor_file_dialog_register(EditorFileDialog *p_dialog);
static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog);
void _cleanup_scene();
@ -394,6 +399,9 @@ class EditorNode : public Node {
bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags);
void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags);
void _find_node_types(Node* p_node, int&count_2d, int&count_3d);
void _save_scene_with_preview(String p_file);
struct ExportDefer {
String platform;

View file

@ -0,0 +1,260 @@
#include "editor_resource_preview.h"
#include "editor_settings.h"
#include "os/file_access.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "globals.h"
Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String& p_path) {
RES res = ResourceLoader::load(p_path);
if (!res.is_valid())
return res;
return generate(res);
}
EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
}
EditorResourcePreview* EditorResourcePreview::singleton=NULL;
void EditorResourcePreview::_thread_func(void *ud) {
EditorResourcePreview *erp=(EditorResourcePreview*)ud;
erp->_thread();
}
void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture>& p_texture,ObjectID id,const StringName& p_func,const Variant& p_ud) {
print_line("preview is ready");
preview_mutex->lock();
Item item;
item.order=order++;
item.preview=p_texture;
cache[p_str]=item;
Object *recv = ObjectDB::get_instance(id);
if (recv) {
recv->call_deferred(p_func,p_str,p_texture,p_ud);
}
preview_mutex->unlock();
}
Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,const String& cache_base) {
String type = ResourceLoader::get_resource_type(p_item.path);
print_line("resource type is: "+type);
if (type=="")
return Ref<Texture>(); //could not guess type
Ref<Texture> generated;
for(int i=0;i<preview_generators.size();i++) {
if (!preview_generators[i]->handles(type))
continue;
generated = preview_generators[i]->generate_from_path(p_item.path);
break;
}
if (generated.is_valid()) {
print_line("was generated");
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
//wow it generated a preview... save cache
ResourceSaver::save(cache_base+".png",generated);
FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE);
f->store_line(itos(thumbnail_size));
f->store_line(itos(FileAccess::get_modified_time(p_item.path)));
f->store_line(FileAccess::get_md5(p_item.path));
memdelete(f);
} else {
print_line("was not generated");
}
return generated;
}
void EditorResourcePreview::_thread() {
print_line("begin thread");
while(!exit) {
print_line("wait for semaphore");
preview_sem->wait();
preview_mutex->lock();
print_line("blue team go");
if (queue.size()) {
print_line("pop from queue");
QueueItem item = queue.front()->get();
queue.pop_front();
preview_mutex->unlock();
Ref<Texture> texture;
uint64_t modtime = FileAccess::get_modified_time(item.path);
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
if (cache.has(item.path)) {
//already has it because someone loaded it, just let it know it's ready
call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata);
} else {
String temp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
String cache_base = Globals::get_singleton()->globalize_path(item.path).md5_text();
cache_base = temp_path.plus_file("resthumb-"+cache_base);
//does not have it, try to load a cached thumbnail
String file = cache_base+".txt";
print_line("cachetxt at "+file);
FileAccess *f=FileAccess::open(file,FileAccess::READ);
if (!f) {
print_line("generate because not cached");
//generate
texture=_generate_preview(item,cache_base);
} else {
int tsize = f->get_line().to_int64();
uint64_t last_modtime = f->get_line().to_int64();
bool cache_valid = true;
if (tsize!=thumbnail_size) {
cache_valid=false;
memdelete(f);
} else if (last_modtime!=modtime) {
String last_md5 = f->get_line();
String md5 = FileAccess::get_md5(item.path);
memdelete(f);
if (last_md5!=md5) {
cache_valid=false;
} else {
//update modified time
f=FileAccess::open(file,FileAccess::WRITE);
f->store_line(itos(modtime));
f->store_line(md5);
memdelete(f);
}
} else {
memdelete(f);
}
if (cache_valid) {
texture = ResourceLoader::load(cache_base+".png","ImageTexture",true);
if (!texture.is_valid()) {
//well fuck
cache_valid=false;
}
}
if (!cache_valid) {
texture=_generate_preview(item,cache_base);
}
}
print_line("notify of preview ready");
call_deferred("_preview_ready",item.path,texture,item.id,item.function,item.userdata);
}
} else {
preview_mutex->unlock();
}
}
}
void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) {
ERR_FAIL_NULL(p_receiver);
preview_mutex->lock();
if (cache.has(p_path)) {
cache[p_path].order=order++;
p_receiver->call_deferred(p_receiver_func,p_path,cache[p_path].preview,p_userdata);
preview_mutex->unlock();
return;
}
print_line("send to thread");
QueueItem item;
item.function=p_receiver_func;
item.id=p_receiver->get_instance_ID();
item.path=p_path;
item.userdata=p_userdata;
queue.push_back(item);
preview_mutex->unlock();
preview_sem->post();
}
void EditorResourcePreview::add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator) {
preview_generators.push_back(p_generator);
}
EditorResourcePreview* EditorResourcePreview::get_singleton() {
return singleton;
}
void EditorResourcePreview::_bind_methods() {
ObjectTypeDB::bind_method("_preview_ready",&EditorResourcePreview::_preview_ready);
}
EditorResourcePreview::EditorResourcePreview() {
singleton=this;
preview_mutex = Mutex::create();
preview_sem = Semaphore::create();
order=0;
exit=false;
thread = Thread::create(_thread_func,this);
}
EditorResourcePreview::~EditorResourcePreview()
{
exit=true;
preview_sem->post();
Thread::wait_to_finish(thread);
memdelete(thread);
memdelete(preview_mutex);
memdelete(preview_sem);
}

View file

@ -0,0 +1,95 @@
#ifndef EDITORRESOURCEPREVIEW_H
#define EDITORRESOURCEPREVIEW_H
#include "scene/main/node.h"
#include "os/semaphore.h"
#include "os/thread.h"
#include "scene/resources/texture.h"
/* make previews for:
*packdscene
-wav
*image
-mesh
-font
*script
*material
-shader
-shader graph?
-navigation mesh
-collision?
-occluder polygon
-navigation polygon
-tileset
-curve and curve2D
*/
class EditorResourcePreviewGenerator : public Reference {
OBJ_TYPE(EditorResourcePreviewGenerator,Reference );
public:
virtual bool handles(const String& p_type) const=0;
virtual Ref<Texture> generate(const RES& p_from)=0;
virtual Ref<Texture> generate_from_path(const String& p_path);
EditorResourcePreviewGenerator();
};
class EditorResourcePreview : public Node {
OBJ_TYPE(EditorResourcePreview,Node);
static EditorResourcePreview* singleton;
struct QueueItem {
String path;
ObjectID id;
StringName function;
Variant userdata;
};
List<QueueItem> queue;
Mutex *preview_mutex;
Semaphore *preview_sem;
Thread *thread;
bool exit;
struct Item {
Ref<Texture> preview;
int order;
};
int order;
Map<String,Item> cache;
void _preview_ready(const String& p_str,const Ref<Texture>& p_texture, ObjectID id, const StringName &p_func, const Variant &p_ud);
Ref<Texture> _generate_preview(const QueueItem& p_item, const String &cache_base);
static void _thread_func(void *ud);
void _thread();
Vector<Ref<EditorResourcePreviewGenerator> > preview_generators;
protected:
static void _bind_methods();
public:
static EditorResourcePreview* get_singleton();
//callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load
void queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata);
void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator);
EditorResourcePreview();
~EditorResourcePreview();
};
#endif // EDITORRESOURCEPREVIEW_H

View file

@ -448,6 +448,8 @@ void EditorSettings::_load_defaults() {
set("text_editor/create_signal_callbacks",true);
set("file_dialog/show_hidden_files", false);
set("file_dialog/thumbnail_size", 64);
hints["file_dialog/thumbnail_size"]=PropertyInfo(Variant::INT,"file_dialog/thumbnail_size",PROPERTY_HINT_RANGE,"32,128,16");
set("animation/autorename_animation_tracks",true);
set("animation/confirm_insert_track",true);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,664 @@
#include "editor_preview_plugins.h"
#include "io/resource_loader.h"
#include "tools/editor/editor_settings.h"
#include "io/file_access_memory.h"
#include "os/os.h"
#include "scene/resources/material.h"
#include "scene/resources/sample.h"
bool EditorTexturePreviewPlugin::handles(const String& p_type) const {
return ObjectTypeDB::is_type(p_type,"ImageTexture");
}
Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) {
Ref<ImageTexture> tex =p_from;
Image img = tex->get_data();
if (img.empty())
return Ref<Texture>();
img.clear_mipmaps();
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
if (img.is_compressed()) {
if (img.decompress()!=OK)
return Ref<Texture>();
} else if (img.get_format()!=Image::FORMAT_RGB && img.get_format()!=Image::FORMAT_RGB) {
img.convert(Image::FORMAT_RGBA);
}
int width,height;
if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) {
width=thumbnail_size;
height = img.get_height() * thumbnail_size / img.get_width();
} else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) {
height=thumbnail_size;
width = img.get_width() * thumbnail_size / img.get_height();
} else {
width=img.get_width();
height=img.get_height();
}
img.resize(width,height);
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
ptex->create_from_image(img,0);
return ptex;
}
EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
}
///////////////////////////////////////////////////////////////////////////
Ref<Texture> EditorPackedScenePreviewPlugin::_gen_from_imd(Ref<ResourceImportMetadata> p_imd) {
if (p_imd.is_null())
return Ref<Texture>();
if (!p_imd->has_option("thumbnail"))
return Ref<Texture>();
Variant tn = p_imd->get_option("thumbnail");
print_line(Variant::get_type_name(tn.get_type()));
DVector<uint8_t> thumbnail = tn;
int len = thumbnail.size();
if (len==0)
return Ref<Texture>();
DVector<uint8_t>::Read r = thumbnail.read();
Image img(r.ptr(),len);
if (img.empty())
return Ref<Texture>();
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
ptex->create_from_image(img,0);
return ptex;
}
bool EditorPackedScenePreviewPlugin::handles(const String& p_type) const {
return ObjectTypeDB::is_type(p_type,"PackedScene");
}
Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES& p_from) {
Ref<ResourceImportMetadata> imd = p_from->get_import_metadata();
return _gen_from_imd(imd);
}
Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String& p_path) {
Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path);
return _gen_from_imd(imd);
}
EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
}
//////////////////////////////////////////////////////////////////
bool EditorMaterialPreviewPlugin::handles(const String& p_type) const {
return ObjectTypeDB::is_type(p_type,"Material"); //any material
}
Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES& p_from) {
Ref<Material> material = p_from;
ERR_FAIL_COND_V(material.is_null(),Ref<Texture>());
VS::get_singleton()->mesh_surface_set_material(sphere,0,material->get_rid());
VS::get_singleton()->viewport_queue_screen_capture(viewport);
VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture
// print_line("queue capture!");
Image img;
int timeout=1000;
while(timeout) {
//print_line("try capture?");
OS::get_singleton()->delay_usec(10);
img = VS::get_singleton()->viewport_get_screen_capture(viewport);
if (!img.empty())
break;
timeout--;
}
//print_line("captured!");
VS::get_singleton()->mesh_surface_set_material(sphere,0,RID());
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
img.resize(thumbnail_size,thumbnail_size);
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
ptex->create_from_image(img,0);
return ptex;
}
EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
scenario = VS::get_singleton()->scenario_create();
viewport = VS::get_singleton()->viewport_create();
VS::get_singleton()->viewport_set_as_render_target(viewport,true);
VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED);
VS::get_singleton()->viewport_set_scenario(viewport,scenario);
VS::ViewportRect vr;
vr.x=0;
vr.y=0;
vr.width=128;
vr.height=128;
VS::get_singleton()->viewport_set_rect(viewport,vr);
camera = VS::get_singleton()->camera_create();
VS::get_singleton()->viewport_attach_camera(viewport,camera);
VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3)));
VS::get_singleton()->camera_set_perspective(camera,45,0.1,10);
light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
light_instance = VS::get_singleton()->instance_create2(light,scenario);
VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7));
VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0));
light_instance2 = VS::get_singleton()->instance_create2(light2,scenario);
VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
sphere = VS::get_singleton()->mesh_create();
sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario);
int lats=32;
int lons=32;
float radius=1.0;
DVector<Vector3> vertices;
DVector<Vector3> normals;
DVector<Vector2> uvs;
DVector<float> tangents;
Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5);
for(int i = 1; i <= lats; i++) {
double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
double z0 = Math::sin(lat0);
double zr0 = Math::cos(lat0);
double lat1 = Math_PI * (-0.5 + (double) i / lats);
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
for(int j = lons; j >= 1; j--) {
double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
double lng1 = 2 * Math_PI * (double) (j) / lons;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
Vector3 v[4]={
Vector3(x1 * zr0, z0, y1 *zr0),
Vector3(x1 * zr1, z1, y1 *zr1),
Vector3(x0 * zr1, z1, y0 *zr1),
Vector3(x0 * zr0, z0, y0 *zr0)
};
#define ADD_POINT(m_idx) \
normals.push_back(v[m_idx]);\
vertices.push_back(v[m_idx]*radius);\
{ Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\
uv/=Math_PI;\
uv*=4.0;\
uv=uv*0.5+Vector2(0.5,0.5);\
uvs.push_back(uv);\
}\
{ Vector3 t = tt.xform(v[m_idx]);\
tangents.push_back(t.x);\
tangents.push_back(t.y);\
tangents.push_back(t.z);\
tangents.push_back(1.0);\
}
ADD_POINT(0);
ADD_POINT(1);
ADD_POINT(2);
ADD_POINT(2);
ADD_POINT(3);
ADD_POINT(0);
}
}
Array arr;
arr.resize(VS::ARRAY_MAX);
arr[VS::ARRAY_VERTEX]=vertices;
arr[VS::ARRAY_NORMAL]=normals;
arr[VS::ARRAY_TANGENT]=tangents;
arr[VS::ARRAY_TEX_UV]=uvs;
VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr);
}
EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
VS::get_singleton()->free(sphere);
VS::get_singleton()->free(sphere_instance);
VS::get_singleton()->free(viewport);
VS::get_singleton()->free(light);
VS::get_singleton()->free(light_instance);
VS::get_singleton()->free(light2);
VS::get_singleton()->free(light_instance2);
VS::get_singleton()->free(camera);
VS::get_singleton()->free(scenario);
}
///////////////////////////////////////////////////////////////////////////
static bool _is_text_char(CharType c) {
return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
}
bool EditorScriptPreviewPlugin::handles(const String& p_type) const {
return ObjectTypeDB::is_type(p_type,"Script");
}
Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) {
Ref<Script> scr = p_from;
if (scr.is_null())
return Ref<Texture>();
String code = scr->get_source_code().strip_edges();
if (code=="")
return Ref<Texture>();
List<String> kwors;
scr->get_language()->get_reserved_words(&kwors);
Set<String> keywords;
for(List<String>::Element *E=kwors.front();E;E=E->next()) {
keywords.insert(E->get());
}
int line = 0;
int col=0;
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA);
Color bg_color = EditorSettings::get_singleton()->get("text_editor/background_color");
bg_color.a=1.0;
Color keyword_color = EditorSettings::get_singleton()->get("text_editor/keyword_color");
Color text_color = EditorSettings::get_singleton()->get("text_editor/text_color");
Color symbol_color = EditorSettings::get_singleton()->get("text_editor/symbol_color");
Color comment_color = EditorSettings::get_singleton()->get("text_editor/comment_color");
for(int i=0;i<thumbnail_size;i++) {
for(int j=0;j<thumbnail_size;j++) {
img.put_pixel(i,j,bg_color);
}
}
bool prev_is_text=false;
bool in_keyword=false;
for(int i=0;i<code.length();i++) {
CharType c = code[i];
if (c>32) {
if (col<thumbnail_size) {
Color color = text_color;
if (c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t')) {
//make symbol a little visible
color=symbol_color;
in_keyword=false;
} else if (!prev_is_text && _is_text_char(c)) {
int pos = i;
while(_is_text_char(code[pos])) {
pos++;
}
///print_line("from "+itos(i)+" to "+itos(pos));
String word = code.substr(i,pos-i);
//print_line("found word: "+word);
if (keywords.has(word))
in_keyword=true;
} else if (!_is_text_char(c)) {
in_keyword=false;
}
if (in_keyword)
color=keyword_color;
Color ul=color;
ul.a*=0.5;
img.put_pixel(col,line*2,bg_color.blend(ul));
img.put_pixel(col,line*2+1,color);
prev_is_text=_is_text_char(c);
}
} else {
prev_is_text=false;
in_keyword=false;
if (c=='\n') {
col=0;
line++;
if (line>=thumbnail_size/2)
break;
} else if (c=='\t') {
col+=3;
}
}
col++;
}
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture));
ptex->create_from_image(img,0);
return ptex;
}
EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() {
}
///////////////////////////////////////////////////////////////////
bool EditorSamplePreviewPlugin::handles(const String& p_type) const {
return ObjectTypeDB::is_type(p_type,"Sample");
}
Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) {
Ref<Sample> smp =p_from;
ERR_FAIL_COND_V(smp.is_null(),Ref<Texture>());
int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size");
DVector<uint8_t> img;
int w = thumbnail_size;
int h = thumbnail_size;
img.resize(w*h*3);
DVector<uint8_t>::Write imgdata = img.write();
uint8_t * imgw = imgdata.ptr();
DVector<uint8_t> data = smp->get_data();
DVector<uint8_t>::Read sampledata = data.read();
const uint8_t *sdata=sampledata.ptr();
bool stereo = smp->is_stereo();
bool _16=smp->get_format()==Sample::FORMAT_PCM16;
int len = smp->get_length();
if (len<1)
return Ref<Texture>();
if (smp->get_format()==Sample::FORMAT_IMA_ADPCM) {
struct IMA_ADPCM_State {
int16_t step_index;
int32_t predictor;
/* values at loop point */
int16_t loop_step_index;
int32_t loop_predictor;
int32_t last_nibble;
int32_t loop_pos;
int32_t window_ofs;
const uint8_t *ptr;
} ima_adpcm;
ima_adpcm.step_index=0;
ima_adpcm.predictor=0;
ima_adpcm.loop_step_index=0;
ima_adpcm.loop_predictor=0;
ima_adpcm.last_nibble=-1;
ima_adpcm.loop_pos=0x7FFFFFFF;
ima_adpcm.window_ofs=0;
ima_adpcm.ptr=NULL;
for(int i=0;i<w;i++) {
float max[2]={-1e10,-1e10};
float min[2]={1e10,1e10};
int from = i*len/w;
int to = (i+1)*len/w;
if (to>=len)
to=len-1;
for(int j=from;j<to;j++) {
while(j>ima_adpcm.last_nibble) {
static const int16_t _ima_adpcm_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
static const int8_t _ima_adpcm_index_table[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
int16_t nibble,signed_nibble,diff,step;
ima_adpcm.last_nibble++;
const uint8_t *src_ptr=sdata;
nibble = (ima_adpcm.last_nibble&1)?
(src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF);
step=_ima_adpcm_step_table[ima_adpcm.step_index];
ima_adpcm.step_index += _ima_adpcm_index_table[nibble];
if (ima_adpcm.step_index<0)
ima_adpcm.step_index=0;
if (ima_adpcm.step_index>88)
ima_adpcm.step_index=88;
/*
signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
diff = (2 * signed_nibble + 1) * step / 4; */
diff = step >> 3 ;
if (nibble & 1)
diff += step >> 2 ;
if (nibble & 2)
diff += step >> 1 ;
if (nibble & 4)
diff += step ;
if (nibble & 8)
diff = -diff ;
ima_adpcm.predictor+=diff;
if (ima_adpcm.predictor<-0x8000)
ima_adpcm.predictor=-0x8000;
else if (ima_adpcm.predictor>0x7FFF)
ima_adpcm.predictor=0x7FFF;
/* store loop if there */
if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) {
ima_adpcm.loop_step_index = ima_adpcm.step_index;
ima_adpcm.loop_predictor = ima_adpcm.predictor;
}
}
float v=ima_adpcm.predictor/32767.0;
if (v>max[0])
max[0]=v;
if (v<min[0])
min[0]=v;
}
max[0]*=0.8;
min[0]*=0.8;
for(int j=0;j<h;j++) {
float v = (j/(float)h) * 2.0 - 1.0;
uint8_t* imgofs = &imgw[(j*w+i)*3];
if (v>min[0] && v<max[0]) {
imgofs[0]=255;
imgofs[1]=150;
imgofs[2]=80;
} else {
imgofs[0]=0;
imgofs[1]=0;
imgofs[2]=0;
}
}
}
} else {
for(int i=0;i<w;i++) {
// i trust gcc will optimize this loop
float max[2]={-1e10,-1e10};
float min[2]={1e10,1e10};
int c=stereo?2:1;
int from = i*len/w;
int to = (i+1)*len/w;
if (to>=len)
to=len-1;
if (_16) {
const int16_t*src =(const int16_t*)sdata;
for(int j=0;j<c;j++) {
for(int k=from;k<=to;k++) {
float v = src[k*c+j]/32768.0;
if (v>max[j])
max[j]=v;
if (v<min[j])
min[j]=v;
}
}
} else {
const int8_t*src =(const int8_t*)sdata;
for(int j=0;j<c;j++) {
for(int k=from;k<=to;k++) {
float v = src[k*c+j]/128.0;
if (v>max[j])
max[j]=v;
if (v<min[j])
min[j]=v;
}
}
}
max[0]*=0.8;
max[1]*=0.8;
min[0]*=0.8;
min[1]*=0.8;
if (!stereo) {
for(int j=0;j<h;j++) {
float v = (j/(float)h) * 2.0 - 1.0;
uint8_t* imgofs = &imgw[(j*w+i)*3];
if (v>min[0] && v<max[0]) {
imgofs[0]=255;
imgofs[1]=150;
imgofs[2]=80;
} else {
imgofs[0]=0;
imgofs[1]=0;
imgofs[2]=0;
}
}
} else {
for(int j=0;j<h;j++) {
int half,ofs;
float v;
if (j<(h/2)) {
half=0;
ofs=0;
v = (j/(float)(h/2)) * 2.0 - 1.0;
} else {
half=1;
ofs=h/2;
v = ((j-(h/2))/(float)(h/2)) * 2.0 - 1.0;
}
uint8_t* imgofs = &imgw[(j*w+i)*3];
if (v>min[half] && v<max[half]) {
imgofs[0]=255;
imgofs[1]=150;
imgofs[2]=80;
} else {
imgofs[0]=0;
imgofs[1]=0;
imgofs[2]=0;
}
}
}
}
}
imgdata = DVector<uint8_t>::Write();
Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture));
ptex->create_from_image(Image(w,h,0,Image::FORMAT_RGB,img),0);
return ptex;
}
EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() {
}
///////////////////////////////////////////////////////////////////////////

View file

@ -0,0 +1,69 @@
#ifndef EDITORPREVIEWPLUGINS_H
#define EDITORPREVIEWPLUGINS_H
#include "tools/editor/editor_resource_preview.h"
class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String& p_type) const;
virtual Ref<Texture> generate(const RES& p_from);
EditorTexturePreviewPlugin();
};
class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
Ref<Texture> _gen_from_imd(Ref<ResourceImportMetadata> p_imd);
public:
virtual bool handles(const String& p_type) const;
virtual Ref<Texture> generate(const RES& p_from);
virtual Ref<Texture> generate_from_path(const String& p_path);
EditorPackedScenePreviewPlugin();
};
class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
RID scenario;
RID sphere;
RID sphere_instance;
RID viewport;
RID light;
RID light_instance;
RID light2;
RID light_instance2;
RID camera;
public:
virtual bool handles(const String& p_type) const;
virtual Ref<Texture> generate(const RES& p_from);
EditorMaterialPreviewPlugin();
~EditorMaterialPreviewPlugin();
};
class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String& p_type) const;
virtual Ref<Texture> generate(const RES& p_from);
EditorScriptPreviewPlugin();
};
class EditorSamplePreviewPlugin : public EditorResourcePreviewGenerator {
public:
virtual bool handles(const String& p_type) const;
virtual Ref<Texture> generate(const RES& p_from);
EditorSamplePreviewPlugin();
};
#endif // EDITORPREVIEWPLUGINS_H

View file

@ -98,6 +98,125 @@ void SampleEditor::generate_preview_texture(const Ref<Sample>& p_sample,Ref<Imag
if (p_sample->get_format()==Sample::FORMAT_IMA_ADPCM) {
struct IMA_ADPCM_State {
int16_t step_index;
int32_t predictor;
/* values at loop point */
int16_t loop_step_index;
int32_t loop_predictor;
int32_t last_nibble;
int32_t loop_pos;
int32_t window_ofs;
const uint8_t *ptr;
} ima_adpcm;
ima_adpcm.step_index=0;
ima_adpcm.predictor=0;
ima_adpcm.loop_step_index=0;
ima_adpcm.loop_predictor=0;
ima_adpcm.last_nibble=-1;
ima_adpcm.loop_pos=0x7FFFFFFF;
ima_adpcm.window_ofs=0;
ima_adpcm.ptr=NULL;
for(int i=0;i<w;i++) {
float max[2]={-1e10,-1e10};
float min[2]={1e10,1e10};
int from = i*len/w;
int to = (i+1)*len/w;
if (to>=len)
to=len-1;
for(int j=from;j<to;j++) {
while(j>ima_adpcm.last_nibble) {
static const int16_t _ima_adpcm_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
static const int8_t _ima_adpcm_index_table[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
int16_t nibble,signed_nibble,diff,step;
ima_adpcm.last_nibble++;
const uint8_t *src_ptr=sdata;
nibble = (ima_adpcm.last_nibble&1)?
(src_ptr[ima_adpcm.last_nibble>>1]>>4):(src_ptr[ima_adpcm.last_nibble>>1]&0xF);
step=_ima_adpcm_step_table[ima_adpcm.step_index];
ima_adpcm.step_index += _ima_adpcm_index_table[nibble];
if (ima_adpcm.step_index<0)
ima_adpcm.step_index=0;
if (ima_adpcm.step_index>88)
ima_adpcm.step_index=88;
/*
signed_nibble = (nibble&7) * ((nibble&8)?-1:1);
diff = (2 * signed_nibble + 1) * step / 4; */
diff = step >> 3 ;
if (nibble & 1)
diff += step >> 2 ;
if (nibble & 2)
diff += step >> 1 ;
if (nibble & 4)
diff += step ;
if (nibble & 8)
diff = -diff ;
ima_adpcm.predictor+=diff;
if (ima_adpcm.predictor<-0x8000)
ima_adpcm.predictor=-0x8000;
else if (ima_adpcm.predictor>0x7FFF)
ima_adpcm.predictor=0x7FFF;
/* store loop if there */
if (ima_adpcm.last_nibble==ima_adpcm.loop_pos) {
ima_adpcm.loop_step_index = ima_adpcm.step_index;
ima_adpcm.loop_predictor = ima_adpcm.predictor;
}
}
float v=ima_adpcm.predictor/32767.0;
if (v>max[0])
max[0]=v;
if (v<min[0])
min[0]=v;
}
for(int j=0;j<h;j++) {
float v = (j/(float)h) * 2.0 - 1.0;
uint8_t* imgofs = &imgw[(j*w+i)*3];
if (v>min[0] && v<max[0]) {
imgofs[0]=255;
imgofs[1]=150;
imgofs[2]=80;
} else {
imgofs[0]=0;
imgofs[1]=0;
imgofs[2]=0;
}
}
}
} else {
for(int i=0;i<w;i++) {
// i trust gcc will optimize this loop

View file

@ -239,7 +239,7 @@ public:
void set_state(const Dictionary& p_state);
Dictionary get_state() const;
void reset();
Viewport *get_viewport_node() { return viewport; }
SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index);
@ -422,6 +422,7 @@ private:
HBoxContainer *hbc_menu;
//
//
void _generate_selection_box();
@ -514,6 +515,11 @@ public:
void set_can_preview(Camera* p_preview);
SpatialEditorViewport *get_editor_viewport(int p_idx) {
ERR_FAIL_INDEX_V(p_idx,4,NULL);
return viewports[p_idx];
}
Camera *get_camera() { return NULL; }
void edit(Spatial *p_spatial);
void clear();

View file

@ -152,7 +152,7 @@ void ResourcesDock::save_resource_as(const Ref<Resource>& p_resource) {
List<String> extensions;
ResourceSaver::get_recognized_extensions(res,&extensions);
file->set_mode(FileDialog::MODE_SAVE_FILE);
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
if (p_resource->get_path()!="" && p_resource->get_path().find("::")==-1) {
@ -396,7 +396,7 @@ ResourcesDock::ResourcesDock(EditorNode *p_editor) {
accept = memnew (AcceptDialog);
add_child(accept);
file = memnew( FileDialog );
file = memnew( EditorFileDialog );
add_child(file);
file->connect("file_selected",this,"_file_action");

View file

@ -38,6 +38,7 @@
#include "scene/gui/menu_button.h"
#include "scene/gui/file_dialog.h"
#include "create_dialog.h"
#include "editor_file_dialog.h"
class EditorNode;
@ -68,7 +69,7 @@ class ResourcesDock : public VBoxContainer {
CreateDialog *create_dialog;
AcceptDialog *accept;
FileDialog *file;
EditorFileDialog *file;
Tree *resources;
bool block_add;
int current_action;

View file

@ -1,10 +1,10 @@
#include "core/object.h"
#include "core/reference.h"
class FileAccess;
class PCKPacker : public Object {
class PCKPacker : public Reference {
OBJ_TYPE(PCKPacker, Object);
OBJ_TYPE(PCKPacker, Reference);
FileAccess* file;
int alignment;