So im trying to make this mod give you 2 apples (for testing purposes) but I cant seem to get it to work :/ (no errors nothing the mod does not output anything) here's my code (1.8.9 Forge BTW):
#SubscribeEvent
public static void init(FMLInitializationEvent event)
{
MinecraftForge.EVENT_BUS.register(EventHandler.class);
}
#SubscribeEvent
public void onPlayerJoin(PlayerLoggedInEvent event)
{
event.player.inventory.addItemStackToInventory(new ItemStack(Items.apple, 2));
event.player.addChatMessage(new ChatComponentText("test"));
return;
}
Minecraft uses two different event systems for some reason. init is supposed to be #EventHandler, not #SubscribeEvent. onPlayerJoin is correct though. (Add import net.minecraftforge.fml.common.Mod.EventHandler; if you don't already have it.)
Also, if onPlayerJoin is in your MainGuts class, then you need to do either MinecraftForge.EVENT_BUS.register(MainGuts.class); or MinecraftForge.EVENT_BUS.register(this); (try both; I forget which is correct all the way back in 1.8.9), not MinecraftForge.EVENT_BUS.register(EventHandler.class);.
Related
How to professionally refactor lambda function to be called by another class WHILE make caller's code still short?
My attempt shows that for changing a lambda function to a normal function, I have to capture variables manually, thus the new normal function requires more parameters (to compensate automatic capture ability).
As a result, the new function is more tedious to use, and can cause more bug.
Example
Here is my original code, using lambda.
void Turret::registerFullversion(int gameObjectId, PhysicObject* phyO){//utility
//.... something a bit complex .......
}
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
auto registerEasy=[&]( PhysicObject* phyO){
//^ served as a short hand version of "registerFullversion"
// 1 parameter is more comfortable than 2
registerFullversion(gameObjectId,phyO);
}
switch(typeOfTurret){
case 1:{ //this part will be moved into another class (###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
registerEasy( phy);
//^ equivalent to "registerFullversion(gameObjectId,phy)"
// but it is very concise (1 parameter), nice!
};break;
//..... a lot of case ....
}
//... do something about "gameObjectId"
}
I want to move a part of function (###) from Turret into another class (TurretLaser).
It works, but the result is that caller have to capture gameObjectId and pass it manually :-
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
switch(typeOfTurret){
case 1:{ //this part have to be move into another class
TurretLaser::createTurret(gameObjectId)
};break;
//..... a lot of case ....
}
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
Turret:registerFullversion(gameObjectId,phy);
//^ it is not as short as before (now = 2 parameters)
}
Note
In real case, all above functions are non-static function, and all functions are far more complex.
Performance is the first priority. Thus, std::bind and std::function are not allowed.
This question asks about how to omit the captured parameters rather than "Please fix my code", so a valid solution can also just provide a new example with its own fix instead of showing modification of my code.
My attempt
I will manually capture the related data (gameObjectId) and cache it (using a new variable CACHE_gameObjectId):-
void Turret::registerEasy(PhysicObject* physicO){
registerFullversion(CACHE_gameObjectId,physicO);
//int "CACHE_gameObjectId" is a new field of "Turret"
};
void Turret::createTurret(int typeOfTurret){
int gameObjectId=createNewGameObjectId();
Turret::CACHE_gameObjectId=gameObjectId;
switch(typeOfTurret){
case 1:{ //this part have to be move into another class
TurretLaser::createTurret(gameObjectId)
};break;
//..... a lot of case ....
}
}
void TurretLaser::createTurret(int gameObjectId){ //(###)
PhysicObject* phy=PhysicSystem::createNewPhysicObject();
Turret:registerEasy(phy);
//^ short as before, nice
}
Disadvantage of my solution: dirty, look dangerous (not so automatic, thus can cause more bug) , seem to be less thread-safe (?)
I try to use jsprit to solve a VRP with multiple TimeWindows. Therefore I created a new Constraint-Class which contains a Map that relates a "TimeWindowsNotAvailable"-class to a Service.
The "TimeWindowsNotAvailable"-class contains a List of TimeWindows where the Service can't be done (e.g. customer is not at home etc.).
The main problem is, that the newAct.getArrTime() is always 0.0, although you can see in the solution of the VRP that the arrTime is not 0.0.
Does anybody have an idea how I can fix this issue or are multiple TimeWindows much harder to implement?
public class TimeConstraint implements HardActivityStateLevelConstraint {
private Map<Service, TimeWindowsNotAvailable> notAvailableMap;
private RouteAndActivityStateGetter states;
private VehicleRoutingTransportCosts routingCosts;
public TimeConstraint() {
super();
}
public boolean checkDepTime(Service service, Double depTime){
TimeWindowsNotAvailable timeWindowsNotAvailable = notAvailableMap.get(service);
if(timeWindowsNotAvailable == null) return true;
System.out.println(depTime);
return timeWindowsNotAvailable.isAvailable(depTime);
}
public void setNotAvailableMap(Map<Service, TimeWindowsNotAvailable> notAvailableMap){
this.notAvailableMap = notAvailableMap;
}
#Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
Service currentService = (Service)iFacts.getJob();
if(checkDepTime(currentService, **newAct.getArrTime()**)) return ConstraintsStatus.FULFILLED;
return ConstraintsStatus.NOT_FULFILLED;
}
}
You cannot yet model multiple time windows out-of-the box but it is going to be implemented. For the time being, you can implement your own. Assume you have for example the following two time windows for a service: (e1,l1), (e2,l2) where e means earliest operation start and l latest. If l1 < e2, it is comparably "easy" to implement. Just look at how I implemented single hard time windows. Look at which is the TimeWindowConstraint and which is the practical time window state updater. You probably only need minor modifications of these classes, so just copy them and add multiple time windows, and add these two new classes to your State- and ConstraintManager (do not forget to deactivate the default time window constraints/stateUpdater).
The newAct does not have any arrTime since it is not yet inserted into the route and the best insertion position is still to be determined (by checking constraints and calculating marginal insertion costs). But you can easily calculate it as follows:
double newActArrTime = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle);
This may sound stupid, but C++ and C++11 has surprised me before in terms of the magic it can achieve. Perhaps this is too far, but I prefer confirming my fears rather than assuming them.
Is it possible in any way to cast a std::future or std::future_shared object?
I find it usually helps if I describe the concrete problem I am having. I am essentially loading some audio and video asynchronously and although I've started using std::async which I find really useful, I haven't used futures before until now. It's essentially born out of me learning that futures seem to handle exceptions fairly well and I want to make my async loading a bit more robust. My crummy program will occasionally run out of memory but that won't occur to the program until the async call has been launched. Solving the memory issue is another issue entirely and not a viable solution currently.
Anyway - I have two separate objects that handle the loading of audio (AudioLibrary) and video (VideoLibrary), but since they share a number of commonalities they both inherit from the same base object (BaseLibrary).
The audio and video each of these respective libraries return come in their own containers for audio (AudioTrack) and video (VideoTrack), which also inherit from a common object (BaseTrack).
I'm sure you can see where this is going. I'd like some general exception handling to occur in the BaseLibrary which will have some virtual functions like loadMedia. These will be overwritten by the derived libraries. Thus the trouble begins. I read that pointer objects (like unique_ptr or shared_ptr) cannot be covariant and so just creating a virtual method doesn't quite solve it.
However, I was hoping via virtual functions I could still somehow achieve what I wanted.
Something along the lines of BaseLibrary implementing the following:
std::shared_future<BaseTrack> BaseLibrary::loadMedia()
std::shared_future<BaseTrack> BaseLibrary::loadMediaHelper()
and then AudioLibrary would implement
std::shared_future<AudioTrack> AudioLibrary::loadAudio()
where this function makes use of the functions in the BaseLibrary yet returns its own specific type of AudioTrack, rather than a BaseTrack.
Is this at all possible?
Update 1:
Thanks to the comment and answer, I see how it's possible to achieve what I want, but I have a few more unresolved questions. I think it'll be much easier to address those by just being very explicit. I'm actually working with shared_ptrs since a number of objects are making use of the loaded audio and video, so I have the following type defs:
typedef std::shared_ptr<BaseTrack> BaseTrackPtr;
typedef std::shared_ptr<AudioTrack> AudioTrackPtr;
AudioTrack inherits from BaseTrack of course. Following the given advice I have a compile-able (abbreviated) code structure which is as follows for the BaseLibrary:
class BaseLibrary {
virtual std::shared_future<BaseTrackPtr> loadMedia();
virtual std::shared_future<BaseTrackPtr> loadMediaHelper() = 0;
}
std::shared_future<BaseTrackPtr> BaseLibrary::loadMedia()
{
// Place code to catch exceptions coming through the std::future here.
// Call the loadMediaHelper via async - loadMediaHelper is overwritten in the inherited libraries.
}
And the AudioLibrary:
class AudioLibrary : public BaseLibrary {
public:
virtual std::shared_future<AudioTrackPtr> loadAudio();
protected:
virtual std::shared_future<BaseTrackPtr> loadMediaHelper();
}
std::shared_future<AudioTrackPtr> AudioLibrary::loadAudio()
{
std::shared_future<BaseTrackPtr> futureBaseTrackPtr = loadMedia();
return std::async( std::launch::deferred, [=]() {
return AudioTrackPtr( std::static_pointer_cast<AudioTrack>( futureBaseTrackPtr.get() ) );
} );
}
std::shared_future<BaseTrackPtr> AudioLibrary::loadMediaHelper()
{
// Place specific audio loading code here
}
This structure allows me to catch any video/audio loading exceptions in one place, and also return the proper Audio/Video Object rather than a base object that needs to be recast.
My two current questions are as follows:
Isn't it best to let the async call in loadMedia in the BaseLibrary be std::launch::deferred, and then let the async calls in either loadAudio (or loadVideo) be std::launch::async? I essentially want the loading commence immediately, but might as well wait til the outer async call is performed...? Does that make sense?
Finally, is this hideously ugly? A part of me feels like I'm properly leveraging all the goodness C++11 has to offer, shared_ptr's, futures and so forth. But I'm also quite new to futures so... I don't know if putting a shared pointer in a shared future is... Weird?
So you have something like:
class BaseLibrary
{
public:
virtual ~BaseLibrary() {}
virtual std::shared_future<std::unique_ptr<BaseTrack>> loadMedia() = 0;
};
class AudioLibrary : public BaseLibrary
{
public:
std::shared_future<AudioTrack> loadAudio();
std::shared_future<std::unique_ptr<BaseTrack>> loadMedia() override;
};
So you may implement loadMedia() like that:
std::shared_future<std::unique_ptr<BaseTrack>> AudioLibrary::loadMedia()
{
auto futureAudioTrack = loadAudio();
return std::async(std::launch::deferred,
[=]{
std::unique_ptr<BaseTrack> res =
make_unique<AudioTrack>(futureAudioTrack.get());
return res;
});
}
I have this problem that I am trying to get the killers health from the PlayerDeathEvent but it gives me the error that the method getHealth() is ambiguous for the type Player
Here is a piece of the code.
#EventHandler
public void onDeath(PlayerDeathEvent event) {
Player p = event.getEntity();
Player killer = p.getKiller();
double playerHealth = killer.getHealth();
}
Anyone got any idea why it's not working?
There are two getHealth() methods, due to the way Bukkit handled Minecraft changing the way entity health is stored in 1.6. You can read more about this here.
If you aren't using any NMS code, you should use the bukkit.jar in your build path as opposed to craftbukkit.jar. This should resolve your issue easily enough.
If you do need NMS code, you need to have both bukkit.jar AND craftbukkit.jar in your build path. Furthermore, you have to have bukkit.jar above craftbukkit.jar in the build path for it to work.
The reason that you're getting an error could be because, lets say a creeper or another non-player entity kills the player. Here's what you should do to prevent this:
#EventHandler
public void onDeath(PlayerDeathEvent e){
Player p = e.getEntity().getPlayer(); //use .getPlayer() just to be safe
if(p.getLastDamageCause().equals(DamageCause.ENTITY_ATTACK) && p.getKiller() instanceof Player){
//the player was last damaged by a LivingEntity, and the killer of the player is in-fact a player
Player killer = p.getKiller();
double playerHealth = killer.getHealth();
}
}
casting the player to Damagable will also work if you need nms code
How much information hiding is necessary? I have boilerplate code before I delete a record, it looks like this:
public override void OrderProcessing_Delete(Dictionary<string, object> pkColumns)
{
var c = Connect();
using (var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM orders WHERE order_id = :_order_id", c)
{ Parameters = { {"_order_id", pkColumns["order_id"]} } } )
{
var count = (long)cmd.ExecuteScalar();
// deletion's boilerplate code...
if (count == 0) throw new RecordNotFoundException();
else if (count > 1) throw new DatabaseStructureChangedException();
// ...boiler plate code
}
// deleting of table(s) goes here...
}
NOTE: boilerplate code is code-generated, including the "using (var cmd = new NpgsqlCommand( ... )"
But I'm seriously thinking to refactor the boiler plate code, I wanted a more succint code. This is how I envision to refactor the code (made nicer with extension method (not the sole reason ;))
using (var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM orders WHERE order_id = :_order_id", c)
{ Parameters = { {"_order_id", pkColumns["order_id"]} } } )
{
cmd.VerifyDeletion(); // [EDIT: was ExecuteWithVerification before]
}
I wanted the executescalar and the boilerplate code to goes inside the extension method.
For my code above, does it warrants code refactoring / information hiding? Is my refactored operation looks too opaque?
I would say that your refactor is extremely good, if your new single line of code replaces a handful of lines of code in many places in your program. Especially since the functionality is going to be the same in all of those places.
The programmer coming after you and looking at your code will simply look at the definition of the extension method to find out what it does, and now he knows that this code is defined in one place, so there is no possibility of it differing from place to place.
Try it if you must, but my feeling is it's not about succinctness but whether or not you want to enforce the behavior every time or most of the time. And by extension, if the verify-condition changes that it would likely change across the board.
Basically, reducing a small chunk of boiler-plate code doesn't necessarily make things more succinct; it's just one more bit of abstractness the developer has to wade through and understand.
As a developer, I'd have no idea what "ExecuteWithVerify" means. What exactly are we verifying? I'd have to look it up and remember it. But with the boiler-plate code, I can look at the code and understand exactly what's going on.
And by NOT reducing it to a separate method I can also tune the boiler-plate code for cases where exceptions need to be thrown for differing conditions.
It's not information-hiding when you extract or refactor your code. It's only information-hiding when you start restricting access to your extension definition after refactoring.
"new" operator within a Class (except for the Constructor) should be Avoided at all costs. This is what you need to refactor here.