How to reference a stage instance of a MovieClip from a non-document Class without causing Error 1120? - class

I have a basic AS3 question that has to do with the relationship between object on the stage and objects that are created and controlled by AS3 script. This question has already been addressed tons of times, and I've researched it for hours, but I found drastically different answers, many which were really complicated. I'm looking for the simplest, most general solution to this issue that is humanly (or perhaps I should say computerly) possible.
I want to be able reference an instance of an object on the stage inside a class that is not the main document class. Before I try to explain in my own terms, it might be better to view one of these posts, which cover the exact topic I'm confused about. If any of you understand the issue, and understand the solutions to one of these posts, perhaps you could translate one of the correct answers into n00banese for me. Rather than just focusing on how they did it, you could explain WHY it was necessary to do it that. I would be very thankful if someone could do that much, and if you can it is not necessary to read any further into this post.
AS3 - Access MovieClip from stage within a class
How do I access a MovieClip on the stage from the Document Class?
AS3 Modify stage Objects from a class
how do I make non-document-class classes 'aware' of stage components in Flash AS3?
Accessing ActionScript3 Nested Movie Clips from Class
Since it's highly possible that all of the above-mentioned situations are too complicated for me, I recreated the problem in the simplest, most general way possible in hopes that it would be easier to explain in this case.
I have a MovieClip on the stage with instance name scene_mc. scene_mc does nothing except separate one scene from another. It's linked to a .as file named Scene. Nested inside scene_mc there is a movieclip called thing_mc, linked to .as file Thing. I want to move thing_mc across the scene. I could easily do this by changing its coordinates in the main document class, something like this:
thing_mc.x = thing_mc.x + 100;
But since thing_mc is nested inside of scene_mc, I would like to control thing_mc's position inside the SCENE class so that the coordinates are relevant to other nested symbols in this class. And because in more complicated projects, it just makes sense to control a nested symbol in the code of its parent. So inside Scene.as, I might create this method:
public function moveThing() {
thing_mc.x = thing_mc.x + 200;
}
This causes this error: "1120: Access of undefined property thing_mc."
Error 1120 happens any time one tries to reference a stage instance of a symbol a .as file that is not the main document class.
So to reiterate my question, how can I let the Scene class know what thing_mc is? Or how can I let any class know what any stage instance is? How do you reference a stage instance of an object through a non-document class?
Oh! This might be helpful. The Actioscript 3.0 docs say this- Note: Children instances placed on the Stage in the Flash authoring tool cannot be accessed by code from within the constructor of a parent instance since they have not been created at that point in code execution. Before accessing the child, the parent must instead either create the child instance by code or delay access to a callback function that listens for the child to dispatch itsĀ Event.ADDED_TO_STAGEĀ event.
So I mean, really I get why what I'm trying to do would cause an error, but I still don't get how to work around it.
Anyone who actually read this far into my gibberish, thank you. You are a kind and patient soul, haha. This issue is really consuming me so any attempt to help me understand the theory of how this works would be IMMENSELY appreciated. :D

...From what I understood after an all nighter (and sorry if this isn't the answer you're looking for)
You need to link Scene (the object in your library in Adobe Flash (or Adobe Animate if you're using that)) to your class. (Export for Actionscript) BUT (and here's the kicker) you need to also check export for frame 1 and make sure it's loaded on frame 1.
I run into issues like this when I'm not paying attention. Make sure the movieclip nested inside your main movieclip, somehow, gets loaded. Be it through the constructor, or on frame 1. Say your nested movieclip is on frame 2. Well, flash hasn't loaded frame 2. Therefor, it hasn't constructed anything inside frame 2. So it has no idea what you're talking about.
At times, i've had to do a gotoAndStop(2) and then right back to 1 just so that an object on frame 2 was named and ready to be handled in the future.

Related

Is it possible to implement a module that is not a WPF module (a standard class library, no screens)?

I am developing a modular WPF application with Prism in .Net Core 5.0 (using MVVM, DryIoc) and I would like to have a module that is not a WPF module, i.e., a module with functionality that can be used by any other module. I don't want any project reference, because I want to keep the loosely coupled idea of the modules.
My first question is: is it conceptually correct? Or is it mandatory that a module has a screen? I guess it should be ok.
The second and more important (for me) is, what would be the best way to create the instance?
This is the project (I know I should review the names in this project):
HotfixSearcher is the main class, the one I need to get instantiated. In this class, for example, I subscribe to some events.
And this is the class that implements the IModule interface (the module class):
namespace SearchHotfix.Library
{
public class HotfixSearcherModule : IModule
{
public HotfixSearcherModule()
{
}
public void OnInitialized(IContainerProvider containerProvider)
{
//Create Searcher instance
var searcher = containerProvider.Resolve<IHotfixSearcher>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IHotfixSearcher, HotfixSearcher>();
}
}
}
That is the only way I found to get the class instantiated, but I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
For modules that have screens, the instances get created when navigating to them using the RequestNavigate method:
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
But since this is only a library with no screens, I can't find any other way to get this instantiated.
According to Prism documentation, subscribing to an event shoud be enough but I tried doing that from within my main class HotfixSearcher but it does not work (breakpoints on constructor or on the event handler of the event to which I subscribe are never hit).
When I do this way, instead, the instance is created, I hit the constructor breakpoint, and obviously the instance is subscribed to the event since it is done in the constructor.
To sum up, is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
Thanks in advance!
Or is it mandatory that a module has a screen?
No, of course not, modules have nothing to do with views or view models. They are just a set of registrations with the container.
what would be the best way to create the instance?
Let the container do the work. Normally, you have (at least) one assembly that only contains public interfaces (and the associated enums), but no modules. You reference that from the module and register the module's implementations of the relevant interfaces withing the module's Initialize method. Some other module (or the main app) can then have classes that get the interfaces as constructor parameters, and the container will resolve (i.e. create) the concrete types registered in the module, although they are internal or even private and completely unknown outside the module.
This is as loose a coupling as it gets if you don't want to sacrifice strong typing.
is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
You can skip the var searcher = part :-) But if the HotfixSearcher is never injected anywhere, it won't be created unless you do it yourself. OnInitialized is the perfect spot for this, because it runs after all modules had their chance to RegisterTypes so all dependencies should be registered.
If HotfixSearcher is not meant to be injected, you can also drop IHotfixSearcher and resolve HotfixSearcher directly:
public void OnInitialized(IContainerProvider containerProvider)
{
containerProvider.Resolve<HotfixSearcher>();
}
I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
It is used, I suppose, although not through calling one of its methods. It's used by sending it an event. That's just fine. Think of it like Task.Run - it's fine for the task to exist in seeming isolation, too.

Are UE4 Blueprints the same with a C++ class? If so, how will I implement a class design?

Good day! I am new to using Unreal Engine 4 and I have a few questions about how exactly blueprints work. From my understanding of it, every blueprint works like a class. By that I mean one blueprint is much like one class in an OOP programming language.
Please educate me as to - if my assumption is correct or wrong. If wrong, then maybe you could help me achieve what I want in a different method/perspective. I am willing to learn and accept suggestions.
If at some point my understanding is correct - that blueprints are actually individual classes - I would really appreciate it if you could (please) guide as to where to go and how to implement a design that I want to create. This is from a programmers perspective (PHP OOP Programming). Forgive the approach, I'm just using PHP to logically express how I want the class to work. Plus, it is the only OOP programming I know atm.
I want to create a class named: Items. class Item {}
This class is going to handle everything item related, thus we will have to give it a lot of properties/variable. (Below is just an example; Again I'm using PHP as an example.)
class Item {
var $id;
var $name;
var $description;
var $type;
var $subType;
var $mesh;
var $materials;
}
3.) I would like to initiate this class by having two variables as its construct arguments. (We will require itemID and itemType). This is because I will use these two variables to retrieve the item's data which is already available in a data table. I will use those data in the table to populate the class properties/variables. (I'm not sure if I said that right. I hope you understood my point anyway.)
class Item {
var $id;
var $name;
var $description;
var $type;
var $subType;
var $mesh;
var $materials;
function _construct($cons_itemID, $cons_itemType) {
/*-- Start getting the item Data here based on what item and type provided. Then, push that data into the class properties/variables. We will use individual methods/functions to fill other properties/variables later. --*/
}
}
4.) Basically with that design I could easily pass on an item ID to the class and then get the item's name, description, mesh, materials and etc using pointers.
Example:
$weapon = new Item('10001','Weapon');
$weaponMesh = $weapon->getMesh();
$armor = new Item('12345','Armor');
$armorName = $armor->getName();
I'm just having a lot of trouble working with blueprint and achieve this method or even something similar to it. I'm not trying to avoid C++, I would love to learn it but I just don't have the time freedom right now.
Few things I have tried to make it work:
Casting / Casting to class (But I couldn't figure out what the target object will be and how was I going to add input arguments into the class that way? There isn't any input there that I could use.)
Spawn Actor (This one is very promising, I need to dig in deeper into this)
Blueprint Macros? Blueprint Interfaces? (I'm just lost.)
For all those who will help or answer. Thank you!
~ Chris
So far as I know, yes, we can assume that each blueprint can be viewed as class. (Moreover, since UE 4.12 (in UE 4.11 that functionality is marked as experimental I think) you can check Compile blueprints under Project settings -> Packaging. That will create native class for each blueprint.)
You can create either Blueprint or C++ class based on Object (UObject in C++). Then you can specify all properties (or variables in UE editor terminology). In BP you have small advantage: you can mark some properties as Visible at spawn (they must be Public and Visible). So when you are creating new instance of that class, you can explicitly pass values to that properties.
And in BP Construct event, that properties are correctly filled, thus you can set another properties values based on given ID and Type.
In C++ class having different arguments than FObjectInitializer is not possible, thus you don't have that values in time when constructor is executed. But it is not so hard to achieve same functionality, you can find example here: https://answers.unrealengine.com/questions/156055/passing-arguments-to-constructors-in-ue4.html.
Something about list of what you had tried:
Spawn actor - derive from actor only if you intend to have that BP in scene. Actors are subjects to game updates and rendering, so having actor only as data container is very wrong.
BP Macro is same as BP Function except function will be called just like function (so executing necesary actions by function call conventions) and macro will replace it's implementation in place, where you are calling that macro. More exhausting explanation here.
If I would implement your code, I'd do it like I said and then I'll have that class as property in some component and that component would be attached to some actor, which would be placed in scene.

AS3 targeting controller class variable using string

I'm looking for a way of condensing some of my AS3 code to avoid almost duplicate commands.
The issue is that I have multiple variables with almost the same name e.g. frenchLanguage, englishLanguage, germanLanguage, spanishLanguage
My Controller class contains public static variables (these are accessed across multiple classes) and I need a way to be able to call a few of these variables dynamically. If the variables are in the class you are calling them from you can do this to access them dynamically:
this["spanish"+"Language"]
In AS3 it's not possible to write something like:
Controller.this["spanish"+"Language"]
Is there any way to achieve this? Although everything is working I want to be able to keep my code as minimal as possible.
It is possible to access public static properties of a class this way (assuming the class name is Controller as in your example:
Controller['propertyName']
I'm not sure how this helps to have "minimal code", but this would be a different topic/question, which might need some more details on what you want to achive.
Having said that, I like the approach DodgerThud suggests in the comments of grouping similar values in a (dynamic) Object or Dictonary and give it a proper name.
Keep in mind, that if the string you pass in as the key to the class or dynamic object is created from (textual) user input you should have some checks for the validity of that data, otherwise your programm might crash or expose other fields to the user.
It would make sense to utilize a Dictionary object for a set of variables inherited: it provides a solid logic and it happens to work...
I do not think this is what you are trying to accomplish. I may be wrong.
Classes in AS3 are always wrapped within a package - this is true whether you have compiled from Flash, Flex, Air, or any other...
Don't let Adobe confuse you. This was only done in AS3 to use Java-Based conventions. Regardless, a loosely typed language is often misunderstood, unfortunately. So:
this["SuperObject"]["SubObject"]["ObjectsMethod"][ObjectsMethodsVariable"](args..);
... is technically reliable because the compiler avoids dot notation but at runtime it will collect a lot of unnecessary data to maintain those types of calls.
If efficiency becomes an issue..
Use:
package packages {
import flash.*.*:
class This implements ISpecialInterface {
// Data Objects and Function Model
// for This Class
}
package packages {
import...
class ISpecialInterface extends IEventDispatcher

(UE4) Is there a method of getting all actors in camera view?

Like the title says, i want to be able to get all actors that are within the camera view in Unreal Engine 4.
I have thought of two ways i could do this: 1) using a shape trace in the form of a "boxtracebyobject" which works but seems to be glitchy at times and has trouble recognizing multiple overlapping actors. 2) using a "BoxOverlappingActors", though i havent quite figured out how to use it yet.
If anyone knows of a proper method to getting actors in cameria view, my ears are open!
Update
A much better answer has been posted on Unreal Answers by Rama:
Use the AActor::GetLastRenderTime() to find out for each actor when last drawn or UPrimitiveComponent::LastRenderTime for the primitive itself. His answer explains how you can use this.
Original answer:
As you suggested, it seems weird that you would have to do something to do with collision volumes when Unreal must be checking to do culling so I found the following method to query that information:
First we have to create a FSceneView from the camera. This code is taken from the UE Answers question.
APlayerCameraManager* Manager = World->GetFirstPlayerController()->PlayerCameraManager;
ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController();
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
LocalPlayer->ViewportClient->Viewport,
World->Scene,
LocalPlayer->ViewportClient->EngineShowFlags)
.SetRealtimeUpdate(true));
FVector ViewLocation;
FRotator ViewRotation;
FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);
Once we've created the view we can iterate through all primitive components (includes meshes) and then we can use the bounds from the SceneProxy of the Static Mesh and the bounds of the view to do our own culling.
for (TObjectIterator<UPrimitiveComponent> ScenePrimitsItr; ScenePrimitsItr; ++ScenePrimitsItr)
{
// Using the Object iterator so we have to skip objects not in the
// relevant world
if (ScenePrimitsItr->GetWorld() == World)
{
FPrimitiveSceneProxy* Proxy = ScenePrimitsItr->SceneProxy;
if (Proxy)
{
bool bIsShown =
SceneView->ViewFrustum.IntersectSphere(Proxy->GetBounds().Origin, Proxy->GetBounds().SphereRadius)||
SceneView->ViewFrustum.IntersectBox(Proxy->GetBounds().Origin, Proxy->GetBounds().BoxExtent);
}
}
}
The frustrum check came from SceneVisibility.cpp in the method FrustumCull This method isn't ideal as a) involves duplicating that check and b) performing the test twice. However, I couldn't find a way to actually query the result. It appears to be stored in a bit array in the FViewInfo. Unfortunately this info is not exposed outside of the renderer module.
You could try this to create an array of actors:
But I don't know if it's good performance wise if there are too many actors of the class you want.

Magento: Accessing models/blocks from a phtml

Hi I have a situation where I need to look up the number of recently viewed products on catalog/product/view.phtml. In the recently viewed 'product_viewed.phtml' file it calls
$_products = $this->getRecentlyViewedProducts()
to get the recently viewed. How would I access this method from within the catalog/product/view.phtml file?
I don't know where this method is. I've tried searching for it but it doesn't seem to exist. When I write click it in Netbeans and click go to declaration it takes me to
class Mage_Reports_Block_Product_Viewed extends Mage_Reports_Block_Product_Abstract
Actually on the class itself. This class only has _toHtml(), getCount(), and getPageSize() methods.
I just need to know whether there are any recently viewed products.
Any help most appreciated!
Billy
If you look into 'Mage_Reports_Block_Product_Viewed', you will notice:
$this->setRecentlyViewedProducts($this->getItemsCollection());
That 'getItemsCollection' method is defined in the abstract class... And you will notice this abstract class will create a model based on $_indexName defined in the (subclassed) block.
If you just want the collection, you can probably get away with:
$_products = Mage::getModel('reports/product_index_viewed')->getCollection();
And then adding whatever you want to the collection:
$_products
->addAttributeToSelect('*')
->setAddedAtOrder();
// optionally add other methods similar to Mage_Reports_Block_Product_Abstract::getItemsCollection
Another approach that might be more suited would be to create the original block:
$productViewedBlock = $this->getLayout()->createBlock('reports/product_viewed');
On which you can simply call whatever you want:
$_collection = $productViewedBlock->getItemsCollection();
$_count = $productViewedBlock->getCount();
The getRecentlyViewedProducts function is a magical getter that gets the data that was set with setRecentlyViewedProducts in app/code/core/Mage/Reports/Block/Product/Viewed.php (which builds it using app/code/core/Mage/Reports/Block/Product/Abstract.php's function _getRecentProductsCollection).
This is complicated stuff that you don't want to reproduce; its better, IMO to make your own Block that extends Mage_Catalog_Block_Product_Abstract that will give you access to the same functionality, and drop your new block into the page you're working on.